arm64: introduce MMU support for EL3

Currently MMU supports only EL1.  Introduce EL3 support as well.

Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
This commit is contained in:
Eero Nurkkala 2024-05-15 14:30:12 +03:00 committed by Xiang Xiao
parent 0f9a262311
commit 505f57dd00

View File

@ -523,6 +523,40 @@ static void setup_page_tables(void)
}
}
#ifdef CONFIG_ARCH_BOOT_EL3
static void enable_mmu_el3(unsigned int flags)
{
uint64_t value;
UNUSED(flags);
/* Set MAIR, TCR and TBBR registers */
write_sysreg(MEMORY_ATTRIBUTES, mair_el3);
write_sysreg(get_tcr(3), tcr_el3);
write_sysreg(((uint64_t)base_xlat_table), ttbr0_el3);
/* Ensure these changes are seen before MMU is enabled */
ARM64_DSB();
ARM64_ISB();
/* Enable the MMU and data cache */
value = read_sysreg(sctlr_el3);
write_sysreg((value | SCTLR_M_BIT
#ifndef CONFIG_ARM64_DCACHE_DISABLE
| SCTLR_C_BIT
#endif
), sctlr_el3);
/* Ensure the MMU enable takes effect immediately */
ARM64_ISB();
#ifdef CONFIG_MMU_DEBUG
sinfo("MMU enabled with dcache\n");
#endif
}
#else
static void enable_mmu_el1(unsigned int flags)
{
uint64_t value;
@ -555,6 +589,7 @@ static void enable_mmu_el1(unsigned int flags)
sinfo("MMU enabled with dcache\n");
#endif
}
#endif
/***************************************************************************
* Public Functions
@ -588,19 +623,30 @@ int arm64_mmu_set_memregion(const struct arm_mmu_region *region)
int arm64_mmu_init(bool is_primary_core)
{
uint64_t val;
uint64_t el;
unsigned flags = 0;
/* Current MMU code supports only EL1 */
/* Current MMU code supports EL1 and EL3 */
__asm__ volatile ("mrs %0, CurrentEL" : "=r" (val));
__asm__ volatile ("mrs %0, CurrentEL" : "=r" (el));
__MMU_ASSERT(GET_EL(val) == MODE_EL1,
#ifdef CONFIG_ARCH_BOOT_EL3
__MMU_ASSERT(GET_EL(el) == MODE_EL3,
"Exception level not EL3, MMU not enabled!\n");
/* Ensure that MMU is already not enabled */
__asm__ volatile ("mrs %0, sctlr_el3" : "=r" (val));
__MMU_ASSERT((val & SCTLR_M_BIT) == 0, "MMU is already enabled\n");
#else
__MMU_ASSERT(GET_EL(el) == MODE_EL1,
"Exception level not EL1, MMU not enabled!\n");
/* Ensure that MMU is already not enabled */
__asm__ volatile ("mrs %0, sctlr_el1" : "=r" (val));
__MMU_ASSERT((val & SCTLR_M_BIT) == 0, "MMU is already enabled\n");
#endif
#ifdef CONFIG_MMU_DEBUG
sinfo("xlat tables:\n");
@ -617,9 +663,13 @@ int arm64_mmu_init(bool is_primary_core)
setup_page_tables();
}
/* currently only EL1 is supported */
/* Currently EL1 and EL3 are supported */
#ifdef CONFIG_ARCH_BOOT_EL3
enable_mmu_el3(flags);
#else
enable_mmu_el1(flags);
#endif
return 0;
}