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
This commit is contained in:
Regular → Executable
+37
-17
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boot/addr_range.h>
|
||||||
#include <boot/platform.h>
|
#include <boot/platform.h>
|
||||||
#include <boot/stage2.h>
|
#include <boot/stage2.h>
|
||||||
#include <kernel/arch/x86/arch_kernel.h>
|
#include <kernel/arch/x86/arch_kernel.h>
|
||||||
@@ -276,25 +277,9 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags)
|
|||||||
physicalAddress -= pageOffset;
|
physicalAddress -= pageOffset;
|
||||||
size += pageOffset;
|
size += pageOffset;
|
||||||
|
|
||||||
size_t aligned_size = ROUNDUP(size, B_PAGE_SIZE);
|
if (insert_physical_allocated_range(physicalAddress, ROUNDUP(size, B_PAGE_SIZE)) != B_OK)
|
||||||
allocated_memory_region *region = new(std::nothrow) allocated_memory_region;
|
|
||||||
|
|
||||||
if (!region)
|
|
||||||
return B_NO_MEMORY;
|
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;
|
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
|
extern "C" status_t
|
||||||
platform_bootloader_address_to_kernel_address(void *address, uint64_t *_result)
|
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;
|
uint64_t addr = (uint64_t)address;
|
||||||
|
|
||||||
for (allocated_memory_region *region = allocated_memory_regions; region; region = region->next) {
|
for (allocated_memory_region *region = allocated_memory_regions; region; region = region->next) {
|
||||||
|
|||||||
Reference in New Issue
Block a user