[PATCH 43/78] ARM: aarch64: mmu: Fix TCR setting

Sascha Hauer s.hauer at pengutronix.de
Fri Mar 16 05:53:19 PDT 2018


A BITS_PER_VA value of 33 is a little small. Increase it to 39 which is
the maximum size we can do with 3 level page tables. The TCR value
depends on the current exception level, so we have to calculate the
value during runtime. To do this use a function derived from U-Boots
get_tcr function.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/cpu/mmu.h               |  7 -------
 arch/arm/cpu/mmu_64.c            | 31 ++++++++++++++++++++++++++++---
 arch/arm/include/asm/pgtable64.h |  3 ++-
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h
index 186d408ead..5803cb6a83 100644
--- a/arch/arm/cpu/mmu.h
+++ b/arch/arm/cpu/mmu.h
@@ -3,13 +3,6 @@
 
 #ifdef CONFIG_CPU_64v8
 
-#define TCR_FLAGS		(TCR_TG0_4K | \
-		TCR_SHARED_OUTER | \
-		TCR_SHARED_INNER | \
-		TCR_IRGN_WBWA | \
-		TCR_ORGN_WBWA | \
-		TCR_T0SZ(BITS_PER_VA))
-
 #ifndef __ASSEMBLY__
 
 static inline void set_ttbr_tcr_mair(int el, uint64_t table, uint64_t tcr, uint64_t attr)
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index c7590fa33c..7932185885 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -54,6 +54,27 @@ static void arm_mmu_not_initialized_error(void)
 	panic("MMU not initialized\n");
 }
 
+static uint64_t calc_tcr(int el)
+{
+	u64 ips, va_bits;
+	u64 tcr;
+
+	ips = 2;
+	va_bits = BITS_PER_VA;
+
+	if (el == 1)
+		tcr = (ips << 32) | TCR_EPD1_DISABLE;
+	else if (el == 2)
+		tcr = (ips << 16);
+	else
+		tcr = (ips << 16);
+
+	/* PTWs cacheable, inner/outer WBWA and inner shareable */
+	tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA;
+	tcr |= TCR_T0SZ(va_bits);
+
+	return tcr;
+}
 
 /*
  * Do it the simple way for now and invalidate the entire
@@ -254,6 +275,7 @@ static void mmu_enable(void)
 static int mmu_init(void)
 {
 	struct memory_bank *bank;
+	unsigned int el;
 
 	if (list_empty(&memory_banks))
 		/*
@@ -281,8 +303,8 @@ static int mmu_init(void)
 
 		memset(ttb, 0, GRANULE_SIZE);
 
-		set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS,
-				  MEMORY_ATTRIBUTES);
+		el = current_el();
+		set_ttbr_tcr_mair(el, (uint64_t)ttb, calc_tcr(el), MEMORY_ATTRIBUTES);
 	}
 
 	pr_debug("ttb: 0x%p\n", ttb);
@@ -323,11 +345,14 @@ void mmu_disable(void)
 
 void mmu_early_enable(uint64_t membase, uint64_t memsize, uint64_t _ttb)
 {
+	int el;
+
 	ttb = (uint64_t *)_ttb;
 
 	memset(ttb, 0, GRANULE_SIZE);
 
-	set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, MEMORY_ATTRIBUTES);
+	el = current_el();
+	set_ttbr_tcr_mair(el, (uint64_t)ttb, calc_tcr(el), MEMORY_ATTRIBUTES);
 
 	create_sections(0, 0, 1UL << (BITS_PER_VA - 1), UNCACHED_MEM);
 
diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h
index f2888c3ccd..d8382505d0 100644
--- a/arch/arm/include/asm/pgtable64.h
+++ b/arch/arm/include/asm/pgtable64.h
@@ -21,7 +21,7 @@
 #define UNUSED_DESC                0x6EbAAD0BBADbA6E0
 
 #define VA_START                   0x0
-#define BITS_PER_VA                33
+#define BITS_PER_VA                39
 
 /* Granule size of 4KB is being used */
 #define GRANULE_SIZE_SHIFT         12
@@ -116,6 +116,7 @@
 #define TCR_EL1_IPS_BITS	(UL(3) << 32)	/* 42 bits physical address */
 #define TCR_EL2_IPS_BITS	(3 << 16)	/* 42 bits physical address */
 #define TCR_EL3_IPS_BITS	(3 << 16)	/* 42 bits physical address */
+#define TCR_EPD1_DISABLE	(1 << 23)
 
 #define TCR_EL1_RSVD		(1 << 31)
 #define TCR_EL2_RSVD		(1 << 31 | 1 << 23)
-- 
2.16.1




More information about the barebox mailing list