hos/kernel/sys/pci.cpp

62 lines
1.3 KiB
C++

// pci.cpp
// Author: Josh Holtrop
// Date: 07/13/05
// Modified: 07/17/05
#define _HOS_CPP_
extern "C" {
#include "hos_defines.h"
#include "display/kout.h"
#include "sys/io.h"
}
#include "pci.h"
#include "lang/vector.h"
vector<pci_header_t> *pci_devices;
int pci_init()
{
pci_devices = new vector<pci_header_t>;
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);
}