diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-08-31 11:06:27 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-08-31 11:06:27 -0400 |
commit | 5fdaa0346cb9d864ffff0e6fd2c2139c4a6b612f (patch) | |
tree | ccd6c13405c18a2397b191d187f820780bb0634d /src | |
parent | 15b3165711bc3c94b4941e17bc9036cd151f997e (diff) | |
download | seabios-hppa-5fdaa0346cb9d864ffff0e6fd2c2139c4a6b612f.zip seabios-hppa-5fdaa0346cb9d864ffff0e6fd2c2139c4a6b612f.tar.gz seabios-hppa-5fdaa0346cb9d864ffff0e6fd2c2139c4a6b612f.tar.bz2 |
Rename pci_find_class() to pci_find_classprog(), and add new functions.
New pci_find_class() searches by just class, not class and prog-if.
Add some new pci config space definitions.
Add inline functions for converting to/from bus/dev/fn to bdf to PCIDevice.
Diffstat (limited to 'src')
-rw-r--r-- | src/pci.c | 30 | ||||
-rw-r--r-- | src/pci.h | 26 | ||||
-rw-r--r-- | src/pcibios.c | 2 |
3 files changed, 50 insertions, 8 deletions
@@ -60,7 +60,7 @@ pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev) 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) { @@ -75,15 +75,39 @@ pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev) 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--; @@ -8,12 +8,22 @@ typedef struct PCIDevice { 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); @@ -23,7 +33,8 @@ u16 pci_config_readw(PCIDevice d, u32 addr); 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(); @@ -38,7 +49,14 @@ 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 */ diff --git a/src/pcibios.c b/src/pcibios.c index 4e29a43..b189f0b 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -49,7 +49,7 @@ static void handle_1ab103(struct bregs *regs) { PCIDevice d; - int ret = pci_find_class(regs->ecx, regs->si, &d); + int ret = pci_find_classprog(regs->ecx, regs->si, &d); if (ret) { set_code_fail(regs, RET_DEVICE_NOT_FOUND); return; |