aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c28
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c4
-rw-r--r--arch/arm/cpu/armv8/start.S2
-rw-r--r--arch/arm/include/asm/armv8/mmu.h4
4 files changed, 30 insertions, 8 deletions
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 3de18c7675b..e4736e56436 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -39,8 +39,28 @@ DECLARE_GLOBAL_DATA_PTR;
* off: FFF
*/
-u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
+static int get_effective_el(void)
{
+ int el = current_el();
+
+ if (el == 2) {
+ u64 hcr_el2;
+
+ /*
+ * If we are using the EL2&0 translation regime, the TCR_EL2
+ * looks like the EL1 version, even though we are in EL2.
+ */
+ __asm__ ("mrs %0, HCR_EL2\n" : "=r" (hcr_el2));
+ if (hcr_el2 & BIT(HCR_EL2_E2H_BIT))
+ return 1;
+ }
+
+ return el;
+}
+
+u64 get_tcr(u64 *pips, u64 *pva_bits)
+{
+ int el = get_effective_el();
u64 max_addr = 0;
u64 ips, va_bits;
u64 tcr;
@@ -115,7 +135,7 @@ static u64 *find_pte(u64 addr, int level)
debug("addr=%llx level=%d\n", addr, level);
- get_tcr(0, NULL, &va_bits);
+ get_tcr(NULL, &va_bits);
if (va_bits < 39)
start_level = 1;
@@ -343,7 +363,7 @@ __weak u64 get_page_table_size(void)
u64 va_bits;
int start_level = 0;
- get_tcr(0, NULL, &va_bits);
+ get_tcr(NULL, &va_bits);
if (va_bits < 39)
start_level = 1;
@@ -415,7 +435,7 @@ __weak void mmu_setup(void)
setup_all_pgtables();
el = current_el();
- set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(NULL, NULL),
MEMORY_ATTRIBUTES);
/* enable the mmu */
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 253008a9c13..c989a43cbeb 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -454,7 +454,7 @@ static inline void early_mmu_setup(void)
/* point TTBR to the new table */
set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
- get_tcr(el, NULL, NULL) &
+ get_tcr(NULL, NULL) &
~(TCR_ORGN_MASK | TCR_IRGN_MASK),
MEMORY_ATTRIBUTES);
@@ -609,7 +609,7 @@ static inline void final_mmu_setup(void)
invalidate_icache_all();
/* point TTBR to the new table */
- set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(NULL, NULL),
MEMORY_ATTRIBUTES);
set_sctlr(get_sctlr() | CR_M);
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index d328e8c08a1..28f0df13f0d 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -125,7 +125,7 @@ pie_fixup_done:
msr cptr_el3, xzr /* Enable FP/SIMD */
b 0f
2: mrs x1, hcr_el2
- tbnz x1, #34, 1f /* HCR_EL2.E2H */
+ tbnz x1, #HCR_EL2_E2H_BIT, 1f /* HCR_EL2.E2H */
orr x1, x1, #HCR_EL2_AMO_EL2 /* Route SErrors to EL2 */
msr hcr_el2, x1
set_vbar vbar_el2, x0
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index c36b2cf5a58..9f58cedb650 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -103,6 +103,8 @@
#define TCR_EL2_RSVD (1U << 31 | 1 << 23)
#define TCR_EL3_RSVD (1U << 31 | 1 << 23)
+#define HCR_EL2_E2H_BIT 34
+
#ifndef __ASSEMBLY__
static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
{
@@ -134,7 +136,7 @@ struct mm_region {
extern struct mm_region *mem_map;
void setup_pgtables(void);
-u64 get_tcr(int el, u64 *pips, u64 *pva_bits);
+u64 get_tcr(u64 *pips, u64 *pva_bits);
#endif
#endif /* _ASM_ARMV8_MMU_H_ */