/* * */ #include #include #include "pci.h" const uint16_t CONFIG_ADDRESS = 0xCF8; const uint16_t CONFIG_DATA = 0xCFC; /* Make a PCI Address */ static inline uint32_t make_pci_address(int bus, int dev, int func, int off) { return (1 << 31) | (bus << 16) | (dev << 11) | (func << 8) | (off & 0xFC); } /* Read PCI config byte */ uint8_t pci_read_byte(int bus, int dev, int func, int off) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); return inb(CONFIG_DATA + (off & 3)); } /* Read PCI config word */ uint16_t pci_read_word(int bus, int dev, int func, int off) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); return inw(CONFIG_DATA + (off & 2)); } /* Read PCI config dword */ uint32_t pci_read_dword(int bus, int dev, int func, int off) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); return inl(CONFIG_DATA); } /* Write PCI config byte */ void pci_write_byte(int bus, int dev, int func, int off, uint8_t value) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); outb(CONFIG_DATA + (off & 3), value); } /* Write PCI config word */ void pci_write_word(int bus, int dev, int func, int off, uint16_t value) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); outw(CONFIG_DATA + (off & 2), value); } /* Write PCI config dword */ void pci_write_dword(int bus, int dev, int func, int off, uint32_t value) { outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off)); outl(CONFIG_DATA, value); } /* Scan for PCI devices */ void init_pci(void) { uint16_t bus, slot, func; uint16_t vendor, device; uint8_t class, subclass; uint32_t dev; /* This is one massive iteration */ for (bus = 0; bus < 256; bus++) for (slot = 0; slot < 32; slot++) for (func = 0; func < 8; func++) if ((vendor = pci_read_word(bus, slot, func, 0)) != 0xFFFF) { device = pci_read_word(bus, slot, func, 2); /* do something */ // kprintf("PCI(%d,%d,%d) = %#.4x:%#.4x", // bus, slot, func, vendor, device); } }