diff --git a/common/lib/blib.c b/common/lib/blib.c index d8e8b9d4..245644fa 100644 --- a/common/lib/blib.c +++ b/common/lib/blib.c @@ -213,102 +213,6 @@ retry: asm volatile ("cli" ::: "memory"); - // Go through new EFI memmap and free up bootloader entries - size_t entry_count = efi_mmap_size / efi_desc_size; - - EFI_MEMORY_DESCRIPTOR *efi_copy = ext_mem_alloc(EFI_COPY_MAX_ENTRIES * efi_desc_size); - size_t efi_copy_i = 0; - - for (size_t i = 0; i < entry_count; i++) { - EFI_MEMORY_DESCRIPTOR *orig_entry = (void *)efi_mmap + i * efi_desc_size; - EFI_MEMORY_DESCRIPTOR *new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size; - - memcpy(new_entry, orig_entry, efi_desc_size); - - uint64_t base = orig_entry->PhysicalStart; - uint64_t length = orig_entry->NumberOfPages * 4096; - uint64_t top = base + length; - - // Find for a match in the untouched memory map - for (size_t j = 0; j < untouched_memmap_entries; j++) { - if (untouched_memmap[j].type != MEMMAP_USABLE) - continue; - - if (top > untouched_memmap[j].base && top <= untouched_memmap[j].base + untouched_memmap[j].length) { - if (untouched_memmap[j].base < base) { - new_entry->NumberOfPages = (base - untouched_memmap[j].base) / 4096; - - efi_copy_i++; - if (efi_copy_i == EFI_COPY_MAX_ENTRIES) { - panic(false, "efi: New memory map exhausted"); - } - new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size; - memcpy(new_entry, orig_entry, efi_desc_size); - - new_entry->NumberOfPages -= (base - untouched_memmap[j].base) / 4096; - new_entry->PhysicalStart = base; - new_entry->VirtualStart = new_entry->PhysicalStart; - - length = new_entry->NumberOfPages * 4096; - top = base + length; - } - - if (untouched_memmap[j].base > base) { - new_entry->NumberOfPages = (untouched_memmap[j].base - base) / 4096; - - efi_copy_i++; - if (efi_copy_i == EFI_COPY_MAX_ENTRIES) { - panic(false, "efi: New memory map exhausted"); - } - new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size; - memcpy(new_entry, orig_entry, efi_desc_size); - - new_entry->NumberOfPages -= (untouched_memmap[j].base - base) / 4096; - new_entry->PhysicalStart = untouched_memmap[j].base; - new_entry->VirtualStart = new_entry->PhysicalStart; - - base = new_entry->PhysicalStart; - length = new_entry->NumberOfPages * 4096; - top = base + length; - } - - if (length < untouched_memmap[j].length) { - panic(false, "efi: Memory map corruption"); - } - - new_entry->Type = EfiConventionalMemory; - - if (length == untouched_memmap[j].length) { - // It's a perfect match! - break; - } - - new_entry->NumberOfPages = untouched_memmap[j].length / 4096; - - efi_copy_i++; - if (efi_copy_i == EFI_COPY_MAX_ENTRIES) { - panic(false, "efi: New memory map exhausted"); - } - new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size; - memcpy(new_entry, orig_entry, efi_desc_size); - - new_entry->NumberOfPages = (length - untouched_memmap[j].length) / 4096; - new_entry->PhysicalStart = base + untouched_memmap[j].length; - new_entry->VirtualStart = new_entry->PhysicalStart; - - break; - } - } - - efi_copy_i++; - if (efi_copy_i == EFI_COPY_MAX_ENTRIES) { - panic(false, "efi: New memory map exhausted"); - } - } - - efi_mmap = efi_copy; - efi_mmap_size = efi_copy_i * efi_desc_size; - efi_boot_services_exited = true; printv("efi: Exited boot services.\n"); diff --git a/common/mm/pmm.h b/common/mm/pmm.h index 100d6179..f9c7c2f6 100644 --- a/common/mm/pmm.h +++ b/common/mm/pmm.h @@ -32,9 +32,6 @@ extern size_t memmap_entries; #if uefi == 1 extern struct e820_entry_t *memmap; extern size_t memmap_entries; - -extern struct e820_entry_t *untouched_memmap; -extern size_t untouched_memmap_entries; #endif extern bool allocations_disallowed; @@ -55,7 +52,6 @@ void *conv_mem_alloc(size_t count); void pmm_free(void *ptr, size_t length); #if uefi == 1 -void pmm_reclaim_uefi_mem(void); void pmm_release_uefi_mem(void); #endif diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c index 5a93c276..76b2054b 100644 --- a/common/mm/pmm.s2.c +++ b/common/mm/pmm.s2.c @@ -61,8 +61,8 @@ static size_t memmap_max_entries; struct e820_entry_t *memmap; size_t memmap_entries = 0; -struct e820_entry_t *untouched_memmap; -size_t untouched_memmap_entries = 0; +static struct e820_entry_t *untouched_memmap; +static size_t untouched_memmap_entries = 0; #endif static const char *memmap_type(uint32_t type) { @@ -119,8 +119,6 @@ static bool align_entry(uint64_t *base, uint64_t *length) { return true; } -static bool sanitiser_keep_first_page = false; - #define MEMMAP_DROP_LATER ((uint32_t)-1) static void sanitise_entries(struct e820_entry_t *m, size_t *_count, bool align_entries) { @@ -192,7 +190,7 @@ static void sanitise_entries(struct e820_entry_t *m, size_t *_count, bool align_ if (m[i].type != MEMMAP_USABLE) continue; - if (!sanitiser_keep_first_page && m[i].base < 0x1000) { + if (bios && m[i].base < 0x1000) { if (m[i].base + m[i].length <= 0x1000) { goto del_mm1; } @@ -246,6 +244,8 @@ del_mm1: *_count = count; } +static void pmm_reclaim_uefi_mem(struct e820_entry_t *m, size_t *_count); + struct e820_entry_t *get_memmap(size_t *entries) { #if uefi == 1 @@ -294,7 +294,7 @@ struct e820_entry_t *get_memmap(size_t *entries) { ); #endif - pmm_reclaim_uefi_mem(); + pmm_reclaim_uefi_mem(memmap, &memmap_entries); #endif sanitise_entries(memmap, &memmap_entries, true); @@ -469,11 +469,13 @@ fail: panic(false, "pmm: Failure initialising memory map"); } -void pmm_reclaim_uefi_mem(void) { +static void pmm_reclaim_uefi_mem(struct e820_entry_t *m, size_t *_count) { + size_t count = *_count; + // First, ensure the boot services are still boot services, or free, in // the EFI memmap - for (size_t i = 0; i < memmap_entries; i++) { - if (memmap[i].type != MEMMAP_EFI_BOOTSERVICES) + for (size_t i = 0; i < count; i++) { + if (m[i].type != MEMMAP_EFI_BOOTSERVICES) continue; // Go through EFI memmap and ensure this entry fits within a boot services @@ -492,8 +494,8 @@ void pmm_reclaim_uefi_mem(void) { continue; } - uintptr_t base = memmap[i].base; - uintptr_t top = base + memmap[i].length; + uintptr_t base = m[i].base; + uintptr_t top = base + m[i].length; uintptr_t efi_base = entry->PhysicalStart; uintptr_t efi_size = entry->NumberOfPages * 4096; uintptr_t efi_top = efi_base + efi_size; @@ -502,14 +504,14 @@ void pmm_reclaim_uefi_mem(void) { && top > efi_base && top <= efi_top)) continue; - memmap[i].type = MEMMAP_USABLE; + m[i].type = MEMMAP_USABLE; } } size_t recl_i = 0; - for (size_t i = 0; i < memmap_entries; i++) { - if (memmap[i].type == MEMMAP_EFI_RECLAIMABLE) { + for (size_t i = 0; i < count; i++) { + if (m[i].type == MEMMAP_EFI_RECLAIMABLE) { recl_i++; } } @@ -518,9 +520,9 @@ void pmm_reclaim_uefi_mem(void) { { size_t recl_j = 0; - for (size_t i = 0; i < memmap_entries; i++) { - if (memmap[i].type == MEMMAP_EFI_RECLAIMABLE) { - recl[recl_j++] = memmap[i]; + for (size_t i = 0; i < count; i++) { + if (m[i].type == MEMMAP_EFI_RECLAIMABLE) { + recl[recl_j++] = m[i]; } } } @@ -572,7 +574,18 @@ another_recl:; our_type = MEMMAP_RESERVED; break; } + struct e820_entry_t *memmap_save = memmap; + size_t memmap_entries_save = memmap_entries; + + memmap = m; + memmap_entries = count; + memmap_alloc_range(efi_base, efi_size, our_type, false, true, false, true); + + count = memmap_entries; + + memmap = memmap_save; + memmap_entries = memmap_entries_save; } if (--recl_i > 0) { @@ -580,7 +593,9 @@ another_recl:; goto another_recl; } - sanitise_entries(memmap, &memmap_entries, false); + sanitise_entries(m, &count, false); + + *_count = count; } void pmm_release_uefi_mem(void) { @@ -612,49 +627,9 @@ struct e820_entry_t *get_raw_memmap(size_t *entry_count) { #if uefi == 1 struct e820_entry_t *get_raw_memmap(size_t *entry_count) { - size_t mmap_count = efi_mmap_size / efi_desc_size; - size_t mmap_len = mmap_count * sizeof(struct e820_entry_t); - - struct e820_entry_t *mmap = ext_mem_alloc(mmap_len); - - for (size_t i = 0; i < mmap_count; i++) { - EFI_MEMORY_DESCRIPTOR *entry = (void *)efi_mmap + i * efi_desc_size; - - uint32_t our_type; - switch (entry->Type) { - case EfiReservedMemoryType: - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - case EfiUnusableMemory: - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: - case EfiPalCode: - case EfiLoaderCode: - case EfiLoaderData: - default: - our_type = MEMMAP_RESERVED; break; - case EfiACPIReclaimMemory: - our_type = MEMMAP_ACPI_RECLAIMABLE; break; - case EfiACPIMemoryNVS: - our_type = MEMMAP_ACPI_NVS; break; - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - our_type = MEMMAP_USABLE; break; - } - - mmap[i].base = entry->PhysicalStart; - mmap[i].length = entry->NumberOfPages * 4096; - mmap[i].type = our_type; - } - - bool s_old = sanitiser_keep_first_page; - sanitiser_keep_first_page = true; - sanitise_entries(mmap, &mmap_count, false); - sanitiser_keep_first_page = s_old; - - *entry_count = mmap_count; - return mmap; + pmm_reclaim_uefi_mem(untouched_memmap, &untouched_memmap_entries); + *entry_count = untouched_memmap_entries; + return untouched_memmap; } #endif