diff --git a/headers/private/kernel/arch/arm64/arch_kernel_args.h b/headers/private/kernel/arch/arm64/arch_kernel_args.h index dfeb8bc037..459ce88c4b 100644 --- a/headers/private/kernel/arch/arm64/arch_kernel_args.h +++ b/headers/private/kernel/arch/arm64/arch_kernel_args.h @@ -17,12 +17,17 @@ #define _PACKED __attribute__((packed)) +#define MAX_VIRTUAL_RANGES_TO_KEEP 32 typedef struct { uint64 phys_pgdir; uint64 vir_pgdir; uint64 next_pagetable; + // The virtual ranges we want to keep in the kernel. + uint32 num_virtual_ranges_to_keep; + addr_range virtual_ranges_to_keep[MAX_VIRTUAL_RANGES_TO_KEEP]; + // needed for UEFI, otherwise kernel acpi support can't find ACPI root FixedWidthPointer acpi_root; FixedWidthPointer fdt; 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 1030e6befb..a6e4034582 100644 --- a/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp @@ -402,6 +402,13 @@ arch_mmu_post_efi_setup(size_t memory_map_size, start, start + size, size)); } + TRACE(("virt memory ranges to keep:\n")); + for (uint32_t i = 0; i < gKernelArgs.arch_args.num_virtual_ranges_to_keep; i++) { + uint64 start = gKernelArgs.arch_args.virtual_ranges_to_keep[i].start; + uint64 size = gKernelArgs.arch_args.virtual_ranges_to_keep[i].size; + TRACE((" 0x%08" B_PRIx32 "-0x%08" B_PRIx64 ", length 0x%08" B_PRIx64 "\n", + start, start + size, size)); + } } diff --git a/src/system/kernel/arch/arm64/arch_vm.cpp b/src/system/kernel/arch/arm64/arch_vm.cpp index d55c76c0ad..51218db3dd 100644 --- a/src/system/kernel/arch/arm64/arch_vm.cpp +++ b/src/system/kernel/arch/arm64/arch_vm.cpp @@ -9,6 +9,7 @@ #include #include +#include #include @@ -47,7 +48,39 @@ arch_vm_init_post_area(kernel_args* args) status_t arch_vm_init_end(kernel_args* args) { - TRACE("arch_vm_init_end\n"); + TRACE("arch_vm_init_end(): %" B_PRIu32 " virtual ranges to keep:\n", + args->arch_args.num_virtual_ranges_to_keep); + + for (int i = 0; i < (int)args->arch_args.num_virtual_ranges_to_keep; i++) { + addr_range &range = args->arch_args.virtual_ranges_to_keep[i]; + + TRACE(" start: %p, size: %#" B_PRIxSIZE "\n", (void*)range.start, range.size); + + // skip ranges outside the kernel address space + if (!IS_KERNEL_ADDRESS(range.start)) { + TRACE(" no kernel address, skipping...\n"); + continue; + } + + phys_addr_t physicalAddress; + void *address = (void*)range.start; + if (vm_get_page_mapping(VMAddressSpace::KernelID(), range.start, + &physicalAddress) != B_OK) + panic("arch_vm_init_end(): No page mapping for %p\n", address); + + area_id area = vm_map_physical_memory(VMAddressSpace::KernelID(), + "boot loader reserved area", &address, + B_EXACT_ADDRESS, range.size, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, + physicalAddress, true); + + if (area < 0) { + panic("arch_vm_init_end(): Failed to create area for boot loader " + "reserved area: %p - %p\n", (void*)range.start, + (void*)(range.start + range.size)); + } + } + return B_OK; }