diff options
author | Andrew Thoelke <andrew.thoelke@arm.com> | 2014-05-16 12:26:26 +0100 |
---|---|---|
committer | Andrew Thoelke <andrew.thoelke@arm.com> | 2014-05-16 12:26:26 +0100 |
commit | ef27980d71d0f5f8f83895929e246d0495c9d189 (patch) | |
tree | 5e868eed032f450ad30961447a522249d744d74f /plat/fvp | |
parent | 19ea62d398f9dcb4d25f0856b3f44fb4bd0c4b83 (diff) | |
parent | b793e43166348772af74331df7be46d7a696a7aa (diff) |
Merge pull request #69 from sandrine-bailleux:sb/split-mmu-fcts-per-el
Diffstat (limited to 'plat/fvp')
-rw-r--r-- | plat/fvp/aarch64/plat_common.c | 173 | ||||
-rw-r--r-- | plat/fvp/bl1_plat_setup.c | 10 | ||||
-rw-r--r-- | plat/fvp/bl2_plat_setup.c | 10 | ||||
-rw-r--r-- | plat/fvp/bl31_plat_setup.c | 10 | ||||
-rw-r--r-- | plat/fvp/bl32_plat_setup.c | 10 | ||||
-rw-r--r-- | plat/fvp/platform.h | 18 |
6 files changed, 114 insertions, 117 deletions
diff --git a/plat/fvp/aarch64/plat_common.c b/plat/fvp/aarch64/plat_common.c index edeb6e0..099751d 100644 --- a/plat/fvp/aarch64/plat_common.c +++ b/plat/fvp/aarch64/plat_common.c @@ -47,81 +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; - unsigned long current_el = read_current_el(); - - /* 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 (GET_EL(current_el) == MODE_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 }, @@ -139,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 fd03ec2..edd3f7b 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 4c649eb..80bb52e 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 5c00baa..baf7df1 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 9fe8fe1..bb2b602 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 6c28a14..40f780e 100644 --- a/plat/fvp/platform.h +++ b/plat/fvp/platform.h @@ -373,12 +373,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); |