mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
Integrate uACPI & remove own ACPI parsing code
This commit adds uACPI as a submodule and removes all handwritten table parsing code as well as struct definitions, since they now work via uACPI. There's also now an ability to shut down by using the power button.
This commit is contained in:
@@ -1,86 +1,12 @@
|
||||
#include <arch/acpi.h>
|
||||
#include <limine.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/vmm.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <string.h>
|
||||
|
||||
static size_t headercount;
|
||||
static sdtheader_t **headers;
|
||||
#include <stdint.h>
|
||||
|
||||
static volatile struct limine_rsdp_request rsdpreq = {
|
||||
.id = LIMINE_RSDP_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
bool arch_acpi_checksumok(void *table) {
|
||||
sdtheader_t *header = table;
|
||||
uint8_t *ptr = table;
|
||||
uint8_t sum = 0;
|
||||
for (int i = 0; i < header->length; ++i)
|
||||
sum += *ptr++;
|
||||
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
void *arch_acpi_findtable(char *sig, int n) {
|
||||
for (size_t i = 0; i < headercount; ++i) {
|
||||
if (headers[i] == NULL)
|
||||
continue;
|
||||
|
||||
if (strncmp(sig, headers[i]->sig, 4) == 0) {
|
||||
if (n-- == 0)
|
||||
return headers[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *map_table(void *physical) {
|
||||
// TODO map according to header length entry
|
||||
uintmax_t pageoffset = (uintptr_t)physical % PAGE_SIZE;
|
||||
void *virt = vmm_map(NULL, PAGE_SIZE * 16, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, physical);
|
||||
__assert(virt);
|
||||
return (void *)((uintptr_t)virt + pageoffset);
|
||||
}
|
||||
|
||||
void arch_acpi_init() {
|
||||
// FIXME search if no response
|
||||
__assert(rsdpreq.response);
|
||||
rsdp_t *rsdp = map_table(FROM_HHDM(rsdpreq.response->address));
|
||||
|
||||
if (rsdp->revision == 0) {
|
||||
printf("\e[93macpi: version 1.0 -- Using RSDT instead of XSDT.\e[0m\n");
|
||||
rsdt_t *rsdt = map_table((void *)(uint64_t)rsdp->rsdt);
|
||||
__assert(arch_acpi_checksumok(rsdt));
|
||||
|
||||
headercount = (rsdt->header.length - sizeof(sdtheader_t)) / sizeof(uint32_t);
|
||||
headers = alloc(sizeof(sdtheader_t *) * headercount);
|
||||
__assert(headers);
|
||||
|
||||
// TODO map according to the header length entry
|
||||
for (size_t i = 0; i < headercount; ++i) {
|
||||
// map it
|
||||
void *addr = map_table((void *)(uint64_t)rsdt->tables[i]);
|
||||
if (arch_acpi_checksumok(addr))
|
||||
headers[i] = addr;
|
||||
}
|
||||
} else {
|
||||
xsdt_t *xsdt = map_table((void *)rsdp->xsdt);
|
||||
__assert(arch_acpi_checksumok(xsdt));
|
||||
|
||||
headercount = (xsdt->header.length - sizeof(sdtheader_t)) / sizeof(uint64_t);
|
||||
headers = alloc(sizeof(sdtheader_t *) * headercount);
|
||||
__assert(headers);
|
||||
|
||||
for (size_t i = 0; i < headercount; ++i) {
|
||||
// map it
|
||||
void *addr = map_table((void *)xsdt->tables[i]);
|
||||
if (arch_acpi_checksumok(addr))
|
||||
headers[i] = addr;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ACPI: %lu tables found\n", headercount);
|
||||
uintptr_t arch_get_rsdp(void) {
|
||||
return (uintptr_t)FROM_HHDM(rsdpreq.response->address);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user