From 50201fe6dfe9dfd055ccb33484a49183b14f9168 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Thu, 8 Jun 2023 00:24:50 -0700 Subject: [PATCH] Updated PCIe walk to be recursive and dump the offset of the sata drive --- sys/yellowstone/hw/pcie.cpp | 59 ++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/sys/yellowstone/hw/pcie.cpp b/sys/yellowstone/hw/pcie.cpp index 34ecfde..45286fa 100644 --- a/sys/yellowstone/hw/pcie.cpp +++ b/sys/yellowstone/hw/pcie.cpp @@ -20,8 +20,14 @@ struct PciDeviceHeader { uint8_t bist; } __attribute__((packed)); -void DumpFn(uint64_t fn_start, uint64_t bus, uint64_t dev, uint64_t fun) { - PciDeviceHeader* hdr = reinterpret_cast(fn_start); +PciDeviceHeader* PciHeader(uint64_t base, uint64_t bus, uint64_t dev, + uint64_t fun) { + return reinterpret_cast(base + (bus << 20) + (dev << 15) + + (fun << 12)); +} + +void FunctionDump(uint64_t base, uint64_t bus, uint64_t dev, uint64_t fun) { + PciDeviceHeader* hdr = PciHeader(base, bus, dev, fun); if (hdr->vendor_id == 0xFFFF) { return; } @@ -30,14 +36,47 @@ void DumpFn(uint64_t fn_start, uint64_t bus, uint64_t dev, uint64_t fun) { "%x, %x, %x)", bus, dev, fun, hdr->vendor_id, hdr->device_id, hdr->header_type, hdr->class_code, hdr->subclass, hdr->prog_interface); + + if ((hdr->class_code == 0x6) && (hdr->subclass == 0x4)) { + dbgln("FIXME: Handle PCI to PCI bridge."); + } + if (hdr->class_code == 0x1) { + dbgln("SATA Device at: %lx", reinterpret_cast(hdr) - base); + } } -void PciDump(uint64_t base, uint64_t size) { - for (uint64_t b = 0; b <= 0xFF; b++) { - for (uint64_t d = 0; d <= 0x1F; d++) { - for (uint64_t f = 0; f < 8; f++) { - uint64_t fn_base = base + (b << 20) + (d << 15) + (f << 12); - DumpFn(fn_base, b, d, f); +void DeviceDump(uint64_t base, uint64_t bus, uint64_t dev) { + PciDeviceHeader* hdr = PciHeader(base, bus, dev, 0); + if (hdr->vendor_id == 0xFFFF) { + return; + } + + FunctionDump(base, bus, dev, 0); + + // Device is multifunction. + if (hdr->header_type & 0x80) { + for (uint64_t f = 1; f < 0x8; f++) { + FunctionDump(base, bus, dev, f); + } + } +} + +void BusDump(uint64_t base, uint64_t bus) { + for (uint64_t dev = 0; dev < 0x20; dev++) { + DeviceDump(base, bus, dev); + } +} + +void PciDump(uint64_t base) { + PciDeviceHeader* hdr = PciHeader(base, 0, 0, 0); + if ((hdr->header_type & 0x80) == 0) { + // Single bus system. + BusDump(base, 0); + } else { + for (uint64_t f = 0; f < 8; f++) { + PciDeviceHeader* f_hdr = PciHeader(base, 0, 0, f); + if (f_hdr->vendor_id != 0xFFFF) { + BusDump(base, f); } } } @@ -53,9 +92,9 @@ void DumpPciEDevices() { dbgln("Creating addr space"); uint64_t vaddr; check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr)); - dbgln("Addr %x", vaddr); + dbgln("Addr %lx", vaddr); dbgln("Dumping PCI"); - PciDump(vaddr, vmmo_size); + PciDump(vaddr); dbgln("Done"); }