:: commit 302d57e47da3032d91f0bf2051123adac26a00e9

mintsuki <mintsuki@protonmail.com> — 2023-12-06 23:08

parents: 40313b25ec

limine: Add EFI memory map feature

diff --git a/PROTOCOL.md b/PROTOCOL.md
index 3e4b5faa..84b30be4 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -1347,6 +1347,41 @@ struct limine_efi_system_table_response {
 
 * `address` - Address of EFI system table.
 
+### EFI Memory Map Feature
+
+ID:
+```c
+#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
+```
+
+Request:
+```c
+struct limine_efi_memmap_request {
+    uint64_t id[4];
+    uint64_t revision;
+    struct limine_efi_memmap_response *response;
+};
+```
+
+Response:
+```c
+struct limine_efi_memmap_response {
+    uint64_t revision;
+    void *memmap;
+    uint64_t memmap_size;
+    uint64_t desc_size;
+    uint64_t desc_version;
+};
+```
+
+* `memmap` - Address (HHDM) of the EFI memory map.
+* `memmap_size` - Size in bytes of the EFI memory map.
+* `desc_size` - EFI memory map descriptor size in bytes.
+* `desc_version` - Version of EFI memory map descriptors.
+
+Note: This feature provides data suitable for use with RT->SetVirtualAddressMap(), provided
+HHDM offset is subtracted from `memmap`.
+
 ### Boot Time Feature
 
 ID:
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 14217658..37068804 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -973,6 +973,24 @@ FEAT_END
     efi_exit_boot_services();
 #endif
 
+    // EFI memory map
+FEAT_START
+    struct limine_efi_memmap_request *efi_memmap_request = get_request(LIMINE_EFI_MEMMAP_REQUEST);
+    if (efi_memmap_request == NULL) {
+        break; // next feature
+    }
+
+    struct limine_efi_memmap_response *efi_memmap_response =
+        ext_mem_alloc(sizeof(struct limine_efi_memmap_response));
+
+    efi_memmap_response->memmap = reported_addr(efi_mmap);
+    efi_memmap_response->memmap_size = efi_mmap_size;
+    efi_memmap_response->desc_size = efi_desc_size;
+    efi_memmap_response->desc_version = efi_desc_ver;
+
+    efi_memmap_request->response = reported_addr(efi_memmap_response);
+FEAT_END
+
     // SMP
 FEAT_START
     struct limine_smp_request *smp_request = get_request(LIMINE_SMP_REQUEST);
diff --git a/limine.h b/limine.h
index 9df02b0d..b7baa79a 100644
--- a/limine.h
+++ b/limine.h
@@ -507,6 +507,24 @@ struct limine_efi_system_table_request {
     LIMINE_PTR(struct limine_efi_system_table_response *) response;
 };
 
+/* EFI memory map */
+
+#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
+
+struct limine_efi_memmap_response {
+    uint64_t revision;
+    LIMINE_PTR(void *) memmap;
+    uint64_t memmap_size;
+    uint64_t desc_size;
+    uint64_t desc_version;
+};
+
+struct limine_efi_memmap_request {
+    uint64_t id[4];
+    uint64_t revision;
+    LIMINE_PTR(struct limine_efi_memmap_response *) response;
+};
+
 /* Boot time */
 
 #define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
diff --git a/test/limine.c b/test/limine.c
index c8ed75ec..910d3b3c 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -86,6 +86,11 @@ struct limine_efi_system_table_request est_request = {
     .revision = 0, .response = NULL
 };
 
+struct limine_efi_memmap_request efi_memmap_request = {
+    .id = LIMINE_EFI_MEMMAP_REQUEST,
+    .revision = 0, .response = NULL
+};
+
 struct limine_boot_time_request boot_time_request = {
     .id = LIMINE_BOOT_TIME_REQUEST,
     .revision = 0, .response = NULL
@@ -364,6 +369,20 @@ FEAT_START
     e9_printf("EFI system table at: %x", est_response->address);
 FEAT_END
 
+FEAT_START
+    e9_printf("");
+    if (efi_memmap_request.response == NULL) {
+        e9_printf("EFI memory map not passed");
+        break;
+    }
+    struct limine_efi_memmap_response *efi_memmap_response = efi_memmap_request.response;
+    e9_printf("EFI memory map feature, revision %d", efi_memmap_response->revision);
+    e9_printf("EFI memory map at: %x", efi_memmap_response->memmap);
+    e9_printf("EFI memory map size: %x", efi_memmap_response->memmap_size);
+    e9_printf("EFI memory descriptor size: %x", efi_memmap_response->desc_size);
+    e9_printf("EFI memory descriptor version: %d", efi_memmap_response->desc_version);
+FEAT_END
+
 FEAT_START
     e9_printf("");
     if (boot_time_request.response == NULL) {
tab: 248 wrap: offon