:: commit e33a76bd995d35e5d6f1f47756e1129040b2eb0d

mintsuki <mintsuki@protonmail.com> — 2022-03-12 20:41

parents: b2e614e7c2

limine: Add memmap feature

diff --git a/common/limine.h b/common/limine.h
index 689d6359..d727094c 100644
--- a/common/limine.h
+++ b/common/limine.h
@@ -4,39 +4,35 @@
 #include <stdint.h>
 
 #ifdef LIMINE_NO_POINTERS
-#  define LIMINE_CHARPTR uint64_t
-#  define LIMINE_VOIDPTR uint64_t
-#  define LIMINE_VOIDPTRPTR uint64_t
+#  define LIMINE_PTR(TYPE) uint64_t
 #else
-#  define LIMINE_CHARPTR char *
-#  define LIMINE_VOIDPTR void *
-#  define LIMINE_VOIDPTRPTR void **
+#  define LIMINE_PTR(TYPE) TYPE
 #endif
 
 #define LIMINE_MAGIC { 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b }
 
 struct limine_header {
     uint64_t magic[2];
-    LIMINE_VOIDPTR entry;
+    LIMINE_PTR(void *) entry;
     uint64_t features_count;
-    LIMINE_VOIDPTRPTR features;
+    LIMINE_PTR(void *) features;
 };
 
 // Boot info
 
-#define LIMINE_BOOT_INFO_REQUEST ((LIMINE_VOIDPTR) 1 )
+#define LIMINE_BOOT_INFO_REQUEST ((LIMINE_PTR(void *)) 1 )
 
 struct limine_boot_info_response {
     uint64_t flags;
-    LIMINE_CHARPTR loader;
+    LIMINE_PTR(char *) loader;
 };
 
 // Framebuffer
 
-#define LIMINE_FRAMEBUFFER_REQUEST ((LIMINE_VOIDPTR) 2 )
+#define LIMINE_FRAMEBUFFER_REQUEST ((LIMINE_PTR(void *)) 2 )
 
 struct limine_framebuffer_request {
-    LIMINE_VOIDPTR id;
+    LIMINE_PTR(void *) id;
 
 #define LIMINE_FRAMEBUFFER_PREFER_LFB 0
 #define LIMINE_FRAMEBUFFER_PREFER_TEXT 1
@@ -52,7 +48,7 @@ struct limine_framebuffer_request {
 
 // 5-level paging
 
-#define LIMINE_5_LEVEL_PAGING_REQUEST ((LIMINE_VOIDPTR) 3 )
+#define LIMINE_5_LEVEL_PAGING_REQUEST ((LIMINE_PTR(void *)) 3 )
 
 struct limine_5_level_paging_response {
     uint64_t flags;
@@ -60,6 +56,32 @@ struct limine_5_level_paging_response {
 
 // PMRs
 
-#define LIMINE_PMR_REQUEST ((LIMINE_VOIDPTR) 4 )
+#define LIMINE_PMR_REQUEST ((LIMINE_PTR(void *)) 4 )
+
+// Memory map
+
+#define LIMINE_MEMMAP_REQUEST ((LIMINE_PTR(void *)) 5 )
+
+#define LIMINE_MEMMAP_USABLE                 0
+#define LIMINE_MEMMAP_RESERVED               1
+#define LIMINE_MEMMAP_ACPI_RECLAIMABLE       2
+#define LIMINE_MEMMAP_ACPI_NVS               3
+#define LIMINE_MEMMAP_BAD_MEMORY             4
+#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
+#define LIMINE_MEMMAP_KERNEL_AND_MODULES     6
+#define LIMINE_MEMMAP_FRAMEBUFFER            7
+
+struct limine_memmap_entry {
+    uint64_t base;
+    uint64_t length;
+    uint64_t type;
+};
+
+struct limine_memmap_response {
+    uint64_t flags;
+
+    uint64_t entries_count;
+    LIMINE_PTR(struct limine_memmap_entry *) entries;
+};
 
 #endif
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 7bdc2102..99667318 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -234,9 +234,54 @@ FEAT_END
 
     // Memmap
 FEAT_START
+    struct feature memmap_feat = get_feature(LIMINE_MEMMAP_REQUEST);
+    struct limine_memmap_response *memmap_response;
+
+    if (memmap_feat.found == true) {
+        memmap_response = ext_mem_alloc(sizeof(struct limine_memmap_response));
+    }
+
     size_t mmap_entries;
     struct e820_entry_t *mmap = get_memmap(&mmap_entries);
-    (void)mmap;
+
+    if (memmap_feat.found == false) {
+        break; // next feature
+    }
+
+    for (size_t i = 0; i < mmap_entries; i++) {
+        switch (mmap[i].type) {
+            case MEMMAP_USABLE:
+                mmap[i].type = LIMINE_MEMMAP_USABLE;
+                break;
+            case MEMMAP_ACPI_RECLAIMABLE:
+                mmap[i].type = LIMINE_MEMMAP_ACPI_RECLAIMABLE;
+                break;
+            case MEMMAP_ACPI_NVS:
+                mmap[i].type = LIMINE_MEMMAP_ACPI_NVS;
+                break;
+            case MEMMAP_BAD_MEMORY:
+                mmap[i].type = LIMINE_MEMMAP_BAD_MEMORY;
+                break;
+            case MEMMAP_BOOTLOADER_RECLAIMABLE:
+                mmap[i].type = LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE;
+                break;
+            case MEMMAP_KERNEL_AND_MODULES:
+                mmap[i].type = LIMINE_MEMMAP_KERNEL_AND_MODULES;
+                break;
+            case MEMMAP_FRAMEBUFFER:
+                mmap[i].type = LIMINE_MEMMAP_FRAMEBUFFER;
+                break;
+            default:
+            case MEMMAP_RESERVED:
+                mmap[i].type = LIMINE_MEMMAP_RESERVED;
+                break;
+        }
+    }
+
+    memmap_response->entries_count = mmap_entries;
+    memmap_response->entries = reported_addr(mmap);
+
+    features_orig[memmap_feat.index] = reported_addr(memmap_response);
 FEAT_END
 
     // Final wrap-up
diff --git a/common/sys/e820.h b/common/sys/e820.h
index ae0fb9e9..38c9071f 100644
--- a/common/sys/e820.h
+++ b/common/sys/e820.h
@@ -9,7 +9,7 @@ struct e820_entry_t {
     uint64_t length;
     uint32_t type;
     uint32_t unused;
-} __attribute__((packed));
+};
 
 extern struct e820_entry_t e820_map[];
 extern size_t e820_entries;
diff --git a/test/limine.c b/test/limine.c
index 357fbc2d..1cb37b88 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -14,6 +14,7 @@ static struct limine_framebuffer_request framebuffer_request = {
 static void *features_array[] = {
     LIMINE_BOOT_INFO_REQUEST,
     &framebuffer_request,
+    LIMINE_MEMMAP_REQUEST,
     LIMINE_5_LEVEL_PAGING_REQUEST,
     LIMINE_PMR_REQUEST
 };
@@ -28,6 +29,29 @@ static struct limine_header limine_header = {
     .features = features_array
 };
 
+static char *get_memmap_type(uint64_t type) {
+    switch (type) {
+        case LIMINE_MEMMAP_USABLE:
+            return "Usable";
+        case LIMINE_MEMMAP_RESERVED:
+            return "Reserved";
+        case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
+            return "ACPI reclaimable";
+        case LIMINE_MEMMAP_ACPI_NVS:
+            return "ACPI NVS";
+        case LIMINE_MEMMAP_BAD_MEMORY:
+            return "Bad memory";
+        case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
+            return "Bootloader reclaimable";
+        case LIMINE_MEMMAP_KERNEL_AND_MODULES:
+            return "Kernel and modules";
+        case LIMINE_MEMMAP_FRAMEBUFFER:
+            return "Framebuffer";
+        default:
+            return "???";
+    }
+}
+
 #define FEAT_START do {
 #define FEAT_END } while (0);
 
@@ -36,12 +60,25 @@ static void limine_main(void) {
 
 FEAT_START
     if (features_array[0] == NULL) {
+        e9_printf("Boot info not passed");
         break;
     }
     struct limine_boot_info_response *boot_info_response = features_array[0];
     e9_printf("Boot info response:");
     e9_printf("Bootloader name: %s", boot_info_response->loader);
+FEAT_END
 
+FEAT_START
+    if (features_array[2] == NULL) {
+        e9_printf("Memory map not passed");
+        break;
+    }
+    struct limine_memmap_response *memmap_response = features_array[2];
+    e9_printf("%d memory map entries", memmap_response->entries_count);
+    for (size_t i = 0; i < memmap_response->entries_count; i++) {
+        struct limine_memmap_entry *e = &memmap_response->entries[i];
+        e9_printf("%x->%x %s", e->base, e->base + e->length, get_memmap_type(e->type));
+    }
 FEAT_END
 
     for (;;);
tab: 248 wrap: offon