pmm: Use our custom EFI memory entry type to release EFI memory back instead of relying on our memmap
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index 921db84d..4fc5b36f 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -344,20 +344,50 @@ void pmm_reclaim_uefi_mem(void) {
void pmm_release_uefi_mem(void) {
EFI_STATUS status;
- for (size_t i = 0; i < memmap_entries; i++) {
- if (memmap[i].type != MEMMAP_USABLE
- && memmap[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE) {
- continue;
- }
+ EFI_MEMORY_DESCRIPTOR tmp_mmap[1];
+ efi_mmap_size = sizeof(tmp_mmap);
+ UINTN mmap_key = 0;
- status = uefi_call_wrapper(gBS->FreePages, 2,
- memmap[i].base, memmap[i].length / 4096);
+ uefi_call_wrapper(gBS->GetMemoryMap, 5,
+ &efi_mmap_size, tmp_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
- if (status)
- panic("pmm: FreePages failure (%x)", status);
+ efi_mmap_size += 4096;
+
+ status = uefi_call_wrapper(gBS->FreePool, 1, efi_mmap);
+ if (status)
+ goto fail;
+
+ status = uefi_call_wrapper(gBS->AllocatePool, 3,
+ EfiLoaderData, efi_mmap_size, &efi_mmap);
+ if (status)
+ goto fail;
+
+ status = uefi_call_wrapper(gBS->GetMemoryMap, 5,
+ &efi_mmap_size, efi_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
+ if (status)
+ goto fail;
+
+ // Go through new EFI memmap and free up bootloader held entries
+ size_t entry_count = efi_mmap_size / efi_desc_size;
+
+ for (size_t i = 0; i < entry_count; i++) {
+ EFI_MEMORY_DESCRIPTOR *entry = (void *)efi_mmap + i * efi_desc_size;
+
+ if (entry->Type == 0x80000000) {
+ status = uefi_call_wrapper(gBS->FreePages, 2,
+ entry->PhysicalStart, entry->NumberOfPages);
+
+ if (status)
+ panic("pmm: FreePages failure (%x)", status);
+ }
}
allocations_disallowed = true;
+
+ return;
+
+fail:
+ panic("pmm: Failed to release UEFI memory");
}
#endif
diff --git a/stage23/protos/chainload.c b/stage23/protos/chainload.c
index 6ca5cfe7..eae87b3e 100644
--- a/stage23/protos/chainload.c
+++ b/stage23/protos/chainload.c
@@ -9,6 +9,7 @@
#include <lib/fb.h>
#include <lib/uri.h>
#include <lib/print.h>
+#include <lib/libc.h>
#include <sys/idt.h>
#include <drivers/vga_textmode.h>
#include <mm/pmm.h>
@@ -119,8 +120,14 @@ void chainload(char *config) {
if (!uri_open(image, image_path))
panic("chainload: Failed to open image with path `%s`. Is the path correct?", image_path);
- void *ptr = freadall(image, MEMMAP_RESERVED);
+ void *_ptr = freadall(image, MEMMAP_RESERVED);
size_t image_size = image->size;
+ void *ptr;
+ status = uefi_call_wrapper(gBS->AllocatePool, 3,
+ EfiLoaderData, image_size, &ptr);
+ if (status)
+ panic("chainload: Allocation failure");
+ memcpy(ptr, _ptr, image_size);
term_deinit();
