aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2014-05-09 11:35:36 +0100
committerSandrine Bailleux <sandrine.bailleux@arm.com>2014-05-09 14:56:10 +0100
commitb793e43166348772af74331df7be46d7a696a7aa (patch)
tree849b8b5c0978a03431caa5df2578be3bc7f75bbd
parentb3254e8547707ff57ed7766aba53933884bd6a1c (diff)
downloadarm-trusted-firmware-b793e43166348772af74331df7be46d7a696a7aa.tar.gz
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
-rw-r--r--bl32/tsp/aarch64/tsp_entrypoint.S2
-rw-r--r--plat/fvp/aarch64/plat_common.c172
-rw-r--r--plat/fvp/bl1_plat_setup.c10
-rw-r--r--plat/fvp/bl2_plat_setup.c10
-rw-r--r--plat/fvp/bl31_plat_setup.c10
-rw-r--r--plat/fvp/bl32_plat_setup.c10
-rw-r--r--plat/fvp/platform.h18
-rw-r--r--services/std_svc/psci/psci_afflvl_on.c2
8 files changed, 116 insertions, 118 deletions
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 97d54f6..aeb54bc 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 9e205a0..099751d 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 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 3fe892e..7244866 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 8f9bb4d..9f4ebf6 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