mirror of
https://codeberg.org/Limine/Limine
synced 2026-01-26 21:22:15 +00:00
protos/limine: Initial implementation of base revision 4
This commit is contained in:
parent
cf739c2441
commit
80c82d9772
@ -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 \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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 += \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user