mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
ACPI tables support
Added parsing for the (X)RSDT and RSDP, as well as table searching.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
#include <arch/acpi.h>
|
||||
#include <limine.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <arch/panic.h>
|
||||
#include <string.h>
|
||||
#include <kernel/pmm.h>
|
||||
|
||||
static bool usersdt = false;
|
||||
static sdt_t* sdt;
|
||||
static size_t sdtentrycount;
|
||||
|
||||
|
||||
static volatile struct limine_rsdp_request rsdpreq = {
|
||||
.id = LIMINE_RSDP_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
static bool checksumok(sdt_t* table){
|
||||
uint8_t sum;
|
||||
uint8_t* ptr = (uint8_t*)table;
|
||||
|
||||
for(size_t i = 0; i < table->length; ++i)
|
||||
sum += *ptr++;
|
||||
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
void* acpi_gettable(char* sig, size_t n){
|
||||
size_t ptrsize = usersdt ? 4 : 8;
|
||||
|
||||
void* ptr = (char*)sdt + sizeof(sdt_t);
|
||||
|
||||
|
||||
for(size_t i = 0; i < sdtentrycount; ++i){
|
||||
|
||||
sdt_t* table = usersdt ? (*(uint32_t*)ptr & 0xFFFFFFFF) : *(uint64_t*)ptr;
|
||||
|
||||
table = (uint8_t*)table + (size_t)limine_hhdm_offset;
|
||||
|
||||
if(!strncmp(sig, table->signature, 4)){
|
||||
if(n-- == 0)
|
||||
return (uint8_t*)table + (size_t) limine_hhdm_offset;
|
||||
|
||||
}
|
||||
|
||||
ptr += ptrsize;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void acpi_init(){
|
||||
if(!rsdpreq.response){
|
||||
// TODO search for ourselves
|
||||
_panic("No reponse for the RSDP request", 0);
|
||||
}
|
||||
|
||||
rsdp_t* rsdp = rsdpreq.response->address;
|
||||
|
||||
printf("RSDP at: %p\n", rsdp);
|
||||
|
||||
sdt = rsdp->xsdtaddr;
|
||||
|
||||
if(rsdp->revision == 0){
|
||||
printf("WARNING: XSDT does not exist in revision 0, falling back to RSDT!\n");
|
||||
sdt = rsdp->rsdtaddr;
|
||||
usersdt = true;
|
||||
}
|
||||
|
||||
sdt = (uint8_t*)sdt + (size_t)limine_hhdm_offset;
|
||||
|
||||
sdtentrycount = (sdt->length - sizeof(sdt_t)) / (usersdt ? 4 : 8);
|
||||
|
||||
printf("Root System Description Table address: %p with %lu tables\n", sdt, sdtentrycount);
|
||||
|
||||
if(!checksumok(sdt))
|
||||
_panic("Invalid RSDT checksum!", 0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef _ACPI_H_INCLUDE
|
||||
#define _ACPI_H_INCLUDE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdtaddr;
|
||||
|
||||
uint32_t length;
|
||||
uint64_t xsdtaddr;
|
||||
uint8_t xchecksum;
|
||||
} __attribute__((packed))rsdp_t;
|
||||
|
||||
typedef struct {
|
||||
char signature[4];
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t checksum;
|
||||
char oem[6];
|
||||
char oemtable[8];
|
||||
uint32_t oemrevision;
|
||||
uint32_t creator;
|
||||
uint32_t creatorrevision;
|
||||
} __attribute__((packed)) sdt_t;
|
||||
|
||||
typedef struct {
|
||||
sdt_t header;
|
||||
uint64_t pointers[];
|
||||
} __attribute__((packed)) xsdt_t;
|
||||
|
||||
typedef struct {
|
||||
sdt_t header;
|
||||
uint32_t pointers[];
|
||||
} __attribute__((packed)) rsdt_t;
|
||||
|
||||
void* acpi_gettable(char* sig, size_t n);
|
||||
void acpi_init();
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <kernel/alloc.h>
|
||||
#include <arch/panic.h>
|
||||
#include <kernel/vfs.h>
|
||||
#include <arch/acpi.h>
|
||||
|
||||
static volatile struct limine_terminal_request liminettyr = {
|
||||
.id = LIMINE_TERMINAL_REQUEST,
|
||||
@@ -56,6 +57,8 @@ void kmain(){
|
||||
_panic("Failed to mount tmpfs", 0);
|
||||
|
||||
initrd_parse();
|
||||
|
||||
acpi_init();
|
||||
|
||||
_panic("End of kmain()", 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user