aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Clément Tosi <ptosi@google.com>2022-03-29 18:06:07 +0100
committerPierre-Clément Tosi <ptosi@google.com>2022-03-29 18:13:53 +0100
commitff9edd19f61ceaf690f3efb363ca2cff15541de3 (patch)
tree1fddb1cf22ee279ddb8c05c1b33bd74c6fac3f55
parent544489298a4c62be03951561fb71f1cba8db3988 (diff)
downloadu-boot-ff9edd19f61ceaf690f3efb363ca2cff15541de3.tar.gz
FROMLIST: armv8: Initialize MAIR in early boot
As the register is initialized to a constant value, it can be set at any point before the MMU has been enabled. Instead of waiting until the very last moment to do so, initialize it during early boot, when we initialize other system registers. This ensures it is valid at any point once the C runtime is up. (am from https://patchwork.ozlabs.org/project/uboot/patch/20220329170607 .689006-3-ptosi@google.com) Signed-off-by: Pierre-Clément Tosi <ptosi@google.com> Cc: Tom Rini <trini@konsulko.com> Change-Id: I1d57061e3871b64b7ddc6e97b0267a45f77337fd
-rw-r--r--arch/arm/cpu/armv8/Kconfig6
-rw-r--r--arch/arm/cpu/armv8/start.S12
-rw-r--r--arch/arm/include/asm/armv8/mmu.h5
3 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index fdcfd98a11..fa2fecf59f 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -35,6 +35,12 @@ config ARMV8_SET_SMPEN
it can be safely enabled when EL2/EL3 initialized SMPEN bit
or when CPU implementation doesn't include that register.
+config ARMV8_SET_MAIR
+ bool "Initialize the MAIR to its constant value out of boot"
+ default y if !SYS_DISABLE_DCACHE_OPS
+ help
+ Say Y here to set MAIR_ELx (MEMORY_ATTRIBUTES), needed by the MMU.
+
config ARMV8_SPIN_TABLE
bool "Support spin-table enable method"
depends on ARMV8_MULTIENTRY && OF_LIBFDT
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index b3eef705a5..a2b42c2712 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -139,6 +139,18 @@ pie_fixup_done:
msr cpacr_el1, x0 /* Enable FP/SIMD */
0:
+#ifdef CONFIG_ARMV8_SET_MAIR
+ ldr x2, =(MEMORY_ATTRIBUTES)
+ switch_el x1, 3f, 2f, 1f
+ b 0f
+3: msr mair_el3, x2
+ b 0f
+2: msr mair_el2, x2
+ b 0f
+1: msr mair_el1, x2
+0:
+#endif
+
#ifdef COUNTER_FREQUENCY
branch_if_not_highest_el x0, 4f
ldr x0, =COUNTER_FREQUENCY
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 9aadd0edd4..6f21f93712 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -115,21 +115,16 @@
static inline void set_ttbr_tcr(int el, u64 table, u64 tcr)
{
- const u64 attr = MEMORY_ATTRIBUTES;
-
asm volatile("dsb sy");
if (el == 1) {
asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory");
asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory");
- asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory");
} else if (el == 2) {
asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory");
asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory");
- asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory");
} else if (el == 3) {
asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory");
asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory");
- asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory");
} else {
hang();
}