ACPI tables support

Added parsing for the (X)RSDT and RSDP, as well as table searching.
This commit is contained in:
Matheus
2022-08-05 17:27:01 -03:00
parent ea8f21fb71
commit 592133af39
3 changed files with 129 additions and 0 deletions
+82
View File
@@ -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);
}
+44
View File
@@ -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
+3
View File
@@ -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);