protos/limine: Initial implementation of base revision 4

This commit is contained in:
Mintsuki 2025-10-25 02:31:49 +02:00
parent cf739c2441
commit 80c82d9772
No known key found for this signature in database
GPG Key ID: 1F3C021BECA23821
9 changed files with 134 additions and 11 deletions

View File

@ -85,7 +85,7 @@ if ! test -f version; then
clone_repo_commit \
https://codeberg.org/Limine/limine-protocol.git \
limine-protocol \
fedf97facd1c473ee8720f8dfd5a71d03490d928
cc957208629a1ee427a826915f323508fd52ee91
clone_repo_commit \
https://codeberg.org/PicoEFI/PicoEFI.git \

View File

@ -46,7 +46,7 @@ override CPPFLAGS_FOR_TARGET := \
$(CPPFLAGS_FOR_TARGET) \
-DCOM_OUTPUT=$(COM_OUTPUT) \
-DE9_OUTPUT=$(E9_OUTPUT) \
-DLIMINE_API_REVISION=3 \
-DLIMINE_API_REVISION=4 \
-DFLANTERM_IN_FLANTERM \
-MMD \
-MP

View File

@ -5,6 +5,7 @@
#include <lib/misc.h>
#include <lib/libc.h>
#include <lib/print.h>
#include <mm/pmm.h>
// Following function based on https://github.com/managarm/lai/blob/master/helpers/pc-bios.c's function lai_bios_calc_checksum()
uint8_t acpi_checksum(void *ptr, size_t size) {
@ -238,3 +239,95 @@ void *acpi_get_table(const char *signature, int index) {
printv("acpi: \"%s\" not found\n", signature);
return NULL;
}
void map_single_table(uint64_t addr, uint32_t len) {
#if defined (__i386__)
if (addr >= 0x100000000) {
print("acpi: warning: Cannot get length of ACPI table above 4GiB\n");
return;
}
#endif
uint32_t length = len != (uint32_t)-1 ? len : *(uint32_t *)(uintptr_t)(addr + 4);
uint64_t memmap_type = pmm_check_type(addr);
if (memmap_type != MEMMAP_ACPI_RECLAIMABLE && memmap_type != MEMMAP_ACPI_NVS) {
memmap_alloc_range(addr, length, MEMMAP_ACPI_TABLES, 0, true, false, true);
}
}
void acpi_map_tables(void) {
struct rsdp *rsdp = acpi_get_rsdp();
if (rsdp == NULL)
return;
uint64_t rsdp_length;
if (rsdp->rev < 2) {
rsdp_length = 20;
} else {
rsdp_length = rsdp->length;
}
map_single_table((uintptr_t)rsdp, rsdp_length);
if (!(rsdp->rev >= 2 && rsdp->xsdt_addr)) {
goto no_xsdt;
}
struct rsdt *xsdt = (void *)(uintptr_t)rsdp->xsdt_addr;
size_t xsdt_entry_count = (xsdt->header.length - sizeof(struct sdt)) / 8;
map_single_table((uintptr_t)xsdt, (uint32_t)-1);
for (size_t i = 0; i < xsdt_entry_count; i++) {
struct sdt *sdt = (void *)(uintptr_t)((uint64_t *)xsdt->ptrs_start)[i];
map_single_table((uintptr_t)sdt, (uint32_t)-1);
}
no_xsdt:;
struct rsdt *rsdt = (void *)(uintptr_t)rsdp->rsdt_addr;
size_t rsdt_entry_count = (rsdt->header.length - sizeof(struct sdt)) / 4;
map_single_table((uintptr_t)rsdt, (uint32_t)-1);
for (size_t i = 0; i < rsdt_entry_count; i++) {
struct sdt *sdt = (void *)(uintptr_t)((uint32_t *)rsdt->ptrs_start)[i];
map_single_table((uintptr_t)sdt, (uint32_t)-1);
}
uint8_t *fadt = acpi_get_table("FACP", 0);
if (fadt == NULL) {
return;
}
uint32_t fadt_length = *(uint32_t *)(fadt + 4);
// Read the single fields from the FADT without defining a struct for the whole table
if (fadt_length >= 132 + 8) {
uint64_t x_facs = *(uint64_t *)(fadt + 132);
if (x_facs != 0) {
map_single_table(x_facs, (uint32_t)-1);
}
}
if (fadt_length >= 140 + 8) {
uint64_t x_dsdt = *(uint64_t *)(fadt + 140);
if (x_dsdt != 0) {
map_single_table(x_dsdt, (uint32_t)-1);
}
}
if (fadt_length >= 36 + 4) {
uint32_t facs = *(uint32_t *)(fadt + 36);
if (facs != 0) {
map_single_table(facs, (uint32_t)-1);
}
}
if (fadt_length >= 40 + 4) {
uint32_t dsdt = *(uint32_t *)(fadt + 40);
if (dsdt != 0) {
map_single_table(dsdt, (uint32_t)-1);
}
}
}

View File

@ -182,4 +182,6 @@ void *acpi_get_rsdp_v2(void);
void *acpi_get_table(const char *signature, int index);
void acpi_get_smbios(void **smbios32, void **smbios64);
void acpi_map_tables(void);
#endif

View File

@ -20,6 +20,7 @@ struct memmap_entry {
#define MEMMAP_BOOTLOADER_RECLAIMABLE 0x1000
#define MEMMAP_KERNEL_AND_MODULES 0x1001
#define MEMMAP_FRAMEBUFFER 0x1002
#define MEMMAP_ACPI_TABLES 0x1003
#define MEMMAP_EFI_RECLAIMABLE 0x2000
struct meminfo {
@ -48,6 +49,7 @@ void init_memmap(void);
struct memmap_entry *get_memmap(size_t *entries);
struct memmap_entry *get_raw_memmap(size_t *entry_count);
void print_memmap(struct memmap_entry *mm, size_t size);
uint64_t pmm_check_type(uint64_t addr);
bool memmap_alloc_range_in(struct memmap_entry *m, size_t *_count,
uint64_t base, uint64_t length, uint32_t type, uint32_t overlay_type, bool do_panic, bool simulation, bool new_entry);
bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, uint32_t overlay_type, bool panic, bool simulation, bool new_entry);

View File

@ -69,6 +69,8 @@ static const char *memmap_type(uint32_t type) {
return "Usable RAM";
case MEMMAP_RESERVED:
return "Reserved";
case MEMMAP_ACPI_TABLES:
return "ACPI tables";
case MEMMAP_ACPI_RECLAIMABLE:
return "ACPI reclaimable";
case MEMMAP_ACPI_NVS:
@ -208,9 +210,10 @@ del_mm1:
m[p] = min_e;
}
// Merge contiguous bootloader-reclaimable and usable entries
// Merge contiguous bootloader-reclaimable, ACPI tables, usable entries
for (size_t i = 0; i < count - 1; i++) {
if (m[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE
&& m[i].type != MEMMAP_ACPI_TABLES
&& m[i].type != MEMMAP_USABLE)
continue;
@ -751,6 +754,19 @@ static bool pmm_new_entry(struct memmap_entry *m, size_t *_count,
return true;
}
uint64_t pmm_check_type(uint64_t addr) {
for (size_t i = 0; i < memmap_entries; i++) {
uint64_t entry_base = memmap[i].base;
uint64_t entry_top = memmap[i].base + memmap[i].length;
if (addr >= entry_base && addr < entry_top) {
return memmap[i].type;
}
}
return (uint64_t)-1;
}
bool memmap_alloc_range_in(struct memmap_entry *m, size_t *_count,
uint64_t base, uint64_t length, uint32_t type, uint32_t overlay_type, bool do_panic, bool simulation, bool new_entry) {
size_t count = *_count;

View File

@ -50,7 +50,7 @@ static enum executable_format detect_kernel_format(uint8_t *kernel) {
}
}
#define SUPPORTED_BASE_REVISION 3
#define SUPPORTED_BASE_REVISION 4
#define MAX_REQUESTS 128
@ -61,13 +61,13 @@ static int paging_mode;
static uint64_t get_hhdm_span_top(int base_revision) {
uint64_t ret = base_revision >= 3 ? 0 : 0x100000000;
for (size_t i = 0; i < memmap_entries; i++) {
if (base_revision >= 1 && base_revision < 3 && (
if (((base_revision >= 1 && base_revision < 3) || base_revision >= 4) && (
memmap[i].type == MEMMAP_RESERVED
|| memmap[i].type == MEMMAP_BAD_MEMORY)) {
continue;
}
if (base_revision >= 3 && (
if (base_revision == 3 && (
memmap[i].type != MEMMAP_USABLE
&& memmap[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE
&& memmap[i].type != MEMMAP_KERNEL_AND_MODULES
@ -202,13 +202,13 @@ static pagemap_t build_pagemap(int base_revision,
// Map all free memory regions to the higher half direct map offset
for (size_t i = 0; i < _memmap_entries; i++) {
if (base_revision >= 1 && base_revision < 3 && (
if (((base_revision >= 1 && base_revision < 3) || base_revision >= 4) && (
_memmap[i].type == MEMMAP_RESERVED
|| _memmap[i].type == MEMMAP_BAD_MEMORY)) {
continue;
}
if (base_revision >= 3 && (
if (base_revision == 3 && (
_memmap[i].type != MEMMAP_USABLE
&& _memmap[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE
&& _memmap[i].type != MEMMAP_KERNEL_AND_MODULES
@ -995,7 +995,7 @@ FEAT_START
struct limine_rsdp_response *rsdp_response =
ext_mem_alloc(sizeof(struct limine_rsdp_response));
rsdp_response->address = base_revision <= 2 ? reported_addr(rsdp) : (uintptr_t)rsdp;
rsdp_response->address = (base_revision <= 2 || base_revision >= 4) ? reported_addr(rsdp) : (uintptr_t)rsdp;
rsdp_request->response = reported_addr(rsdp_response);
FEAT_END
@ -1446,6 +1446,11 @@ FEAT_END
pmm_sanitise_entries(memmap, &memmap_entries, true);
}
if (base_revision >= 4) {
acpi_map_tables();
pmm_sanitise_entries(memmap, &memmap_entries, true);
}
pagemap_t pagemap = {0};
pagemap = build_pagemap(base_revision, nx_available, ranges, ranges_count,
physical_base, virtual_base, direct_map_offset);
@ -1577,6 +1582,9 @@ FEAT_START
case MEMMAP_USABLE:
_memmap[i].type = LIMINE_MEMMAP_USABLE;
break;
case MEMMAP_ACPI_TABLES:
_memmap[i].type = LIMINE_MEMMAP_ACPI_TABLES;
break;
case MEMMAP_ACPI_RECLAIMABLE:
_memmap[i].type = LIMINE_MEMMAP_ACPI_RECLAIMABLE;
break;

View File

@ -7,7 +7,7 @@
#include <flanterm_backends/fb.h>
__attribute__((section(".limine_requests")))
static volatile LIMINE_BASE_REVISION(3);
static volatile LIMINE_BASE_REVISION(4);
static void limine_main(void);
@ -181,6 +181,8 @@ static char *get_memmap_type(uint64_t type) {
return "Usable";
case LIMINE_MEMMAP_RESERVED:
return "Reserved";
case LIMINE_MEMMAP_ACPI_TABLES:
return "ACPI tables";
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
return "ACPI reclaimable";
case LIMINE_MEMMAP_ACPI_NVS:

View File

@ -72,7 +72,7 @@ override CFLAGS += \
-I../flanterm/src \
-isystem ../freestnd-c-hdrs/include \
-D_LIMINE_PROTO \
-DLIMINE_API_REVISION=3
-DLIMINE_API_REVISION=4
ifeq ($(ARCH),x86)
override CFLAGS += \