boot/efi/arm64: Rework exception level handling
* Deal additionally with EL1 context * Reuse possible present TTBRx allocations * Dump MMU & System Control Registers Change-Id: If27531f3c9d3fa096da11e8a7d46dd7d82a90e33 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5108 Tested-by: Commit checker robot <[email protected]> Reviewed-by: David Karoly <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
committed by
Fredrik Holmqvist
parent
09ea42fa68
commit
c1c3f9812b
@@ -411,14 +411,22 @@ arch_mmu_post_efi_setup(size_t memory_map_size,
|
||||
void
|
||||
arch_mmu_allocate_kernel_page_tables(void)
|
||||
{
|
||||
uint64* page = CurrentRegime.AllocatePage();
|
||||
uint64* page = reinterpret_cast<uint64*>(READ_SPECIALREG(TTBR1_EL1));
|
||||
|
||||
if (page != NULL) {
|
||||
WRITE_SPECIALREG(TTBR1_EL1, page);
|
||||
sPageDirectory = page;
|
||||
// NOTE: On devices supporting multiple translation base registers, TTBR0 must
|
||||
// be used solely.
|
||||
if (page == NULL) {
|
||||
page = CurrentRegime.AllocatePage();
|
||||
if (page != NULL) {
|
||||
WRITE_SPECIALREG(TTBR1_EL1, page);
|
||||
} else {
|
||||
panic("Not enough memory for kernel initial page\n");
|
||||
}
|
||||
} else {
|
||||
panic("Not enough memory for kernel initial page\n");
|
||||
TRACE(("TTBR1_EL1 present ..."));
|
||||
}
|
||||
|
||||
sPageDirectory = page;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -150,30 +150,40 @@ arch_start_kernel(addr_t kernelEntry)
|
||||
* On AArch64 UEFI shall execute as 64-bit code at either EL1 or EL2,
|
||||
* depending on whether or not virtualization is available at OS load time."
|
||||
*/
|
||||
if (arch_exception_level() != 1) {
|
||||
dprintf("Current Exception Level EL%1ld\n", arch_exception_level());
|
||||
if (arch_exception_level() == 2) {
|
||||
/* Transitioning from EL we lose present MMU configuration
|
||||
* which we would like to preserve e.g. peripherals mappings */
|
||||
if (arch_mmu_enabled()) {
|
||||
dprintf("MMU Enabled, Translation Table @ %lx Granularity %s, bits %d\n",
|
||||
arch_mmu_base_register(),
|
||||
granule_type_str(arch_mmu_user_granule()),
|
||||
arch_mmu_user_address_bits());
|
||||
dprintf("Current Exception Level EL%1lx\n", arch_exception_level());
|
||||
dprintf("TTBR0: %" B_PRIx64 " TTBRx: %" B_PRIx64 " SCTLR: %" B_PRIx64 " TCR: %" B_PRIx64 "\n",
|
||||
arch_mmu_base_register(),
|
||||
arch_mmu_base_register(true),
|
||||
_arch_mmu_get_sctlr(),
|
||||
_arch_mmu_get_tcr());
|
||||
|
||||
dprintf("Kernel entry accessibility W: %x R: %x\n",
|
||||
arch_mmu_write_access(kernelEntry),
|
||||
arch_mmu_read_access(kernelEntry));
|
||||
if (arch_mmu_enabled()) {
|
||||
dprintf("MMU Enabled, Granularity %s, bits %d\n",
|
||||
granule_type_str(arch_mmu_user_granule()),
|
||||
arch_mmu_user_address_bits());
|
||||
|
||||
arch_mmu_dump_present_tables();
|
||||
dprintf("Kernel entry accessibility W: %x R: %x\n",
|
||||
arch_mmu_write_access(kernelEntry),
|
||||
arch_mmu_read_access(kernelEntry));
|
||||
|
||||
el2toel1 = true; // we want to print before exit services
|
||||
}
|
||||
arch_mmu_dump_present_tables();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Not ready, undexpected any transition different than EL2 >> EL1
|
||||
switch (arch_exception_level()) {
|
||||
case 1:
|
||||
/* arch_cache_disable(); */
|
||||
/* arch_mmu_generate_post_efi_page_tables */
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
el2toel1 = true; // we want to print before exit services
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unexpected Exception Level\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +225,9 @@ arch_start_kernel(addr_t kernelEntry)
|
||||
|
||||
_arch_transition_EL2_EL1();
|
||||
|
||||
arch_cache_enable();
|
||||
} else {
|
||||
|
||||
arch_cache_enable();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user