for (bus=0; bus < CONFIG_PCI_BUS_COUNT; bus++) {
for (devfn=0; devfn<0x100; devfn++) {
PCIDevice d = pci_bd(bus, devfn);
- u32 v = pci_config_readl(d, 0x00);
+ u32 v = pci_config_readl(d, PCI_VENDOR_ID);
if (v != id)
continue;
if (index) {
return -1;
}
+// Search for a device with the specified class id and prog-if.
int
-pci_find_class(u32 classid, int index, PCIDevice *dev)
+pci_find_classprog(u32 classprog, int index, PCIDevice *dev)
{
int devfn, bus;
for (bus=0; bus < CONFIG_PCI_BUS_COUNT; bus++) {
for (devfn=0; devfn<0x100; devfn++) {
PCIDevice d = pci_bd(bus, devfn);
u32 v = pci_config_readl(d, 0x08);
- if ((v>>8) != classid)
+ if ((v>>8) != classprog)
+ continue;
+ if (index) {
+ index--;
+ continue;
+ }
+ // Found it.
+ *dev = d;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+// Search for a device with the specified class id.
+int
+pci_find_class(u16 classid, int index, PCIDevice *dev)
+{
+ int devfn, bus;
+ for (bus=0; bus < CONFIG_PCI_BUS_COUNT; bus++) {
+ for (devfn=0; devfn<0x100; devfn++) {
+ PCIDevice d = pci_bd(bus, devfn);
+ u16 v = pci_config_readw(d, PCI_CLASS_DEVICE);
+ if (v != classid)
continue;
if (index) {
index--;
u8 devfn;
} PCIDevice;
-static inline PCIDevice
-pci_bd(u8 bus, u8 devfn)
-{
+static inline PCIDevice pci_bd(u8 bus, u8 devfn) {
struct PCIDevice d = {bus, devfn};
return d;
}
+static inline u16 pci_to_bdf(PCIDevice d) {
+ return (d.bus << 8) | d.devfn;
+}
+static inline u8 pci_bdf_to_bus(u16 bdf) {
+ return bdf >> 8;
+}
+static inline u8 pci_bdf_to_dev(u16 bdf) {
+ return (bdf >> 3) & 0x1f;
+}
+static inline u8 pci_bdf_to_fn(u16 bdf) {
+ return bdf & 0x07;
+}
void pci_config_writel(PCIDevice d, u32 addr, u32 val);
void pci_config_writew(PCIDevice d, u32 addr, u16 val);
u8 pci_config_readb(PCIDevice d, u32 addr);
int pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev);
-int pci_find_class(u32 classid, int index, PCIDevice *dev);
+int pci_find_classprog(u32 classprog, int index, PCIDevice *dev);
+int pci_find_class(u16 classid, int index, PCIDevice *dev);
// pirtable.c
void create_pirtable();
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
+#define PCI_CLASS_PROG 0x09
#define PCI_CLASS_DEVICE 0x0a /* Device class */
+#define PCI_BASE_ADDR_0 0x10
+#define PCI_BASE_ADDR_1 0x14
+#define PCI_BASE_ADDR_2 0x18
+#define PCI_BASE_ADDR_3 0x1c
+#define PCI_BASE_ADDR_4 0x20
+#define PCI_BASE_ADDR_5 0x24
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */