[arch][arm64] determine the correct TCR_EL1.IPS at runtime
Change the early startup code to set TCR_EL1.IPS to ID_AA64MMFR0_EL1.PARange if it has a defined value (the currently defined values have the same meanings), but use 48-bit PAs if 52-bit PAs are supported because 52-bit PAs have a different translation table format that we don't support. Stash the computed TCR_EL1 in a variable and use it in the context switch code.
This commit is contained in:
committed by
Travis Geiselbrecht
parent
cd96c43006
commit
576a7a7c82
@@ -197,8 +197,6 @@
|
||||
MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \
|
||||
MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7 )
|
||||
|
||||
#define MMU_TCR_IPS_DEFAULT MMU_TCR_IPS(2) /* TODO: read at runtime, or configure per platform */
|
||||
|
||||
/* Enable cached page table walks:
|
||||
* inner/outer (IRGN/ORGN): write-back + write-allocate
|
||||
*/
|
||||
@@ -212,8 +210,9 @@
|
||||
MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
|
||||
MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
|
||||
MMU_TCR_T0SZ(64 - MMU_USER_SIZE_SHIFT))
|
||||
#define MMU_TCR_FLAGS_KERNEL (MMU_TCR_IPS_DEFAULT | MMU_TCR_FLAGS1 | MMU_TCR_FLAGS0 | MMU_TCR_EPD0)
|
||||
#define MMU_TCR_FLAGS_USER (MMU_TCR_IPS_DEFAULT | MMU_TCR_FLAGS1 | MMU_TCR_FLAGS0)
|
||||
#define MMU_TCR_FLAGS_BASE (MMU_TCR_FLAGS1 | MMU_TCR_FLAGS0)
|
||||
#define MMU_TCR_FLAGS_KERNEL (MMU_TCR_EPD0)
|
||||
#define MMU_TCR_FLAGS_USER (0)
|
||||
|
||||
#define MMU_PTE_KERNEL_RO_FLAGS \
|
||||
(MMU_PTE_ATTR_UXN | \
|
||||
|
||||
@@ -30,6 +30,9 @@ pte_t arm64_kernel_translation_table[MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP]
|
||||
__ALIGNED(MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP * 8)
|
||||
__SECTION(".bss.prebss.translation_table");
|
||||
|
||||
/* the base TCR flags, computed from early init code in start.S */
|
||||
uint64_t arm64_mmu_tcr_flags __SECTION(".bss.prebss.tcr_flags");
|
||||
|
||||
static inline bool is_valid_vaddr(arch_aspace_t *aspace, vaddr_t vaddr) {
|
||||
return (vaddr >= aspace->base && vaddr <= aspace->base + aspace->size - 1);
|
||||
}
|
||||
@@ -630,12 +633,12 @@ void arch_mmu_context_switch(arch_aspace_t *aspace) {
|
||||
if (TRACE_CONTEXT_SWITCH)
|
||||
TRACEF("aspace %p\n", aspace);
|
||||
|
||||
uint64_t tcr;
|
||||
uint64_t tcr = arm64_mmu_tcr_flags;
|
||||
uint64_t ttbr;
|
||||
if (aspace) {
|
||||
DEBUG_ASSERT((aspace->flags & ARCH_ASPACE_FLAG_KERNEL) == 0);
|
||||
|
||||
tcr = MMU_TCR_FLAGS_USER;
|
||||
tcr |= MMU_TCR_FLAGS_USER;
|
||||
ttbr = ((uint64_t)MMU_ARM64_USER_ASID << 48) | aspace->tt_phys;
|
||||
ARM64_WRITE_SYSREG(ttbr0_el1, ttbr);
|
||||
|
||||
@@ -643,7 +646,7 @@ void arch_mmu_context_switch(arch_aspace_t *aspace) {
|
||||
TRACEF("ttbr 0x%llx, tcr 0x%llx\n", ttbr, tcr);
|
||||
ARM64_TLBI(aside1, (uint64_t)MMU_ARM64_USER_ASID << 48);
|
||||
} else {
|
||||
tcr = MMU_TCR_FLAGS_KERNEL;
|
||||
tcr |= MMU_TCR_FLAGS_KERNEL;
|
||||
|
||||
if (TRACE_CONTEXT_SWITCH)
|
||||
TRACEF("tcr 0x%llx\n", tcr);
|
||||
|
||||
@@ -266,6 +266,25 @@ arm_reset:
|
||||
b .Lmap_range_one_table_loop
|
||||
|
||||
.Linitial_mapping_done:
|
||||
/* compute the base TCR configuration and save away in a global for future use */
|
||||
ldr tmp, =MMU_TCR_FLAGS_BASE
|
||||
|
||||
/* Set TCR_EL1.IPS to ID_AA64MMFR0_EL1.PARange */
|
||||
mrs tmp2, id_aa64mmfr0_el1
|
||||
and tmp2, tmp2, #0xf
|
||||
/*
|
||||
* Give up if we see a reserved value. 52-bit PAs have a different translation
|
||||
* table format that we don't support, so use 48-bit PAs in that case.
|
||||
*/
|
||||
cmp tmp2, #6
|
||||
b.hi .
|
||||
b.lo 1f
|
||||
mov tmp2, #5
|
||||
1:
|
||||
orr tmp, tmp, tmp2, lsl #32
|
||||
adrp tmp2, arm64_mmu_tcr_flags
|
||||
str tmp, [tmp2, #:lo12:arm64_mmu_tcr_flags]
|
||||
|
||||
#if WITH_SMP
|
||||
adrp tmp, page_tables_not_ready
|
||||
add tmp, tmp, #:lo12:page_tables_not_ready
|
||||
@@ -295,7 +314,9 @@ arm_reset:
|
||||
/* Initialize TCR_EL1 */
|
||||
/* set cacheable attributes on translation walk */
|
||||
/* (SMP extensions) non-shareable, inner write-back write-allocate */
|
||||
ldr tmp, =MMU_TCR_FLAGS_KERNEL
|
||||
adrp tmp, arm64_mmu_tcr_flags
|
||||
ldr tmp, [tmp, #:lo12:arm64_mmu_tcr_flags]
|
||||
orr tmp, tmp, #MMU_TCR_FLAGS_KERNEL
|
||||
msr tcr_el1, tmp
|
||||
|
||||
isb
|
||||
|
||||
Reference in New Issue
Block a user