From b2d0b3699e5f3ec43396c8faf937247b1912e5fd Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Mon, 11 Jun 2018 15:09:28 +1200 Subject: [PATCH] efi: redo mmu_map_physical_address to not require allocations. * mmu_map_physical_address will get called prior to calling main() which leaves us without a heap, malloc, and new. Instead, use the kernel args physical allocated range array, and then convert to our allocated memory region type on-demand. Change-Id: I265fd165ef7143681e8e40c3686fda1a583c20dc --- src/system/boot/platform/efi/mmu.cpp | 54 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 17 deletions(-) mode change 100644 => 100755 src/system/boot/platform/efi/mmu.cpp diff --git a/src/system/boot/platform/efi/mmu.cpp b/src/system/boot/platform/efi/mmu.cpp old mode 100644 new mode 100755 index d3057c3dee..9cb7b64cae --- a/src/system/boot/platform/efi/mmu.cpp +++ b/src/system/boot/platform/efi/mmu.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -276,25 +277,9 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags) physicalAddress -= pageOffset; size += pageOffset; - size_t aligned_size = ROUNDUP(size, B_PAGE_SIZE); - allocated_memory_region *region = new(std::nothrow) allocated_memory_region; - - if (!region) + if (insert_physical_allocated_range(physicalAddress, ROUNDUP(size, B_PAGE_SIZE)) != B_OK) return B_NO_MEMORY; - // Addresses above 512GB not supported. - // Memory map regions above 512GB can be ignored, but if EFI returns pages above - // that there's nothing that can be done to fix it. - if (physicalAddress + size > (512ull * 1024 * 1024 * 1024)) - panic("Can't currently support more than 512GB of RAM!"); - - region->next = allocated_memory_regions; - allocated_memory_regions = region; - region->vaddr = 0; - region->paddr = physicalAddress; - region->size = aligned_size; - region->released = false; - return physicalAddress + pageOffset; } @@ -331,9 +316,44 @@ get_region(void *address, size_t size) } +static void +convert_physical_ranges() { + addr_range *range = gKernelArgs.physical_allocated_range; + uint32 num_ranges = gKernelArgs.num_physical_allocated_ranges; + + for (uint32 i = 0; i < num_ranges; ++i) { + allocated_memory_region *region = new(std::nothrow) allocated_memory_region; + + if (!region) + panic("Couldn't add allocated region"); + + // Addresses above 512GB not supported. + // Memory map regions above 512GB can be ignored, but if EFI returns pages above + // that there's nothing that can be done to fix it. + if (range[i].start + range[i].size > (512ull * 1024 * 1024 * 1024)) + panic("Can't currently support more than 512GB of RAM!"); + + region->next = allocated_memory_regions; + allocated_memory_regions = region; + region->vaddr = 0; + region->paddr = range[i].start; + region->size = range[i].size; + region->released = false; + + // Clear out the allocated range + range[i].start = 0; + range[i].size = 0; + gKernelArgs.num_physical_allocated_ranges--; + } +} + + extern "C" status_t platform_bootloader_address_to_kernel_address(void *address, uint64_t *_result) { + // Convert any physical ranges prior to looking up address + convert_physical_ranges(); + uint64_t addr = (uint64_t)address; for (allocated_memory_region *region = allocated_memory_regions; region; region = region->next) {