aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/acpi.c
diff options
context:
space:
mode:
authorGravatar ornitorrincos 2026-08-18 12:15:05 +0200
committerGravatar ornitorrincos 2026-08-18 12:15:05 +0200
commit132d3236bb884433bf94e961f6d32264e0334aec (patch)
tree06638976b06f019ea4037175ff228f8271057c44 /kernel/acpi.c
Diffstat (limited to '')
-rw-r--r--kernel/acpi.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/kernel/acpi.c b/kernel/acpi.c
new file mode 100644
index 0000000..5879d05
--- /dev/null
+++ b/kernel/acpi.c
@@ -0,0 +1,169 @@
+#include "acpi.h"
+#include "memops.h"
+#include "kprintf.h"
+#include "asm_inline.h"
+
+#include <stddef.h>
+
+void* getPointerToOtherSDT(ACPISDTHeader* header)
+{
+ uint8_t* base = (uint8_t*)header;
+ return &(base[36]);
+}
+
+void* getACPITablesPointer(APICHeader* header)
+{
+ uint8_t* base = (uint8_t*)header;
+ return &(base[44]);
+}
+
+#define IS_TABLE(x, header) kmemcmp(x, header->signature, 4*sizeof(uint8_t))
+
+enum ACPI_TABLES getTableType(ACPISDTHeader* header)
+{
+ if(IS_TABLE("APIC", header)) return APIC;
+ if(IS_TABLE("BGRT", header)) return BGRT;
+ if(IS_TABLE("BERT", header)) return BERT;
+ if(IS_TABLE("CPEP", header)) return CPEP;
+ if(IS_TABLE("DSDT", header)) return DSDT;
+ if(IS_TABLE("ECDT", header)) return ECDT;
+ if(IS_TABLE("EINJ", header)) return EINJ;
+ if(IS_TABLE("ERST", header)) return ERST;
+ if(IS_TABLE("FACP", header)) return FACP;
+ if(IS_TABLE("FACS", header)) return FACS;
+ if(IS_TABLE("HEST", header)) return HEST;
+ if(IS_TABLE("MSCT", header)) return MSCT;
+ if(IS_TABLE("MPST", header)) return MPST;
+ if(IS_TABLE("OEMx", header)) return OEMx;
+ if(IS_TABLE("PMTT", header)) return PMTT;
+ if(IS_TABLE("PSDT", header)) return PSDT;
+ if(IS_TABLE("RASF", header)) return RASF;
+ if(IS_TABLE("RSDT", header)) return RSDT;
+ if(IS_TABLE("SBST", header)) return SBST;
+ if(IS_TABLE("SLIT", header)) return SLIT;
+ if(IS_TABLE("SRAT", header)) return SRAT;
+ if(IS_TABLE("SSDT", header)) return SSDT;
+ if(IS_TABLE("XSDT", header)) return XSDT;
+ if(IS_TABLE("HPET", header)) return HPET;
+
+ return NONE;
+}
+
+void* getTable(void* xsdt, enum ACPI_TABLES table)
+{
+ ACPISDTHeader* header = (ACPISDTHeader*)xsdt;
+ uint64_t* tables = (uint64_t*)getPointerToOtherSDT(xsdt);
+ uint64_t entries = (header->length - sizeof(ACPISDTHeader)) / 8;
+
+ for(int i = 0; i < entries; i++)
+ {
+ uint64_t table_ptr = tables[i];
+
+ if(getTableType((ACPISDTHeader*)table_ptr) == table)
+ {
+ return (ACPISDTHeader*)table_ptr;
+ }
+ }
+
+ return NULL;
+}
+
+void* getAPIC(APICHeader* header, enum APIC_TYPE apic)
+{
+ header->length;
+ uint8_t* apic_tables = (uint8_t*)getACPITablesPointer(header);
+ APICEntry* entry = (APICEntry*)apic_tables;
+ uint8_t offset = 0;
+
+ while(offset < (header->length - sizeof(APICHeader)))
+ {
+ APICEntry* entry = (APICEntry*)&(apic_tables[offset]);
+ if(entry->type == apic)
+ {
+ return entry;
+ }
+
+ offset += entry->length;
+ }
+
+ return NULL;
+}
+
+uint64_t numberTables(APICHeader* header)
+{
+ header->length;
+ uint8_t* apic_tables = (uint8_t*)getACPITablesPointer(header);
+ APICEntry* entry = (APICEntry*)apic_tables;
+ uint8_t offset = 0;
+ uint64_t tables = 0;
+
+ while(offset < (header->length - sizeof(APICHeader)))
+ {
+ /*
+ APICEntry* entry = (APICEntry*)&(apic_tables[offset]);
+ if(entry->type == apic)
+ {
+ return entry;
+ }
+ */
+
+ tables++;
+ offset += entry->length;
+ }
+
+ return tables;
+}
+
+void init_acpi(XSDP* xsdp)
+{
+ kprintf("=> Initializing ACPI\n");
+
+ uint64_t pic_master = inb(0x21);
+ uint64_t pic_slave = inb(0xA1);
+
+ if((pic_master == 0xFF) && (pic_slave == 0xFF))
+ {
+ kprintf("==> PIC disabled\n");
+ }
+
+ if(xsdp != NULL)
+ {
+ kprintf("==> ACPI 2.0 Found\n");
+ }
+ else
+ {
+ kprintf("==X No ACPI 2.0 Found\n");
+ return;
+ }
+
+ ACPISDTHeader* xsdt = (ACPISDTHeader*)xsdp->xsdtaddress;
+
+ APICHeader* apic_table = (APICHeader*)getTable(xsdt, APIC);
+ if(apic_table == NULL)
+ {
+ kprintf("==X Failed To Find APIC Table\n");
+ return;
+ }
+
+ kprintf("==> Found APIC Table\n");
+ if(apic_table->flags >= 0)
+ {
+ kprintf("==> Dual 8259 PIC Found\n");
+ }
+
+ IOAPICTable* ioapic = getAPIC(apic_table, IOAPIC);
+ if(ioapic == NULL)
+ {
+ kprintf("==X Failed to find a valid IOAPIC\n");
+ return;
+ }
+
+ uint64_t n_tables = numberTables(apic_table);
+
+ kprintf("Number of Tables: %ld\n", n_tables);
+
+ kprintf("==> IOAPIC Found\n");
+
+
+ // kprintf("=> ACPI Initialized\n");
+}