mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2025-03-04 08:27:13 +00:00
Merge pull request #69 from sandrine-bailleux:sb/split-mmu-fcts-per-el
This commit is contained in:
commit
ef27980d71
@ -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
|
||||
|
@ -106,9 +106,7 @@ void __dead2 raise_el(aapcs64_params_t *args)
|
||||
*/
|
||||
void __dead2 change_el(el_change_info_t *info)
|
||||
{
|
||||
unsigned long current_el = read_current_el();
|
||||
|
||||
if (GET_EL(current_el) == MODE_EL3) {
|
||||
if (IS_IN_EL3()) {
|
||||
/*
|
||||
* We can go anywhere from EL3. So find where.
|
||||
* TODO: Lots to do if we are going non-secure.
|
||||
@ -551,7 +549,6 @@ void __dead2 run_image(unsigned long entrypoint,
|
||||
void *second_arg)
|
||||
{
|
||||
el_change_info_t run_image_info;
|
||||
unsigned long current_el = read_current_el();
|
||||
|
||||
/* Tell next EL what we want done */
|
||||
run_image_info.args.arg0 = RUN_IMAGE;
|
||||
@ -565,7 +562,7 @@ void __dead2 run_image(unsigned long entrypoint,
|
||||
* to jump to a higher EL and issue an SMC. Contents of argY
|
||||
* will go into the general purpose register xY e.g. arg0->x0
|
||||
*/
|
||||
if (GET_EL(current_el) == MODE_EL3) {
|
||||
if (IS_IN_EL3()) {
|
||||
run_image_info.args.arg1 = (unsigned long) first_arg;
|
||||
run_image_info.args.arg2 = (unsigned long) second_arg;
|
||||
} else {
|
||||
|
@ -264,5 +264,10 @@ extern void write_cpuectlr(unsigned long);
|
||||
extern void write_cptr_el2(unsigned long);
|
||||
extern void write_cptr_el3(unsigned long);
|
||||
|
||||
#define IS_IN_EL(x) \
|
||||
(GET_EL(read_current_el()) == MODE_EL##x)
|
||||
|
||||
#define IS_IN_EL1() IS_IN_EL(1)
|
||||
#define IS_IN_EL3() IS_IN_EL(3)
|
||||
|
||||
#endif /* __ARCH_HELPERS_H__ */
|
||||
|
@ -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);
|
||||
* 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(); \
|
||||
}
|
||||
|
||||
mmap_add(fvp_mmap);
|
||||
|
||||
init_xlat_tables();
|
||||
|
||||
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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user