#include "acpi.h" #include "memops.h" #include "kprintf.h" #include "asm_inline.h" #include 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"); }