From aa1d5f60474ae0508b2953c72148c176c08d9cfe Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Thu, 12 Jul 2018 15:43:07 +0100 Subject: [PATCH] xlat v2: Remove IMAGE_EL define The Exception Level is now detected at runtime. This means that it is not needed to hardcode the EL used by each image. This doesn't result in a substantial increase of the image size because the initialization functions that aren't used are garbage-collected by the linker. In AArch32 the current EL has been changed from EL3 to EL1 because the the AArch32 PL1&0 translation regime behaves more like the AArch64 EL1&0 translation regime than the EL3 one. Change-Id: I941404299ebe7666ca17619207c923b49a55cb73 Signed-off-by: Antonio Nino Diaz --- include/lib/xlat_tables/xlat_tables_v2.h | 7 ++--- .../lib/xlat_tables/xlat_tables_v2_helpers.h | 25 ----------------- lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 13 +++++---- lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 27 +++++++++---------- lib/xlat_tables_v2/xlat_tables_context.c | 18 ++++++++++--- lib/xlat_tables_v2/xlat_tables_private.h | 3 ++- 6 files changed, 41 insertions(+), 52 deletions(-) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 20a9ea1de..2e5aba527 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -121,10 +121,12 @@ typedef struct mmap_region { } mmap_region_t; /* - * Translation regimes supported by this library. + * Translation regimes supported by this library. EL_REGIME_INVALID tells the + * library to detect it at runtime. */ #define EL1_EL0_REGIME 1 #define EL3_REGIME 3 +#define EL_REGIME_INVALID -1 /* * Declare the translation context type. @@ -165,8 +167,7 @@ typedef struct xlat_ctx xlat_ctx_t; (_xlat_tables_count), \ (_virt_addr_space_size), \ (_phy_addr_space_size), \ - IMAGE_XLAT_DEFAULT_REGIME, \ - "xlat_table") + EL_REGIME_INVALID, "xlat_table") /* * Same as REGISTER_XLAT_CONTEXT plus the additional parameters: diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h index 56b9a93f4..4e79aeccc 100644 --- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h +++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h @@ -172,29 +172,4 @@ struct xlat_ctx { #endif /*__ASSEMBLY__*/ -#if AARCH64 - -/* - * This IMAGE_EL macro must not to be used outside the library, and it is only - * used in AArch64. - */ -#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3) -# define IMAGE_EL 3 -# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME -#else -# define IMAGE_EL 1 -# define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME -#endif - -#else /* if AARCH32 */ - -/* - * 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. - */ -#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME - -#endif /* AARCH64 */ - #endif /* __XLAT_TABLES_V2_HELPERS_H__ */ diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index 1e0a91d40..9302a19cd 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -97,18 +97,21 @@ 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 3; + return 1; } /******************************************************************************* * Function for enabling the MMU in Secure PL1, assuming that the page tables * have already been created. ******************************************************************************/ -void setup_mmu_cfg(unsigned int flags, - const uint64_t *base_table, - unsigned long long max_pa, - uintptr_t max_va) +void setup_mmu_cfg(unsigned int flags, const uint64_t *base_table, + unsigned long long max_pa, uintptr_t max_va, + __unused int xlat_regime) { u_register_t mair0, ttbcr; uint64_t ttbr0; diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index e42762582..00dc63b5d 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -180,10 +180,8 @@ int xlat_arch_current_el(void) return el; } -void setup_mmu_cfg(unsigned int flags, - const uint64_t *base_table, - unsigned long long max_pa, - uintptr_t max_va) +void setup_mmu_cfg(unsigned int flags, const uint64_t *base_table, + unsigned long long max_pa, uintptr_t max_va, int xlat_regime) { uint64_t mair, ttbr, tcr; uintptr_t virtual_addr_space_size; @@ -230,17 +228,16 @@ void setup_mmu_cfg(unsigned int flags, */ unsigned long long tcr_ps_bits = tcr_physical_addr_size_bits(max_pa); -#if IMAGE_EL == 1 - assert(IS_IN_EL(1)); - /* - * TCR_EL1.EPD1: Disable translation table walk for addresses that are - * translated using TTBR1_EL1. - */ - tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT); -#elif IMAGE_EL == 3 - assert(IS_IN_EL(3)); - tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT); -#endif + if (xlat_regime == EL1_EL0_REGIME) { + /* + * TCR_EL1.EPD1: Disable translation table walk for addresses + * that are translated using TTBR1_EL1. + */ + tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT); + } else { + assert(xlat_regime == EL3_REGIME); + tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT); + } mmu_cfg_params[MMU_CFG_MAIR0] = (uint32_t) mair; mmu_cfg_params[MMU_CFG_TCR] = (uint32_t) tcr; diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index 0964b49b2..671d8948b 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -69,6 +70,17 @@ int mmap_remove_dynamic_region(uintptr_t base_va, size_t size) void init_xlat_tables(void) { + assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID); + + int current_el = xlat_arch_current_el(); + + if (current_el == 1) { + tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME; + } else { + assert(current_el == 3); + tf_xlat_ctx.xlat_regime = EL3_REGIME; + } + init_xlat_tables_ctx(&tf_xlat_ctx); } @@ -94,7 +106,7 @@ void init_xlat_tables(void) void enable_mmu_secure(unsigned int flags) { setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR, - tf_xlat_ctx.va_max_address); + tf_xlat_ctx.va_max_address, EL1_EL0_REGIME); enable_mmu_direct(flags); } @@ -103,14 +115,14 @@ void enable_mmu_secure(unsigned int flags) void enable_mmu_el1(unsigned int flags) { setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR, - tf_xlat_ctx.va_max_address); + tf_xlat_ctx.va_max_address, EL1_EL0_REGIME); enable_mmu_direct_el1(flags); } void enable_mmu_el3(unsigned int flags) { setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR, - tf_xlat_ctx.va_max_address); + tf_xlat_ctx.va_max_address, EL3_REGIME); enable_mmu_direct_el3(flags); } diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h index 4661bb656..fa770dbbf 100644 --- a/lib/xlat_tables_v2/xlat_tables_private.h +++ b/lib/xlat_tables_v2/xlat_tables_private.h @@ -90,7 +90,8 @@ unsigned long long xlat_arch_get_max_supported_pa(void); /* Enable MMU and configure it to use the specified translation tables. */ void setup_mmu_cfg(unsigned int flags, const uint64_t *base_table, - unsigned long long max_pa, uintptr_t max_va); + unsigned long long max_pa, uintptr_t max_va, + int xlat_regime); /* * Return 1 if the MMU of the translation regime managed by the given xlat_ctx_t