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