From 99f607989133b12ef28b41aeb1251784b3a7052c Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 31 May 2017 13:31:48 +0100 Subject: [PATCH] xlat lib v2: Remove init_xlat_tables_arch() function In both the AArch32 and AArch64 versions, this function used to check the sanity of the PLAT_PHY_ADDR_SPACE_SIZE in regard to the architectural maximum value. Instead, export the xlat_arch_get_max_supported_pa() function and move the debug assertion in AArch-agnostic code. The AArch64 used to also precalculate the TCR.PS field value, based on the size of the physical address space. This is now done directly by enable_mmu_arch(), which now receives the physical address space size in argument. Change-Id: Ie77ea92eb06db586f28784fdb479c6e27dd1acc1 Signed-off-by: Sandrine Bailleux --- lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 13 +++----- lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 30 ++++++----------- lib/xlat_tables_v2/xlat_tables_internal.c | 33 ++++++++++++++----- lib/xlat_tables_v2/xlat_tables_private.h | 11 +++++-- 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index 40fd2d0b..84f1a7dd 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -14,7 +14,7 @@ #include "../xlat_tables_private.h" #if ENABLE_ASSERTIONS -static unsigned long long xlat_arch_get_max_supported_pa(void) +unsigned long long xlat_arch_get_max_supported_pa(void) { /* Physical address space size for long descriptor format. */ return (1ull << 40) - 1ull; @@ -81,18 +81,11 @@ uint64_t xlat_arch_get_xn_desc(int el __unused) return UPPER_ATTRS(XN); } -void init_xlat_tables_arch(unsigned long long max_pa) -{ - assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= - xlat_arch_get_max_supported_pa()); -} - /******************************************************************************* * Function for enabling the MMU in Secure PL1, assuming that the * page-tables have already been created. ******************************************************************************/ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table) - { u_register_t mair0, ttbcr, sctlr; uint64_t ttbr0; @@ -158,7 +151,9 @@ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table) isb(); } -void enable_mmu_arch(unsigned int flags, uint64_t *base_table) +void enable_mmu_arch(unsigned int flags, + uint64_t *base_table, + unsigned long long max_pa) { enable_mmu_internal_secure(flags, base_table); } diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index 14f6cd6a..ba1ab737 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -60,7 +60,7 @@ static const unsigned int pa_range_bits_arr[] = { PARANGE_0101 }; -static unsigned long long xlat_arch_get_max_supported_pa(void) +unsigned long long xlat_arch_get_max_supported_pa(void) { u_register_t pa_range = read_id_aa64mmfr0_el1() & ID_AA64MMFR0_EL1_PARANGE_MASK; @@ -146,24 +146,6 @@ uint64_t xlat_arch_get_xn_desc(int el) } } -void init_xlat_tables_arch(unsigned long long max_pa) -{ - assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= - xlat_arch_get_max_supported_pa()); - - /* - * If dynamic allocation of new regions is enabled the code can't make - * assumptions about the max physical address because it could change - * after adding new regions. If this functionality is disabled it is - * safer to restrict the max physical address as much as possible. - */ -#ifdef PLAT_XLAT_TABLES_DYNAMIC - tcr_ps_bits = calc_physical_addr_size_bits(PLAT_PHY_ADDR_SPACE_SIZE); -#else - tcr_ps_bits = calc_physical_addr_size_bits(max_pa); -#endif -} - /******************************************************************************* * Macro generating the code for the function enabling the MMU in the given * exception level, assuming that the pagetables have already been created. @@ -247,8 +229,16 @@ DEFINE_ENABLE_MMU_EL(3, tlbialle3) #endif -void enable_mmu_arch(unsigned int flags, uint64_t *base_table) +void enable_mmu_arch(unsigned int flags, + uint64_t *base_table, + unsigned long long max_pa) { + /* + * It is safer to restrict the max physical address accessible by the + * hardware as much as possible. + */ + tcr_ps_bits = calc_physical_addr_size_bits(max_pa); + #if IMAGE_EL == 1 assert(IS_IN_EL(1)); enable_mmu_internal_el1(flags, base_table); diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c index 82b3489c..cdf16694 100644 --- a/lib/xlat_tables_v2/xlat_tables_internal.c +++ b/lib/xlat_tables_v2/xlat_tables_internal.c @@ -1178,14 +1178,14 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx) mm++; } - ctx->initialized = 1; - - xlat_tables_print(ctx); - + assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= + xlat_arch_get_max_supported_pa()); assert(ctx->max_va <= ctx->va_max_address); assert(ctx->max_pa <= ctx->pa_max_address); - init_xlat_tables_arch(ctx->max_pa); + ctx->initialized = 1; + + xlat_tables_print(ctx); } void init_xlat_tables(void) @@ -1193,23 +1193,40 @@ void init_xlat_tables(void) init_xlat_tables_ctx(&tf_xlat_ctx); } +/* + * If dynamic allocation of new regions is disabled then by the time we call the + * function enabling the MMU, we'll have registered all the memory regions to + * map for the system's lifetime. Therefore, at this point we know the maximum + * physical address that will ever be mapped. + * + * If dynamic allocation is enabled then we can't make any such assumption + * because the maximum physical address could get pushed while adding a new + * region. Therefore, in this case we have to assume that the whole address + * space size might be mapped. + */ +#ifdef PLAT_XLAT_TABLES_DYNAMIC +#define MAX_PHYS_ADDR PLAT_PHY_ADDR_SPACE_SIZE +#else +#define MAX_PHYS_ADDR tf_xlat_ctx.max_pa +#endif + #ifdef AARCH32 void enable_mmu_secure(unsigned int flags) { - enable_mmu_arch(flags, tf_xlat_ctx.base_table); + enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR); } #else void enable_mmu_el1(unsigned int flags) { - enable_mmu_arch(flags, tf_xlat_ctx.base_table); + enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR); } void enable_mmu_el3(unsigned int flags) { - enable_mmu_arch(flags, tf_xlat_ctx.base_table); + enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR); } #endif /* AARCH32 */ diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h index 9ff1bdb3..30303888 100644 --- a/lib/xlat_tables_v2/xlat_tables_private.h +++ b/lib/xlat_tables_v2/xlat_tables_private.h @@ -72,11 +72,16 @@ int xlat_arch_current_el(void); */ uint64_t xlat_arch_get_xn_desc(int el); -/* Execute architecture-specific translation table initialization code. */ -void init_xlat_tables_arch(unsigned long long max_pa); +/* + * Return the maximum physical address supported by the hardware. + * This value depends on the execution state (AArch32/AArch64). + */ +unsigned long long xlat_arch_get_max_supported_pa(void); /* Enable MMU and configure it to use the specified translation tables. */ -void enable_mmu_arch(unsigned int flags, uint64_t *base_table); +void enable_mmu_arch(unsigned int flags, + uint64_t *base_table, + unsigned long long max_pa); /* Return 1 if the MMU of this Exception Level is enabled, 0 otherwise. */ int is_mmu_enabled(void); -- 2.30.2