From: Sandrine Bailleux Date: Fri, 9 May 2014 10:35:36 +0000 (+0100) Subject: fvp: Provide per-EL MMU setup functions X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=b793e43166348772af74331df7be46d7a696a7aa;p=project%2Fbcm63xx%2Fatf.git fvp: Provide per-EL MMU setup functions Instead of having a single version of the MMU setup functions for all bootloader images that can execute either in EL3 or in EL1, provide separate functions for EL1 and EL3. Each bootloader image can then call the appropriate version of these functions. The aim is to reduce the amount of code compiled in each BL image by embedding only what's needed (e.g. BL1 to embed only EL3 variants). Change-Id: Ib86831d5450cf778ae78c9c1f7553fe91274c2fa --- diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S index 97d54f65..aeb54bc4 100644 --- a/bl32/tsp/aarch64/tsp_entrypoint.S +++ b/bl32/tsp/aarch64/tsp_entrypoint.S @@ -203,7 +203,7 @@ func tsp_cpu_on_entry * Initialise the MMU * --------------------------------------------- */ - bl enable_mmu + bl enable_mmu_el1 /* --------------------------------------------- * Give ourselves a stack allocated in Normal diff --git a/plat/fvp/aarch64/plat_common.c b/plat/fvp/aarch64/plat_common.c index 9e205a0d..099751dc 100644 --- a/plat/fvp/aarch64/plat_common.c +++ b/plat/fvp/aarch64/plat_common.c @@ -47,80 +47,68 @@ static unsigned long platform_config[CONFIG_LIMIT]; /******************************************************************************* - * Enable the MMU assuming that the pagetables have already been created - *******************************************************************************/ -void enable_mmu() -{ - unsigned long mair, tcr, ttbr, sctlr; - - /* Set the attributes in the right indices of the MAIR */ - mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); - mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, - ATTR_IWBWA_OWBWA_NTR_INDEX); - - /* - * Set TCR bits as well. Inner & outer WBWA & shareable + T0SZ = 32 - */ - tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | - TCR_RGN_INNER_WBA | TCR_T0SZ_4GB; - - /* Set TTBR bits as well */ - ttbr = (unsigned long) l1_xlation_table; - - if (IS_IN_EL3()) { - assert((read_sctlr_el3() & SCTLR_M_BIT) == 0); - - write_mair_el3(mair); - tcr |= TCR_EL3_RES1; - /* Invalidate EL3 TLBs */ - tlbialle3(); - - write_tcr_el3(tcr); - write_ttbr0_el3(ttbr); - - /* 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(); - isb(); - - sctlr = read_sctlr_el3(); - sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; - sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; - write_sctlr_el3(sctlr); - } else { - assert((read_sctlr_el1() & SCTLR_M_BIT) == 0); - - write_mair_el1(mair); - /* Invalidate EL1 TLBs */ - tlbivmalle1(); - - write_tcr_el1(tcr); - write_ttbr0_el1(ttbr); - - /* 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(); - isb(); - - sctlr = read_sctlr_el1(); - sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; - sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; - write_sctlr_el1(sctlr); + * Macro generating the code for the function enabling the MMU in the given + * exception level, assuming that the pagetables have already been created. + * + * _el: Exception level at which the function will run + * _tcr_extra: Extra bits to set in the TCR register. This mask will + * be OR'ed with the default TCR value. + * _tlbi_fct: Function to invalidate the TLBs at the current + * exception level + ******************************************************************************/ +#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \ + void enable_mmu_el##_el(void) \ + { \ + uint64_t mair, tcr, ttbr; \ + uint32_t sctlr; \ + \ + assert(IS_IN_EL(_el)); \ + assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0); \ + \ + /* Set attributes in the right indices of the MAIR */ \ + mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \ + mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \ + ATTR_IWBWA_OWBWA_NTR_INDEX); \ + write_mair_el##_el(mair); \ + \ + /* Invalidate TLBs at the current exception level */ \ + _tlbi_fct(); \ + \ + /* Set TCR bits as well. */ \ + /* Inner & outer WBWA & shareable + T0SZ = 32 */ \ + tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | \ + TCR_RGN_INNER_WBA | TCR_T0SZ_4GB; \ + tcr |= _tcr_extra; \ + write_tcr_el##_el(tcr); \ + \ + /* Set TTBR bits as well */ \ + ttbr = (uint64_t) l1_xlation_table; \ + write_ttbr0_el##_el(ttbr); \ + \ + /* 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(); \ + isb(); \ + \ + sctlr = read_sctlr_el##_el(); \ + sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; \ + sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; \ + write_sctlr_el##_el(sctlr); \ + \ + /* Ensure the MMU enable takes effect immediately */ \ + isb(); \ } - /* ensure the MMU enable takes effect immediately */ - isb(); - return; -} +/* Define EL1 and EL3 variants of the function enabling the MMU */ +DEFINE_ENABLE_MMU_EL(1, 0, tlbivmalle1) +DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1, tlbialle3) /* * Table of regions to map using the MMU. - * This doesn't include TZRAM as the 'mem_layout' argument passed to to - * configure_mmu() will give the available subset of that, + * This doesn't include TZRAM as the 'mem_layout' argument passed to + * configure_mmu_elx() will give the available subset of that, */ const mmap_region_t fvp_mmap[] = { { TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE }, @@ -138,28 +126,32 @@ const mmap_region_t fvp_mmap[] = { }; /******************************************************************************* - * Setup the pagetables as per the platform memory map & initialize the mmu - *******************************************************************************/ -void configure_mmu(meminfo_t *mem_layout, - unsigned long ro_start, - unsigned long ro_limit, - unsigned long coh_start, - unsigned long coh_limit) -{ - mmap_add_region(mem_layout->total_base, mem_layout->total_size, - MT_MEMORY | MT_RW | MT_SECURE); - mmap_add_region(ro_start, ro_limit - ro_start, - MT_MEMORY | MT_RO | MT_SECURE); - mmap_add_region(coh_start, coh_limit - coh_start, - MT_DEVICE | MT_RW | MT_SECURE); - - mmap_add(fvp_mmap); - - init_xlat_tables(); + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void configure_mmu_el##_el(meminfo_t *mem_layout, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(mem_layout->total_base, \ + mem_layout->total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(ro_start, ro_limit - ro_start, \ + MT_MEMORY | MT_RO | MT_SECURE); \ + mmap_add_region(coh_start, coh_limit - coh_start, \ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(fvp_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_el##_el(); \ + } - enable_mmu(); - return; -} +/* Define EL1 and EL3 variants of the function initialising the MMU */ +DEFINE_CONFIGURE_MMU_EL(1) +DEFINE_CONFIGURE_MMU_EL(3) /* Simple routine which returns a configuration variable value */ unsigned long platform_get_cfgvar(unsigned int var_id) diff --git a/plat/fvp/bl1_plat_setup.c b/plat/fvp/bl1_plat_setup.c index fd03ec2d..edd3f7b2 100644 --- a/plat/fvp/bl1_plat_setup.c +++ b/plat/fvp/bl1_plat_setup.c @@ -138,9 +138,9 @@ void bl1_plat_arch_setup(void) cci_enable_coherency(read_mpidr()); } - configure_mmu(&bl1_tzram_layout, - TZROM_BASE, - TZROM_BASE + TZROM_SIZE, - BL1_COHERENT_RAM_BASE, - BL1_COHERENT_RAM_LIMIT); + configure_mmu_el3(&bl1_tzram_layout, + TZROM_BASE, + TZROM_BASE + TZROM_SIZE, + BL1_COHERENT_RAM_BASE, + BL1_COHERENT_RAM_LIMIT); } diff --git a/plat/fvp/bl2_plat_setup.c b/plat/fvp/bl2_plat_setup.c index 4c649eb7..80bb52e5 100644 --- a/plat/fvp/bl2_plat_setup.c +++ b/plat/fvp/bl2_plat_setup.c @@ -172,9 +172,9 @@ void bl2_platform_setup() ******************************************************************************/ void bl2_plat_arch_setup() { - configure_mmu(&bl2_tzram_layout, - BL2_RO_BASE, - BL2_RO_LIMIT, - BL2_COHERENT_RAM_BASE, - BL2_COHERENT_RAM_LIMIT); + configure_mmu_el1(&bl2_tzram_layout, + BL2_RO_BASE, + BL2_RO_LIMIT, + BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT); } diff --git a/plat/fvp/bl31_plat_setup.c b/plat/fvp/bl31_plat_setup.c index 5c00baa4..baf7df15 100644 --- a/plat/fvp/bl31_plat_setup.c +++ b/plat/fvp/bl31_plat_setup.c @@ -172,9 +172,9 @@ void bl31_platform_setup() ******************************************************************************/ void bl31_plat_arch_setup() { - configure_mmu(&bl2_to_bl31_args->bl31_meminfo, - BL31_RO_BASE, - BL31_RO_LIMIT, - BL31_COHERENT_RAM_BASE, - BL31_COHERENT_RAM_LIMIT); + configure_mmu_el3(&bl2_to_bl31_args->bl31_meminfo, + BL31_RO_BASE, + BL31_RO_LIMIT, + BL31_COHERENT_RAM_BASE, + BL31_COHERENT_RAM_LIMIT); } diff --git a/plat/fvp/bl32_plat_setup.c b/plat/fvp/bl32_plat_setup.c index 9fe8fe1c..bb2b602f 100644 --- a/plat/fvp/bl32_plat_setup.c +++ b/plat/fvp/bl32_plat_setup.c @@ -111,9 +111,9 @@ void bl32_platform_setup() ******************************************************************************/ void bl32_plat_arch_setup() { - configure_mmu(&bl32_tzdram_layout, - BL32_RO_BASE, - BL32_RO_LIMIT, - BL32_COHERENT_RAM_BASE, - BL32_COHERENT_RAM_LIMIT); + configure_mmu_el1(&bl32_tzdram_layout, + BL32_RO_BASE, + BL32_RO_LIMIT, + BL32_COHERENT_RAM_BASE, + BL32_COHERENT_RAM_LIMIT); } diff --git a/plat/fvp/platform.h b/plat/fvp/platform.h index 3fe892ec..7244866e 100644 --- a/plat/fvp/platform.h +++ b/plat/fvp/platform.h @@ -370,12 +370,18 @@ extern void bl2_plat_arch_setup(void); extern void bl31_plat_arch_setup(void); extern int platform_setup_pm(const struct plat_pm_ops **); extern unsigned int platform_get_core_pos(unsigned long mpidr); -extern void enable_mmu(void); -extern void configure_mmu(struct meminfo *, - unsigned long, - unsigned long, - unsigned long, - unsigned long); +extern void enable_mmu_el1(void); +extern void enable_mmu_el3(void); +extern void configure_mmu_el1(struct meminfo *mem_layout, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); +extern void configure_mmu_el3(struct meminfo *mem_layout, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit); extern unsigned long platform_get_cfgvar(unsigned int); extern int platform_config_setup(void); extern void plat_report_exception(unsigned long); diff --git a/services/std_svc/psci/psci_afflvl_on.c b/services/std_svc/psci/psci_afflvl_on.c index 8f9bb4de..9f4ebf6b 100644 --- a/services/std_svc/psci/psci_afflvl_on.c +++ b/services/std_svc/psci/psci_afflvl_on.c @@ -362,7 +362,7 @@ static unsigned int psci_afflvl0_on_finish(unsigned long mpidr, /* * Arch. management: Turn on mmu & restore architectural state */ - enable_mmu(); + enable_mmu_el3(); /* * All the platform specific actions for turning this cpu