diff --git a/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp b/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp index 4901634e8e..88655cb5e3 100644 --- a/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp @@ -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(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; } diff --git a/src/system/boot/platform/efi/arch/arm64/arch_start.cpp b/src/system/boot/platform/efi/arch/arm64/arch_start.cpp index 307bdbd020..2cc2f2abb2 100644 --- a/src/system/boot/platform/efi/arch/arm64/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/arm64/arch_start.cpp @@ -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(); }