// pci.cpp // Author: Josh Holtrop // Date: 07/13/05 // Modified: 07/17/05 extern "C" { #include "hos_defines.h" #include "display/kout.h" #include "sys/io.h" } #include "pci.h" #include "lang/vector.h" vector *pci_devices; int pci_init() { pci_devices = new vector; pci_scanBus(0); return 0; } void pci_scanBus(u32_t bus) { pci_header_t pciHdr; u32_t dev, func, off, reg, numFuncs; for (dev = 0; dev < 32; dev++) { numFuncs = 1; for (func = 0; func < 8; func++) { reg = pci_readConfigRegister(bus, dev, func, 0); if (reg != 0 && reg != 0xFFFFFFFF) { for (off = 0; off < 0x40; off += 4) *((u32_t *)(((u32_t)&pciHdr)+off)) = pci_readConfigRegister(bus, dev, func, off); pci_devices->add(pciHdr); if (func == 0 && (pciHdr.header & 0x80)) numFuncs = 8; kprintf("PCI device %d.%d.%d:\t(%s)\n", bus, dev, func, pci_getDeviceClass(pciHdr.cls, pciHdr.subclass, pciHdr.progif)); if ((pciHdr.header & 0x7F) == 1) pci_scanBus(pciHdr.h1_bus1); } } } } u32_t pci_readConfigRegister(u32_t bus, u32_t dev, u32_t func, u32_t offset) { outportd(PCI_CONFIG_ADDRESS, 0x80000000 | ((bus & 0xFF) << 16) | ((dev & 0x1F) << 11) | ((func & 0x7) << 8) | (offset & 0xFC)); return inportd(PCI_CONFIG_DATA); }