Integrate uACPI & remove own ACPI parsing code

This commit adds uACPI as a submodule and removes all handwritten table
parsing code as well as struct definitions, since they now work via
uACPI. There's also now an ability to shut down by using the power
button.
This commit is contained in:
8infy
2024-09-01 19:51:39 +03:00
parent 476d4bad74
commit db55f99e23
14 changed files with 758 additions and 266 deletions
+20 -14
View File
@@ -11,8 +11,11 @@
#include <kernel/alloc.h>
#include <arch/cpu.h>
#include <uacpi/acpi.h>
#include <uacpi/tables.h>
static size_t mcfgentrycount;
static mcfgentry_t *mcfgentries;
static struct acpi_mcfg_allocation *mcfgentries;
static uint32_t (*pci_archread32)(int bus, int device, int function, uint32_t offset);
static void (*pci_archwrite32)(int bus, int device, int function, uint32_t offset, uint32_t value);
@@ -31,13 +34,13 @@ static void legacy_write32(int bus, int device, int function, uint32_t offset, u
outd(CONFDATA, value);
}
static inline mcfgentry_t *getmcfgentry(int bus) {
mcfgentry_t *entry;
static inline struct acpi_mcfg_allocation *getmcfgentry(int bus) {
struct acpi_mcfg_allocation *entry;
int i;
for (i = 0; i < mcfgentrycount; ++i) {
entry = &mcfgentries[i];
if (bus >= entry->startbus && bus <= entry->endbus)
if (bus >= entry->start_bus && bus <= entry->end_bus)
break;
}
@@ -48,21 +51,21 @@ static inline mcfgentry_t *getmcfgentry(int bus) {
}
static uint32_t mcfg_read32(int bus, int device, int function, uint32_t offset) {
mcfgentry_t *entry = getmcfgentry(bus);
struct acpi_mcfg_allocation *entry = getmcfgentry(bus);
if (entry == NULL)
return 0xffffffff;
uint64_t base = (uint64_t)entry->address;
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->start_bus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
return *address;
}
static void mcfg_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
mcfgentry_t *entry = getmcfgentry(bus);
struct acpi_mcfg_allocation *entry = getmcfgentry(bus);
uint64_t base = (uint64_t)entry->address;
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->start_bus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
*address = value;
}
@@ -77,20 +80,23 @@ static uint64_t msiformatmessage(uint32_t *data, int vector, int edgetrigger, in
#define MCFG_MAPPING_SIZE(buscount) (4096l * 8l * 32l * (buscount))
static void pci_archinit() {
mcfg_t *mcfg = arch_acpi_findtable("MCFG", 0);
uacpi_table tbl;
struct acpi_mcfg *mcfg;
if (mcfg) {
uacpi_status ret = uacpi_table_find_by_signature("MCFG", &tbl);
if (ret == UACPI_STATUS_OK) {
printf("pci: MCFG table found. Using extended configuration space\n");
mcfg = tbl.ptr;
pci_archread32 = mcfg_read32;
pci_archwrite32 = mcfg_write32;
mcfgentrycount = (mcfg->header.length - sizeof(sdtheader_t)) / sizeof(mcfgentry_t);
mcfgentries = alloc(sizeof(mcfgentry_t) * mcfgentrycount);
mcfgentrycount = (mcfg->hdr.length - sizeof(struct acpi_sdt_hdr)) / sizeof(struct acpi_mcfg_allocation);
mcfgentries = alloc(sizeof(struct acpi_mcfg_allocation) * mcfgentrycount);
__assert(mcfgentries);
memcpy(mcfgentries, mcfg->entries, sizeof(mcfgentry_t) * mcfgentrycount);
memcpy(mcfgentries, mcfg->entries, sizeof(struct acpi_mcfg_allocation) * mcfgentrycount);
for (int i = 0; i < mcfgentrycount; ++i) {
void *phys = (void *)mcfgentries[i].address;
uintmax_t pageoffset = (uintptr_t)phys % PAGE_SIZE;
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].endbus - mcfgentries[i].startbus + 1);
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].end_bus - mcfgentries[i].start_bus + 1);
void *virt = vmm_map(NULL, mappingsize, VMM_FLAGS_PHYSICAL,
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_UC, phys);
__assert(virt);