mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-30 22:18:21 +00:00
x86_64 pci: properly map ECAM and fix access to it
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
#include <kernel/pmm.h>
|
#include <kernel/pmm.h>
|
||||||
|
#include <kernel/alloc.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
static size_t mcfgentrycount;
|
static size_t mcfgentrycount;
|
||||||
@@ -51,8 +52,8 @@ static uint32_t mcfg_read32(int bus, int device, int function, uint32_t offset)
|
|||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
|
|
||||||
uint64_t base = (uint64_t)MAKE_HHDM(entry->address);
|
uint64_t base = (uint64_t)entry->address;
|
||||||
uint32_t *address = (uint32_t *)(base | ((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3));
|
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
|
||||||
|
|
||||||
return *address;
|
return *address;
|
||||||
}
|
}
|
||||||
@@ -60,8 +61,8 @@ static uint32_t mcfg_read32(int bus, int device, int function, uint32_t offset)
|
|||||||
static void mcfg_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
|
static void mcfg_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
|
||||||
mcfgentry_t *entry = getmcfgentry(bus);
|
mcfgentry_t *entry = getmcfgentry(bus);
|
||||||
|
|
||||||
uint64_t base = (uint64_t)MAKE_HHDM(entry->address);
|
uint64_t base = (uint64_t)entry->address;
|
||||||
uint32_t *address = (uint32_t *)(base | ((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3));
|
volatile uint32_t *address = (uint32_t *)((uintptr_t)base + (((bus - entry->startbus) << 20) | (device << 15) | (function << 12) | (offset & ~0x3)));
|
||||||
|
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
@@ -71,15 +72,30 @@ static uint64_t msiformatmessage(uint32_t *data, int vector, int edgetrigger, in
|
|||||||
return 0xfee00000 | (_cpu()->id << 12);
|
return 0xfee00000 | (_cpu()->id << 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in PCIe, every function has 4096 bytes of config space for it.
|
||||||
|
// there are 8 functions per device and 32 devices per bus
|
||||||
|
#define MCFG_MAPPING_SIZE(buscount) (4096l * 8l * 32l * (buscount))
|
||||||
|
|
||||||
static void pci_archinit() {
|
static void pci_archinit() {
|
||||||
mcfg_t *mcfg = arch_acpi_findtable("MCFG", 0);
|
mcfg_t *mcfg = arch_acpi_findtable("MCFG", 0);
|
||||||
|
|
||||||
if (mcfg) {
|
if (mcfg) {
|
||||||
printf("pci: MCFG table found. Using extended configuration space\n");
|
printf("pci: MCFG table found. Using extended configuration space\n");
|
||||||
mcfgentries = mcfg->entries;
|
|
||||||
pci_archread32 = mcfg_read32;
|
pci_archread32 = mcfg_read32;
|
||||||
pci_archwrite32 = mcfg_write32;
|
pci_archwrite32 = mcfg_write32;
|
||||||
mcfgentrycount = (mcfg->header.length - sizeof(sdtheader_t)) / sizeof(mcfgentry_t);
|
mcfgentrycount = (mcfg->header.length - sizeof(sdtheader_t)) / sizeof(mcfgentry_t);
|
||||||
// TODO map mcfg entries as UC
|
mcfgentries = alloc(sizeof(mcfgentry_t) * mcfgentrycount);
|
||||||
|
__assert(mcfgentries);
|
||||||
|
memcpy(mcfgentries, mcfg->entries, sizeof(mcfgentry_t) * 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);
|
||||||
|
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);
|
||||||
|
mcfgentries[i].address = (uintptr_t)virt + pageoffset;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("pci: MCFG table not found. Falling back to legacy access mechanism\n");
|
printf("pci: MCFG table not found. Falling back to legacy access mechanism\n");
|
||||||
pci_archread32 = legacy_read32;
|
pci_archread32 = legacy_read32;
|
||||||
|
|||||||
Reference in New Issue
Block a user