blob: a5416b665d6ffc0d4a56914edffe8e7192526028 [file] [log] [blame]
#include <dri/pci/pci.h>
#include <dri/pci/vendors.h>
#include <io.h>
#include <log.h>
uint pci_config_readd(uchar bus, uchar slot, uchar func, uchar offset)
{
uint address = (bus << 16) | (slot << 11) | (func << 8) | (offset << 2) | 0x80000000;
outl(PCI_CONFIG_ADDRESS, address);
return inl(PCI_CONFIG_DATA);
}
struct pci_vendor *pci_check_vendor(uchar bus, uchar slot, uchar func, ushort *v, ushort *d)
{
uint vendor_device = pci_config_readd(bus, slot, func, 0);
ushort vendor = vendor_device & 0xffff;
if (v)
*v = vendor;
if (vendor != 0xffff)
{
if (d)
*d = vendor_device >> 16;
return pci_vendor_by_id(vendor);
}
return NULL;
}
struct pci_vendor *pci_vendor_by_id(ushort id)
{
// Find vendor using binary search
uint start = 0,
max = pci_num_vendors;
while (true)
{
if (max == start)
// Can't find one
return NULL;
uint guess = (max - start) / 2 + start;
if (pci_vendors[guess].id == id)
return &pci_vendors[guess];
else if (pci_vendors[guess].id > id)
max = guess;
else
start = guess;
}
}
void pci_print_devices()
{
kprintf("Enumerating PCI devices:\n");
for (int bus = 0; bus < 0xff; bus++)
{
for (int slot = 0; slot < 32; slot++)
{
for (int func = 0; func < 8; func++)
{
ushort vendor, device;
struct pci_vendor *v = pci_check_vendor(bus, slot, func, &vendor, &device);
if (v)
{
kprintf("%d %d %d --- v:0x%x d:0x%x --- %s\n", bus, slot, func, vendor, device, v->name);
}
}
}
}
}