When U-Boot is loaded by XBL in snagboot mode, XBL leaves the MMU
enabled with its own page tables. This causes stale TLB entries and
incorrect memory mappings when U-Boot initializes its own MMU.

Disable the MMU and invalidate TLBs at the earliest entry point,
before branching to the reset vector, handling EL1, EL2, and EL3.
This ensures a clean MMU state for U-Boot initialization.

The changes in this patch are based on:
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/u-boot/[email protected]/

Signed-off-by: Balaji Selvanathan <[email protected]>
---
Changes in v2:
- Newly introduced in v2
---
 arch/arm/mach-snapdragon/include/mach/boot0.h | 46 +++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/arm/mach-snapdragon/include/mach/boot0.h 
b/arch/arm/mach-snapdragon/include/mach/boot0.h
index 032a9fbdb12..c31bf6f52c5 100644
--- a/arch/arm/mach-snapdragon/include/mach/boot0.h
+++ b/arch/arm/mach-snapdragon/include/mach/boot0.h
@@ -8,6 +8,52 @@
 #elif defined(CONFIG_QCOM_EL2_GUNYAH_EXIT_SUPPORT)
 #include "gunyah_exit_boot0.h"
 #else
+       /*
+        * Disable MMU at the earliest possible point.
+        * This must be done before any other U-Boot code executes.
+        * Handle all exception levels (EL1, EL2, EL3).
+        *
+        * After disabling MMU, invalidate TLB to clear any stale entries
+        * that might cause issues when MMU is re-enabled later.
+        */
+       mrs     x0, CurrentEL
+       cmp     x0, #(3 << 2)   /* EL3? */
+       b.eq    disable_mmu_el3
+       cmp     x0, #(2 << 2)   /* EL2? */
+       b.eq    disable_mmu_el2
+       /* EL1 */
+       mrs     x0, sctlr_el1
+       bic     x0, x0, #1      /* Clear M bit (MMU enable) */
+       msr     sctlr_el1, x0
+       isb
+       /* Invalidate TLB for EL1 */
+       tlbi    vmalle1
+       dsb     sy
+       isb
+       b       mmu_disabled
+disable_mmu_el3:
+       mrs     x0, sctlr_el3
+       bic     x0, x0, #1      /* Clear M bit (MMU enable) */
+       bic     x0, x0, #(1 << 19)  /* Clear WXN bit (Write XOR Execute) */
+       msr     sctlr_el3, x0
+       isb
+       /* Invalidate entire TLB for all ELs */
+       tlbi    alle3
+       dsb     sy
+       isb
+       b       mmu_disabled
+disable_mmu_el2:
+       mrs     x0, sctlr_el2
+       bic     x0, x0, #1      /* Clear M bit (MMU enable) */
+       msr     sctlr_el2, x0
+       isb
+       /* Invalidate TLB for EL2 */
+       tlbi    alle2
+       dsb     sy
+       isb
+mmu_disabled:
+
        b       reset
+
 #endif
 #endif

-- 
2.34.1

Reply via email to