mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
acpi: table parsing
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#include <arch/acpi.h>
|
||||
#include <limine.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <string.h>
|
||||
|
||||
static size_t headercount;
|
||||
static sdtheader_t **headers;
|
||||
|
||||
static volatile struct limine_rsdp_request rsdpreq = {
|
||||
.id = LIMINE_RSDP_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
bool 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 *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;
|
||||
}
|
||||
|
||||
void acpi_init() {
|
||||
// FIXME search if no response
|
||||
__assert(rsdpreq.response);
|
||||
rsdp_t *rsdp = rsdpreq.response->address;
|
||||
|
||||
if (rsdp->revision == 0) {
|
||||
printf("\e[93mACPI version 1.0 -- Using RSDT instead of XSDT.\e[0m\n");
|
||||
rsdt_t *rsdt = MAKE_HHDM((rsdt_t *)(uint64_t)rsdp->rsdt);
|
||||
__assert(acpi_checksumok(rsdt));
|
||||
headercount = (rsdt->header.length - sizeof(sdtheader_t)) / sizeof(uint32_t);
|
||||
headers = alloc(sizeof(sdtheader_t *) * headercount);
|
||||
__assert(headers);
|
||||
|
||||
for (size_t i = 0; i < headercount; ++i) {
|
||||
void *addr = MAKE_HHDM((void *)(uint64_t)rsdt->tables[i]);
|
||||
if (acpi_checksumok(addr))
|
||||
headers[i] = addr;
|
||||
}
|
||||
} else {
|
||||
xsdt_t *xsdt = MAKE_HHDM((xsdt_t *)rsdp->xsdt);
|
||||
__assert(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) {
|
||||
void *addr = MAKE_HHDM((void *)xsdt->tables[i]);
|
||||
if (acpi_checksumok(addr))
|
||||
headers[i] = addr;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ACPI: %lu tables found\n", headercount);
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <kernel/vmm.h>
|
||||
#include <kernel/slab.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <arch/acpi.h>
|
||||
|
||||
static cpu_t bsp_cpu;
|
||||
|
||||
@@ -24,5 +25,6 @@ void kernel_entry() {
|
||||
arch_mmu_init();
|
||||
vmm_init();
|
||||
alloc_init();
|
||||
acpi_init();
|
||||
__assert(!"kernel entry end");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef _ACPI_H
|
||||
#define _ACPI_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
char sig[8];
|
||||
uint8_t checksum;
|
||||
char oem[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt;
|
||||
uint32_t length;
|
||||
uint64_t xsdt;
|
||||
uint8_t xchecksum;
|
||||
uint8_t reserved[3];
|
||||
} __attribute__((packed)) rsdp_t;
|
||||
|
||||
typedef struct {
|
||||
char sig[4];
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t cechksum;
|
||||
char oemid[6];
|
||||
char oemtableid[8];
|
||||
uint32_t oemrevision;
|
||||
uint32_t creatorrevision;
|
||||
} __attribute__((packed)) sdtheader_t;
|
||||
|
||||
typedef struct {
|
||||
sdtheader_t header;
|
||||
uint64_t tables[];
|
||||
} __attribute__((packed)) xsdt_t;
|
||||
|
||||
typedef struct {
|
||||
sdtheader_t header;
|
||||
uint32_t tables[];
|
||||
} __attribute__((packed)) rsdt_t;
|
||||
|
||||
void acpi_init();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user