#include #include #include #include #include struct kernel_context { struct rsdp *rsdp; struct xsdp *xsdp; struct rsdt *rsdt; }; struct kernel_context ctx = {0}; void *acpi_find_sdt(void *RootSDT, const char sig[4]) { struct rsdt *rsdt = (struct rsdt *) RootSDT; int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4; for (int i = 0; i < entries; i++) { struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i]; if (!strncmp(h->Signature, sig, 4)) return (void *) h; } return 0; } uint16_t readw(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) { uint32_t lbus = (uint32_t)bus; uint32_t lslot = (uint32_t)slot; uint32_t lfunc = (uint32_t)func; uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12); return *(uint16_t *)address; } uint8_t readb(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) { uint32_t lbus = (uint32_t)bus; uint32_t lslot = (uint32_t)slot; uint32_t lfunc = (uint32_t)func; uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12); return *(uint8_t *)address; } uint32_t readd(uint32_t addr, uint32_t offset, uint8_t bus, uint8_t slot, uint8_t func) { uint32_t lbus = (uint32_t)bus; uint32_t lslot = (uint32_t)slot; uint32_t lfunc = (uint32_t)func; uint32_t address = addr + offset + ((lbus) << 20 | lslot << 15 | lfunc << 12); return *(uint32_t *)address; } void kmain(struct multiboot_info *info) { clear_screen(); // Check if the bootloader gave us the upper and lower memory if (!(info->flags & 0x1)) goto halt; struct rsdp *found_rsdp = acpi_search_for_rsdp(); if (!found_rsdp) { printf("Failed to find RSDP signature\n"); goto halt; } printf("RSDP detected at 0x%X\n", found_rsdp); if (found_rsdp->Revision == ACPI_VER_1) { // ACPI v1.0 is being used if (!acpi_validate_rsdp_checksum(found_rsdp)) { printf("RSDP has an invalid checksum\n"); goto halt; } ctx.rsdp = found_rsdp; ctx.xsdp = 0; if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) { printf("RSDT has an invalid checksum\n"); goto halt; } ctx.rsdt = (struct rsdt*)found_rsdp->RsdtAddress; printf("RSDT detected at 0x%X\n", found_rsdp->RsdtAddress); } else if (found_rsdp->Revision == ACPI_VER_OTHER) { printf("ACPI versions higher than 1.0 are not supported\n"); goto halt; } else { printf("Invalid RSDP\n"); goto halt; } printf("Using ACPI v1.0\n"); struct mcfg *mcfg = acpi_find_sdt(ctx.rsdt, "MCFG"); if (!mcfg) { printf("Failed to find MCFG\n"); goto halt; } printf("Detected MCFG at 0x%X\n", mcfg); int entries = (mcfg->h.Length - 44) / 16; for (int i = 0; i < entries; i++) { uint32_t addr = (uint32_t)mcfg->entries[i].base_addr; for (int j = 0; j < 256; j++) { for (int k = 0; k < 8; k++) { uint32_t word = readd(addr, 8, i, j, k); if (word != 0xFFFFFFFF && word) { printf("%08X\n", word >> 8); } } } } halt: for (;;) {} }