From 1a92a0e00a5093c4b46a55b1eadb48187688caf7 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Tue, 7 Aug 2018 19:59:49 +0100 Subject: [PATCH] xlat v2: Support the EL2 translation regime The translation library is useful elsewhere. Even though this repository doesn't exercise the EL2 support of the library, it is better to have it here as well to make it easier to maintain. enable_mmu_secure() and enable_mmu_direct() have been deprecated. The functions are still present, but they are behind ERROR_DEPRECATED and they call the new functions enable_mmu_svc_mon() and enable_mmu_direct_svc_mon(). Change-Id: I13ad10cd048d9cc2d55e0fff9a5133671b67dcba Signed-off-by: Antonio Nino Diaz --- bl1/aarch32/bl1_exceptions.S | 2 +- include/lib/aarch32/arch.h | 26 ++++++ include/lib/aarch32/arch_helpers.h | 7 +- include/lib/aarch64/arch.h | 2 + include/lib/xlat_tables/xlat_mmu_helpers.h | 11 ++- include/lib/xlat_tables/xlat_tables_v2.h | 1 + lib/xlat_tables/aarch32/xlat_tables.c | 16 +++- lib/xlat_tables_v2/aarch32/enable_mmu.S | 60 +++++++++++- lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 91 +++++++++++++------ lib/xlat_tables_v2/aarch64/enable_mmu.S | 28 +++--- lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 13 ++- lib/xlat_tables_v2/xlat_tables_context.c | 32 ++++++- lib/xlat_tables_v2/xlat_tables_core.c | 4 +- lib/xlat_tables_v2/xlat_tables_utils.c | 7 +- plat/common/aarch32/plat_common.c | 2 +- 15 files changed, 251 insertions(+), 51 deletions(-) diff --git a/bl1/aarch32/bl1_exceptions.S b/bl1/aarch32/bl1_exceptions.S index 154054245..9b001a96f 100644 --- a/bl1/aarch32/bl1_exceptions.S +++ b/bl1/aarch32/bl1_exceptions.S @@ -116,7 +116,7 @@ func smc_handler /* Turn on the MMU */ mov r0, #DISABLE_DCACHE - bl enable_mmu_secure + bl enable_mmu_svc_mon /* Enable the data cache. */ ldcopr r9, SCTLR diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index a5366495e..6f0949bb2 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -313,6 +313,28 @@ #define TTBCR_T0SZ_SHIFT U(0) #define TTBCR_T0SZ_MASK U(0x7) +/* + * HTCR definitions + */ +#define HTCR_RES1 ((U(1) << 31) | (U(1) << 23)) + +#define HTCR_SH0_NON_SHAREABLE (U(0x0) << 12) +#define HTCR_SH0_OUTER_SHAREABLE (U(0x2) << 12) +#define HTCR_SH0_INNER_SHAREABLE (U(0x3) << 12) + +#define HTCR_RGN0_OUTER_NC (U(0x0) << 10) +#define HTCR_RGN0_OUTER_WBA (U(0x1) << 10) +#define HTCR_RGN0_OUTER_WT (U(0x2) << 10) +#define HTCR_RGN0_OUTER_WBNA (U(0x3) << 10) + +#define HTCR_RGN0_INNER_NC (U(0x0) << 8) +#define HTCR_RGN0_INNER_WBA (U(0x1) << 8) +#define HTCR_RGN0_INNER_WT (U(0x2) << 8) +#define HTCR_RGN0_INNER_WBNA (U(0x3) << 8) + +#define HTCR_T0SZ_SHIFT U(0) +#define HTCR_T0SZ_MASK U(0x7) + #define MODE_RW_SHIFT U(0x4) #define MODE_RW_MASK U(0x1) #define MODE_RW_32 U(0x1) @@ -433,6 +455,7 @@ #define TLBIMVA p15, 0, c8, c7, 1 #define TLBIMVAA p15, 0, c8, c7, 3 #define TLBIMVAAIS p15, 0, c8, c3, 3 +#define TLBIMVAHIS p15, 4, c8, c3, 1 #define BPIALLIS p15, 0, c7, c1, 6 #define BPIALL p15, 0, c7, c5, 6 #define ICIALLU p15, 0, c7, c5, 0 @@ -448,6 +471,8 @@ #define CLIDR p15, 1, c0, c0, 1 #define CSSELR p15, 2, c0, c0, 0 #define CCSIDR p15, 1, c0, c0, 0 +#define HTCR p15, 4, c2, c0, 2 +#define HMAIR0 p15, 4, c10, c2, 0 #define DBGOSDLR p14, 0, c1, c3, 4 /* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */ @@ -487,6 +512,7 @@ #define CNTVOFF_64 p15, 4, c14 #define VTTBR_64 p15, 6, c2 #define CNTPCT_64 p15, 0, c14 +#define HTTBR_64 p15, 4, c2 /* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */ #define ICC_SGI1R_EL1_64 p15, 0, c12 diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index beae5d065..aa68bcbe6 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -300,6 +300,7 @@ DEFINE_TLBIOP_FUNC(allis, TLBIALLIS) DEFINE_TLBIOP_PARAM_FUNC(mva, TLBIMVA) DEFINE_TLBIOP_PARAM_FUNC(mvaa, TLBIMVAA) DEFINE_TLBIOP_PARAM_FUNC(mvaais, TLBIMVAAIS) +DEFINE_TLBIOP_PARAM_FUNC(mvahis, TLBIMVAHIS) /* * BPI operation prototypes. @@ -320,6 +321,10 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) #define IS_IN_SECURE() \ (GET_NS_BIT(read_scr()) == 0) +#define IS_IN_HYP() (GET_M32(read_cpsr()) == MODE32_hyp) +#define IS_IN_SVC() (GET_M32(read_cpsr()) == MODE32_svc) +#define IS_IN_MON() (GET_M32(read_cpsr()) == MODE32_mon) +#define IS_IN_EL2() IS_IN_HYP() /* * If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3 */ diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index 397013e4e..c9619f6c6 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -364,7 +364,9 @@ * TCR defintions */ #define TCR_EL3_RES1 ((U(1) << 31) | (U(1) << 23)) +#define TCR_EL2_RES1 ((ULL(1) << 31) | (ULL(1) << 23)) #define TCR_EL1_IPS_SHIFT U(32) +#define TCR_EL2_PS_SHIFT U(16) #define TCR_EL3_PS_SHIFT U(16) #define TCR_TxSZ_MIN ULL(16) diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h index cd42c33e1..e1d02277b 100644 --- a/include/lib/xlat_tables/xlat_mmu_helpers.h +++ b/include/lib/xlat_tables/xlat_mmu_helpers.h @@ -67,15 +67,24 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, #ifdef AARCH32 /* AArch32 specific translation table API */ +#if !ERROR_DEPRECATED void enable_mmu_secure(unsigned int flags); - void enable_mmu_direct(unsigned int flags); +#endif + +void enable_mmu_svc_mon(unsigned int flags); +void enable_mmu_hyp(unsigned int flags); + +void enable_mmu_direct_svc_mon(unsigned int flags); +void enable_mmu_direct_hyp(unsigned int flags); #else /* AArch64 specific translation table APIs */ void enable_mmu_el1(unsigned int flags); +void enable_mmu_el2(unsigned int flags); void enable_mmu_el3(unsigned int flags); void enable_mmu_direct_el1(unsigned int flags); +void enable_mmu_direct_el2(unsigned int flags); void enable_mmu_direct_el3(unsigned int flags); #endif /* AARCH32 */ diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 022accee5..52c4dc6dd 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -125,6 +125,7 @@ typedef struct mmap_region { * library to detect it at runtime. */ #define EL1_EL0_REGIME 1 +#define EL2_REGIME 2 #define EL3_REGIME 3 #define EL_REGIME_INVALID -1 diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c index 87b15b8cf..033e2375f 100644 --- a/lib/xlat_tables/aarch32/xlat_tables.c +++ b/lib/xlat_tables/aarch32/xlat_tables.c @@ -65,7 +65,19 @@ void init_xlat_tables(void) * Function for enabling the MMU in Secure PL1, assuming that the * page-tables have already been created. ******************************************************************************/ +#if !ERROR_DEPRECATED void enable_mmu_secure(unsigned int flags) +{ + enable_mmu_svc_mon(flags); +} + +void enable_mmu_direct(unsigned int flags) +{ + enable_mmu_direct_svc_mon(flags); +} +#endif + +void enable_mmu_svc_mon(unsigned int flags) { unsigned int mair0, ttbcr, sctlr; uint64_t ttbr0; @@ -131,7 +143,7 @@ void enable_mmu_secure(unsigned int flags) isb(); } -void enable_mmu_direct(unsigned int flags) +void enable_mmu_direct_svc_mon(unsigned int flags) { - enable_mmu_secure(flags); + enable_mmu_svc_mon(flags); } diff --git a/lib/xlat_tables_v2/aarch32/enable_mmu.S b/lib/xlat_tables_v2/aarch32/enable_mmu.S index 99cf0881e..4a4ac30f5 100644 --- a/lib/xlat_tables_v2/aarch32/enable_mmu.S +++ b/lib/xlat_tables_v2/aarch32/enable_mmu.S @@ -8,9 +8,11 @@ #include #include - .global enable_mmu_direct + .global enable_mmu_direct_svc_mon + .global enable_mmu_direct_hyp -func enable_mmu_direct + /* void enable_mmu_direct_svc_mon(unsigned int flags) */ +func enable_mmu_direct_svc_mon /* Assert that MMU is turned off */ #if ENABLE_ASSERTIONS ldcopr r1, SCTLR @@ -63,4 +65,56 @@ func enable_mmu_direct isb bx lr -endfunc enable_mmu_direct +endfunc enable_mmu_direct_svc_mon + + + /* void enable_mmu_direct_hyp(unsigned int flags) */ +func enable_mmu_direct_hyp + /* Assert that MMU is turned off */ +#if ENABLE_ASSERTIONS + ldcopr r1, HSCTLR + tst r1, #HSCTLR_M_BIT + ASM_ASSERT(eq) +#endif + + /* Invalidate TLB entries */ + TLB_INVALIDATE(r0, TLBIALL) + + mov r3, r0 + ldr r0, =mmu_cfg_params + + /* HMAIR0 */ + ldr r1, [r0, #(MMU_CFG_MAIR << 3)] + stcopr r1, HMAIR0 + + /* HTCR */ + ldr r2, [r0, #(MMU_CFG_TCR << 3)] + stcopr r2, HTCR + + /* HTTBR */ + ldr r1, [r0, #(MMU_CFG_TTBR0 << 3)] + ldr r2, [r0, #((MMU_CFG_TTBR0 << 3) + 4)] + stcopr16 r1, r2, HTTBR_64 + + /* + * Ensure all translation table writes have drained into memory, the TLB + * invalidation is complete, and translation register writes are + * committed before enabling the MMU + */ + dsb ish + isb + + /* Enable enable MMU by honoring flags */ + ldcopr r1, HSCTLR + ldr r2, =(HSCTLR_WXN_BIT | HSCTLR_C_BIT | HSCTLR_M_BIT) + orr r1, r1, r2 + + /* Clear C bit if requested */ + tst r3, #DISABLE_DCACHE + bicne r1, r1, #HSCTLR_C_BIT + + stcopr r1, HSCTLR + isb + + bx lr +endfunc enable_mmu_direct_hyp diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index 24828409c..66938e5f1 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -43,22 +43,38 @@ unsigned long long xlat_arch_get_max_supported_pa(void) } #endif /* ENABLE_ASSERTIONS*/ -bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused) +bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx) { - return (read_sctlr() & SCTLR_M_BIT) != 0; + if (ctx->xlat_regime == EL1_EL0_REGIME) { + assert(xlat_arch_current_el() == 1U); + return (read_sctlr() & SCTLR_M_BIT) != 0U; + } else { + assert(ctx->xlat_regime == EL2_REGIME); + assert(xlat_arch_current_el() == 2U); + return (read_hsctlr() & HSCTLR_M_BIT) != 0U; + } } bool is_dcache_enabled(void) { - return (read_sctlr() & SCTLR_C_BIT) != 0; + if (IS_IN_EL2()) { + return (read_hsctlr() & HSCTLR_C_BIT) != 0U; + } else { + return (read_sctlr() & SCTLR_C_BIT) != 0U; + } } -uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime __unused) +uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime) { - return UPPER_ATTRS(XN); + if (xlat_regime == EL1_EL0_REGIME) { + return UPPER_ATTRS(XN) | UPPER_ATTRS(PXN); + } else { + assert(xlat_regime == EL2_REGIME); + return UPPER_ATTRS(XN); + } } -void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime __unused) +void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime) { /* * Ensure the translation table write has drained into memory before @@ -66,7 +82,12 @@ void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime __unused) */ dsbishst(); - tlbimvaais(TLBI_ADDR(va)); + if (xlat_regime == EL1_EL0_REGIME) { + tlbimvaais(TLBI_ADDR(va)); + } else { + assert(xlat_regime == EL2_REGIME); + tlbimvahis(TLBI_ADDR(va)); + } } void xlat_arch_tlbi_va_sync(void) @@ -97,19 +118,25 @@ void xlat_arch_tlbi_va_sync(void) unsigned int xlat_arch_current_el(void) { - /* - * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System, - * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. - * - * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime - * in AArch64 except for the XN bits, but we set and unset them at the - * same time, so there's no difference in practice. - */ - return 1U; + if (IS_IN_HYP()) { + return 2U; + } else { + assert(IS_IN_SVC() || IS_IN_MON()); + /* + * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, + * System, SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. + * + * The PL1&0 translation regime in AArch32 behaves like the + * EL1&0 regime in AArch64 except for the XN bits, but we set + * and unset them at the same time, so there's no difference in + * practice. + */ + return 1U; + } } /******************************************************************************* - * Function for enabling the MMU in Secure PL1, assuming that the page tables + * Function for enabling the MMU in PL1 or PL2, assuming that the page tables * have already been created. ******************************************************************************/ void setup_mmu_cfg(uint64_t *params, unsigned int flags, @@ -119,8 +146,6 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, uint64_t mair, ttbr0; uint32_t ttbcr; - assert(IS_IN_SECURE()); - /* Set attributes in the right indices of the MAIR */ mair = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); mair |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, @@ -129,18 +154,32 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, ATTR_NON_CACHEABLE_INDEX); /* - * Configure the control register for stage 1 of the PL1&0 translation - * regime. + * Configure the control register for stage 1 of the PL1&0 or EL2 + * translation regimes. */ /* Use the Long-descriptor translation table format. */ ttbcr = TTBCR_EAE_BIT; - /* - * Disable translation table walk for addresses that are translated - * using TTBR1. Therefore, only TTBR0 is used. - */ - ttbcr |= TTBCR_EPD1_BIT; + if (xlat_regime == EL1_EL0_REGIME) { + assert(IS_IN_SVC() || IS_IN_MON()); + /* + * Disable translation table walk for addresses that are + * translated using TTBR1. Therefore, only TTBR0 is used. + */ + ttbcr |= TTBCR_EPD1_BIT; + } else { + assert(xlat_regime == EL2_REGIME); + assert(IS_IN_HYP()); + + /* + * Set HTCR bits as well. Set HTTBR table properties + * as Inner & outer WBWA & shareable. + */ + ttbcr |= HTCR_RES1 | + HTCR_SH0_INNER_SHAREABLE | HTCR_RGN0_OUTER_WBA | + HTCR_RGN0_INNER_WBA; + } /* * Limit the input address ranges and memory region sizes translated diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S index 5c5a2a927..21717d28a 100644 --- a/lib/xlat_tables_v2/aarch64/enable_mmu.S +++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S @@ -9,6 +9,7 @@ #include .global enable_mmu_direct_el1 + .global enable_mmu_direct_el2 .global enable_mmu_direct_el3 /* Macros to read and write to system register for a given EL. */ @@ -20,6 +21,19 @@ mrs \gp_reg, \reg_name\()_el\()\el .endm + .macro tlbi_invalidate_all el + .if \el == 1 + TLB_INVALIDATE(vmalle1) + .elseif \el == 2 + TLB_INVALIDATE(alle2) + .elseif \el == 3 + TLB_INVALIDATE(alle3) + .else + .error "EL must be 1, 2 or 3" + .endif + .endm + + /* void enable_mmu_direct_el(unsigned int flags) */ .macro define_mmu_enable_func el func enable_mmu_direct_\()el\el #if ENABLE_ASSERTIONS @@ -27,17 +41,8 @@ tst x1, #SCTLR_M_BIT ASM_ASSERT(eq) #endif - - /* Invalidate TLB entries */ - .if \el == 1 - TLB_INVALIDATE(vmalle1) - .else - .if \el == 3 - TLB_INVALIDATE(alle3) - .else - .error "EL must be 1 or 3" - .endif - .endif + /* Invalidate all TLB entries */ + tlbi_invalidate_all \el mov x7, x0 ldr x0, =mmu_cfg_params @@ -86,4 +91,5 @@ * enable_mmu_direct_el3 */ define_mmu_enable_func 1 + define_mmu_enable_func 2 define_mmu_enable_func 3 diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index cf8070ad8..d1555bf27 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -105,6 +105,9 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx) if (ctx->xlat_regime == EL1_EL0_REGIME) { assert(xlat_arch_current_el() >= 1U); return (read_sctlr_el1() & SCTLR_M_BIT) != 0U; + } else if (ctx->xlat_regime == EL2_REGIME) { + assert(xlat_arch_current_el() >= 2U); + return (read_sctlr_el2() & SCTLR_M_BIT) != 0U; } else { assert(ctx->xlat_regime == EL3_REGIME); assert(xlat_arch_current_el() >= 3U); @@ -118,6 +121,8 @@ bool is_dcache_enabled(void) if (el == 1U) { return (read_sctlr_el1() & SCTLR_C_BIT) != 0U; + } else if (el == 2U) { + return (read_sctlr_el2() & SCTLR_C_BIT) != 0U; } else { return (read_sctlr_el3() & SCTLR_C_BIT) != 0U; } @@ -128,7 +133,8 @@ uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime) if (xlat_regime == EL1_EL0_REGIME) { return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN); } else { - assert(xlat_regime == EL3_REGIME); + assert((xlat_regime == EL2_REGIME) || + (xlat_regime == EL3_REGIME)); return UPPER_ATTRS(XN); } } @@ -151,6 +157,9 @@ void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime) if (xlat_regime == EL1_EL0_REGIME) { assert(xlat_arch_current_el() >= 1U); tlbivaae1is(TLBI_ADDR(va)); + } else if (xlat_regime == EL2_REGIME) { + assert(xlat_arch_current_el() >= 2U); + tlbivae2is(TLBI_ADDR(va)); } else { assert(xlat_regime == EL3_REGIME); assert(xlat_arch_current_el() >= 3U); @@ -245,6 +254,8 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, * that are translated using TTBR1_EL1. */ tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT); + } else if (xlat_regime == EL2_REGIME) { + tcr |= TCR_EL2_RES1 | (tcr_ps_bits << TCR_EL2_PS_SHIFT); } else { assert(xlat_regime == EL3_REGIME); tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT); diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index 143f08ab3..bf0cc9f5d 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -82,6 +82,8 @@ void init_xlat_tables(void) if (current_el == 1U) { tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME; + } else if (current_el == 2U) { + tf_xlat_ctx.xlat_regime = EL2_REGIME; } else { assert(current_el == 3U); tf_xlat_ctx.xlat_regime = EL3_REGIME; @@ -119,12 +121,32 @@ int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr) #ifdef AARCH32 +#if !ERROR_DEPRECATED void enable_mmu_secure(unsigned int flags) +{ + enable_mmu_svc_mon(flags); +} + +void enable_mmu_direct(unsigned int flags) +{ + enable_mmu_direct_svc_mon(flags); +} +#endif + +void enable_mmu_svc_mon(unsigned int flags) { setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR, tf_xlat_ctx.va_max_address, EL1_EL0_REGIME); - enable_mmu_direct(flags); + enable_mmu_direct_svc_mon(flags); +} + +void enable_mmu_hyp(unsigned int flags) +{ + setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, + tf_xlat_ctx.base_table, MAX_PHYS_ADDR, + tf_xlat_ctx.va_max_address, EL2_REGIME); + enable_mmu_direct_hyp(flags); } #else @@ -137,6 +159,14 @@ void enable_mmu_el1(unsigned int flags) enable_mmu_direct_el1(flags); } +void enable_mmu_el2(unsigned int flags) +{ + setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, + tf_xlat_ctx.base_table, MAX_PHYS_ADDR, + tf_xlat_ctx.va_max_address, EL2_REGIME); + enable_mmu_direct_el2(flags); +} + void enable_mmu_el3(unsigned int flags) { setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c index 56b9514c3..0340bf632 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -142,7 +142,8 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, desc |= LOWER_ATTRS(AP_NO_ACCESS_UNPRIVILEGED); } } else { - assert(ctx->xlat_regime == EL3_REGIME); + assert((ctx->xlat_regime == EL2_REGIME) || + (ctx->xlat_regime == EL3_REGIME)); desc |= LOWER_ATTRS(AP_ONE_VA_RANGE_RES1); } @@ -1016,6 +1017,7 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx) assert(ctx != NULL); assert(!ctx->initialized); assert((ctx->xlat_regime == EL3_REGIME) || + (ctx->xlat_regime == EL2_REGIME) || (ctx->xlat_regime == EL1_EL0_REGIME)); assert(!is_mmu_enabled_ctx(ctx)); diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c index 8cad3483f..05533c61d 100644 --- a/lib/xlat_tables_v2/xlat_tables_utils.c +++ b/lib/xlat_tables_v2/xlat_tables_utils.c @@ -60,8 +60,8 @@ static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc) tf_printf("DEV"); } - if (xlat_regime == EL3_REGIME) { - /* For EL3 only check the AP[2] and XN bits. */ + if ((xlat_regime == EL3_REGIME) || (xlat_regime == EL2_REGIME)) { + /* For EL3 and EL2 only check the AP[2] and XN bits. */ tf_printf(((desc & LOWER_ATTRS(AP_RO)) != 0ULL) ? "-RO" : "-RW"); tf_printf(((desc & UPPER_ATTRS(XN)) != 0ULL) ? "-XN" : "-EXEC"); } else { @@ -200,6 +200,8 @@ void xlat_tables_print(xlat_ctx_t *ctx) if (ctx->xlat_regime == EL1_EL0_REGIME) { xlat_regime_str = "1&0"; + } else if (ctx->xlat_regime == EL2_REGIME) { + xlat_regime_str = "2"; } else { assert(ctx->xlat_regime == EL3_REGIME); xlat_regime_str = "3"; @@ -329,6 +331,7 @@ static int xlat_get_mem_attributes_internal(const xlat_ctx_t *ctx, assert(ctx != NULL); assert(ctx->initialized); assert((ctx->xlat_regime == EL1_EL0_REGIME) || + (ctx->xlat_regime == EL2_REGIME) || (ctx->xlat_regime == EL3_REGIME)); virt_addr_space_size = (unsigned long long)ctx->va_max_address + 1ULL; diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c index 4f2714902..16c2b5c95 100644 --- a/plat/common/aarch32/plat_common.c +++ b/plat/common/aarch32/plat_common.c @@ -17,5 +17,5 @@ void bl32_plat_enable_mmu(uint32_t flags) { - enable_mmu_secure(flags); + enable_mmu_svc_mon(flags); }