mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Johannes Schneider <johannes.schneider@leica-geosystems.com>
To: barebox@lists.infradead.org
Cc: Johannes Schneider <johannes.schneider@leica-geosystems.com>
Subject: [PATCH v2 01/11] ARM: i.MX8M: enable MMU in PBL around fw-external BL32 verify
Date: Sat,  4 Jul 2026 12:26:18 +0000	[thread overview]
Message-ID: <20260704122628.3326142-2-johannes.schneider@leica-geosystems.com> (raw)
In-Reply-To: <20260704122628.3326142-1-johannes.schneider@leica-geosystems.com>

The BL32 fw-external blob is loaded into DRAM by the PBL and then
SHA-256-verified inside get_builtin_firmware_ext(). With the MMU off and
the D-cache cold that verify walks ~720 KiB through uncached DRAM; on a
Cortex-A53 that is ~2 s of pre-BL31 wall-clock every boot.

The verify is the only thing anchoring the BL32 content to the signed PBL
(HABv4 on i.MX8M only signs/loads what fits in OCRAM = the PBL; BL31/BL32
reach DRAM via PBL copies), so skipping the SHA-256 would be a security
regression.

Turn the MMU + D-cache on once DRAM is populated, right before the verify
+ BL31/BL32 memcpy, and drop it again before the BL31 entry (BL31 expects
MMU off). The verify drops from ~2 s to ~300 ms and BL31 early-init also
benefits from the warm cache.

Wrap the enable in imx8m_mmu_early_enable(), which picks the early-DRAM
size from the DDR bus width (16 for i.MX8MN, 32 otherwise), rather than
open-coding mmu_early_enable() at every call site [1]. Mirrors the
Rockchip PBL MMU handling.

[1] https://lists.infradead.org/pipermail/barebox/2026-July/056889.html

Assisted-by: Claude Opus 4.8 (1M context)
Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
---

Notes:
    v2:
    - Wrap the enable in a new imx8m_mmu_early_enable() that derives the
      early-DRAM size from the DDR bus width (16 for i.MX8MN, 32 otherwise),
      instead of open-coding mmu_early_enable() at each call site (Sascha).
    - Folded into this series (was posted as a standalone patch).
    
    - Guard the mmu_early_enable() call with IS_ENABLED(CONFIG_MMU) (it has no
      !MMU stub), matching arch/arm/cpu/uncompress.c (Copilot).

 arch/arm/mach-imx/atf.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 948756e26b..0f57a204b7 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -20,6 +20,7 @@
 #include <mach/imx/xload.h>
 #include <mach/imx/snvs.h>
 #include <pbl.h>
+#include <asm/mmu.h>
 
 static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32_size)
 {
@@ -130,6 +131,20 @@ static __noreturn void start_bl31_via_bl_params(void *bl31, void *bl32,
  *     4. Transfers control to BL31
  */
 
+/* Enable the MMU + D-cache over the i.MX8M early-DRAM window. */
+static void imx8m_mmu_early_enable(void)
+{
+	unsigned long memsize;
+
+	if (cpu_is_mx8mn())
+		memsize = imx8m_barebox_earlymem_size(16);
+	else
+		memsize = imx8m_barebox_earlymem_size(32);
+
+	if (IS_ENABLED(CONFIG_MMU))
+		mmu_early_enable(MX8M_DDR_CSD1_BASE_ADDR, memsize);
+}
+
 static __noreturn void
 imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
 		     void *tee_bin, size_t tee_size, void *bl33, void *fdt)
@@ -188,6 +203,9 @@ imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
 		     "r" (tfa_dest - 16) :
 		     "cc");
 
+	/* BL31 expects MMU off. */
+	mmu_disable();
+
 	/*
 	 * If enabled the bl_params are passed via x0 to the TF-A, except for
 	 * the i.MX8MQ which doesn't support bl_params yet.
@@ -283,6 +301,9 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
 	imx8m_setup_snvs();
 	imx8mm_load_bl33(bl33);
 
+	/* Cache DRAM for the BL32 verify + BL31/BL32 memcpy that follow. */
+	imx8m_mmu_early_enable();
+
 	if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MM_OPTEE)) {
 		get_builtin_firmware_ext(imx8mm_bl32_bin, bl33, &bl32);
 		get_builtin_firmware(imx8mm_bl31_bin_optee, &bl31);
@@ -346,6 +367,9 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
 	imx8m_setup_snvs();
 	imx8mp_load_bl33(bl33);
 
+	/* Cache DRAM for the BL32 verify + BL31/BL32 memcpy that follow. */
+	imx8m_mmu_early_enable();
+
 	if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MP_OPTEE)) {
 		get_builtin_firmware_ext(imx8mp_bl32_bin, bl33, &bl32);
 		get_builtin_firmware(imx8mp_bl31_bin_optee, &bl31);
@@ -409,6 +433,9 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
 	imx8m_setup_snvs();
 	imx8mn_load_bl33(bl33);
 
+	/* Cache DRAM for the BL32 verify + BL31/BL32 memcpy that follow. */
+	imx8m_mmu_early_enable();
+
 	if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MN_OPTEE)) {
 		get_builtin_firmware_ext(imx8mn_bl32_bin, bl33, &bl32);
 		get_builtin_firmware(imx8mn_bl31_bin_optee, &bl31);
@@ -466,6 +493,9 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
 	imx8m_setup_snvs();
 	imx8mq_load_bl33(bl33);
 
+	/* Cache DRAM for the BL32 verify + BL31/BL32 memcpy that follow. */
+	imx8m_mmu_early_enable();
+
 	if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MQ_OPTEE)) {
 		get_builtin_firmware_ext(imx8mq_bl32_bin, bl33, &bl32);
 		get_builtin_firmware(imx8mq_bl31_bin_optee, &bl31);
-- 
2.43.0




  reply	other threads:[~2026-07-04 12:28 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-04 12:26 [PATCH v2 00/11] i.MX8M: speed up the PBL boot path (MMU, SHA-256, eMMC) Johannes Schneider
2026-07-04 12:26 ` Johannes Schneider [this message]
2026-07-04 12:26 ` [PATCH v2 02/11] crypto: sha256: PBL SHA-256 fast path via pbl/sha256.c Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 03/11] mci: sdhci: bail out on ADMA/transfer errors instead of hanging Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 04/11] mci: sdhci: honor BROKEN_ADMA_ZEROLEN_DESC / NO_ENDATTR_IN_NOPDESC quirks Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 05/11] mci: imx-esdhc: mark the uSDHC ADMA2 descriptor quirks Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 06/11] mci: imx-esdhc: support HS400 and HS400ES on i.MX8M Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 07/11] mci: imx-esdhc: make the transfer mode selectable (PIO/SDMA/ADMA2) Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 08/11] ARM: i.MX8M: enable the MMU before the PBL eMMC load Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 09/11] dma: provide the streaming DMA API in the PBL (opt-in via PBL_HAS_DMA) Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 10/11] mci: sdhci: honour dma_map/dma_sync in the PBL Johannes Schneider
2026-07-04 12:26 ` [PATCH v2 11/11] mci: imx-esdhc: DMA in the i.MX8M PBL eMMC loader Johannes Schneider

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260704122628.3326142-2-johannes.schneider@leica-geosystems.com \
    --to=johannes.schneider@leica-geosystems.com \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox