:: commit dafc710c606f334fc9aeccba6abfdce5e15c5346

mintsuki <mintsuki@protonmail.com> — 2021-09-03 01:10

parents: 0410e53e3d

pmm: Allocate memory map dynamically using EFI

diff --git a/stage23/lib/blib.c b/stage23/lib/blib.c
index f12ac2d1..5f19ec64 100644
--- a/stage23/lib/blib.c
+++ b/stage23/lib/blib.c
@@ -146,6 +146,8 @@ uint32_t get_crc32(void *_stream, size_t len) {
 
 bool efi_boot_services_exited = false;
 
+#define EFI_COPY_MAX_ENTRIES 512
+
 bool efi_exit_boot_services(void) {
     EFI_STATUS status;
 
@@ -182,7 +184,7 @@ bool efi_exit_boot_services(void) {
     // 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(MEMMAP_MAX_ENTRIES * 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++) {
@@ -205,7 +207,7 @@ bool efi_exit_boot_services(void) {
                     new_entry->NumberOfPages = (untouched_memmap[j].base - base) / 4096;
 
                     efi_copy_i++;
-                    if (efi_copy_i == MEMMAP_MAX_ENTRIES) {
+                    if (efi_copy_i == EFI_COPY_MAX_ENTRIES) {
                         panic("efi: New memory map exhausted");
                     }
                     new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size;
@@ -234,7 +236,7 @@ bool efi_exit_boot_services(void) {
                 new_entry->NumberOfPages = untouched_memmap[j].length / 4096;
 
                 efi_copy_i++;
-                if (efi_copy_i == MEMMAP_MAX_ENTRIES) {
+                if (efi_copy_i == EFI_COPY_MAX_ENTRIES) {
                     panic("efi: New memory map exhausted");
                 }
                 new_entry = (void *)efi_copy + efi_copy_i * efi_desc_size;
@@ -249,7 +251,7 @@ bool efi_exit_boot_services(void) {
         }
 
         efi_copy_i++;
-        if (efi_copy_i == MEMMAP_MAX_ENTRIES) {
+        if (efi_copy_i == EFI_COPY_MAX_ENTRIES) {
             panic("efi: New memory map exhausted");
         }
     }
diff --git a/stage23/mm/pmm.h b/stage23/mm/pmm.h
index a63850cf..5c789c13 100644
--- a/stage23/mm/pmm.h
+++ b/stage23/mm/pmm.h
@@ -6,8 +6,6 @@
 #include <stdbool.h>
 #include <sys/e820.h>
 
-#define MEMMAP_MAX_ENTRIES 1024
-
 #define MEMMAP_USABLE                 1
 #define MEMMAP_RESERVED               2
 #define MEMMAP_ACPI_RECLAIMABLE       3
@@ -19,11 +17,16 @@
 #define MEMMAP_EFI_RECLAIMABLE        0x2000
 #define MEMMAP_EFI_BOOTSERVICES       0x2001
 
+#if bios == 1
 extern struct e820_entry_t memmap[];
 extern size_t memmap_entries;
+#endif
 
 #if uefi == 1
-extern struct e820_entry_t untouched_memmap[];
+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
 
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index 0024f72c..063e4e16 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -47,11 +47,20 @@ void *conv_mem_alloc(size_t count) {
     }
 }
 
-struct e820_entry_t memmap[MEMMAP_MAX_ENTRIES];
+#if bios == 1
+#define memmap_max_entries ((size_t)512)
+
+struct e820_entry_t memmap[memmap_max_entries];
 size_t memmap_entries = 0;
+#endif
 
 #if uefi == 1
-struct e820_entry_t untouched_memmap[MEMMAP_MAX_ENTRIES];
+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;
 #endif
 
@@ -208,7 +217,7 @@ struct e820_entry_t *get_memmap(size_t *entries) {
 #if bios == 1
 void init_memmap(void) {
     for (size_t i = 0; i < e820_entries; i++) {
-        if (memmap_entries == MEMMAP_MAX_ENTRIES) {
+        if (memmap_entries == memmap_max_entries) {
             panic("Memory map exhausted.");
         }
 
@@ -260,13 +269,31 @@ void init_memmap(void) {
     efi_mmap_size = sizeof(tmp_mmap);
     UINTN mmap_key = 0;
 
-    status = gBS->GetMemoryMap(&efi_mmap_size, tmp_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
+    gBS->GetMemoryMap(&efi_mmap_size, tmp_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
+
+    memmap_max_entries = (efi_mmap_size / efi_desc_size) + 512;
 
     efi_mmap_size += 4096;
 
     status = gBS->AllocatePool(EfiLoaderData, efi_mmap_size, (void **)&efi_mmap);
+    if (status) {
+        goto fail;
+    }
+
+    status = gBS->AllocatePool(EfiLoaderData, memmap_max_entries * sizeof(struct e820_entry_t), (void **)&memmap);
+    if (status) {
+        goto fail;
+    }
+
+    status = gBS->AllocatePool(EfiLoaderData, memmap_max_entries * sizeof(struct e820_entry_t), (void **)&untouched_memmap);
+    if (status) {
+        goto fail;
+    }
 
     status = gBS->GetMemoryMap(&efi_mmap_size, efi_mmap, &mmap_key, &efi_desc_size, &efi_desc_ver);
+    if (status) {
+        goto fail;
+    }
 
     size_t entry_count = efi_mmap_size / efi_desc_size;
 
@@ -338,6 +365,10 @@ void init_memmap(void) {
         if (status)
             panic("pmm: AllocatePages failure (%x)", status);
     }
+
+    return;
+fail:
+    panic("pmm: Failure initialising memory map");
 }
 
 void pmm_reclaim_uefi_mem(void) {
@@ -596,7 +627,7 @@ bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free
             if (memmap[i].length == 0) {
                 target = &memmap[i];
             } else {
-                if (memmap_entries >= MEMMAP_MAX_ENTRIES)
+                if (memmap_entries >= memmap_max_entries)
                     panic("Memory map exhausted.");
 
                 target = &memmap[memmap_entries++];
@@ -607,7 +638,7 @@ bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free
             target->length = length;
 
             if (top < entry_top) {
-                if (memmap_entries >= MEMMAP_MAX_ENTRIES)
+                if (memmap_entries >= memmap_max_entries)
                     panic("Memory map exhausted.");
 
                 target = &memmap[memmap_entries++];
@@ -627,7 +658,7 @@ bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free
         panic("Memory allocation failure.");
 
     if (new_entry) {
-        if (memmap_entries >= MEMMAP_MAX_ENTRIES)
+        if (memmap_entries >= memmap_max_entries)
             panic("Memory map exhausted.");
 
         struct e820_entry_t *target = &memmap[memmap_entries++];
diff --git a/stage23/sys/e820.s2.c b/stage23/sys/e820.s2.c
index 5e1dcc15..03339457 100644
--- a/stage23/sys/e820.s2.c
+++ b/stage23/sys/e820.s2.c
@@ -8,7 +8,7 @@
 #include <lib/print.h>
 #include <mm/pmm.h>
 
-#define MAX_E820_ENTRIES 512
+#define MAX_E820_ENTRIES 256
 
 struct e820_entry_t e820_map[MAX_E820_ENTRIES];
 size_t e820_entries = 0;
tab: 248 wrap: offon