diff --git a/Kernel/Arch/aarch64/CPU.h b/Kernel/Arch/aarch64/CPU.h index c13c7aa4e6..1145fa22d1 100644 --- a/Kernel/Arch/aarch64/CPU.h +++ b/Kernel/Arch/aarch64/CPU.h @@ -13,6 +13,7 @@ namespace Kernel { void initialize_exceptions(); void init_page_tables(); +void unmap_identity_map(); void panic_without_mmu(StringView); void dbgln_without_mmu(StringView); diff --git a/Kernel/Arch/aarch64/MMU.cpp b/Kernel/Arch/aarch64/MMU.cpp index 53e00af0be..1d3cfdf2f3 100644 --- a/Kernel/Arch/aarch64/MMU.cpp +++ b/Kernel/Arch/aarch64/MMU.cpp @@ -244,4 +244,25 @@ void init_page_tables() activate_mmu(); } +void unmap_identity_map() +{ + auto start_of_physical_memory = FlatPtr(START_OF_NORMAL_MEMORY); + + u64 level0_idx = (start_of_physical_memory >> 39) & 0x1FF; + u64 level1_idx = (start_of_physical_memory >> 30) & 0x1FF; + + u64* level1_table = (u64*)page_tables_phys_start; + + auto level2_table = FlatPtr(descriptor_to_pointer(level1_table[level0_idx])); + if (!level2_table) + panic_without_mmu("Could not find table!"sv); + + // NOTE: The function descriptor_to_pointer returns a physical address, but we want to unmap that range + // so, the pointer must be converted to a virtual address by adding KERNEL_MAPPING_BASE. + level2_table += KERNEL_MAPPING_BASE; + + // Unmap the complete identity map + ((u64*)level2_table)[level1_idx] = 0; +} + }