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 (;;);
