File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include <inttypes.h>
0051 #include <bsp/pci.h>
0052 #include <rtems/bspIo.h>
0053 #include <stdio.h>
0054
0055
0056
0057
0058
0059
0060
0061 #define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
0062
0063
0064
0065
0066 #define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
0067 #define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
0068 #define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
0069
0070 typedef struct {
0071 unsigned short vid,did;
0072 int inst;
0073 } fd_arg;
0074
0075 static int
0076 find_dev_cb(
0077 int bus,
0078 int dev,
0079 int fun,
0080 void *uarg
0081 ) {
0082 fd_arg *a = uarg;
0083 unsigned short s;
0084
0085 pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
0086 if (a->vid == s) {
0087 pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
0088 if (a->did == s && 0 == a->inst-- ) {
0089 a->inst = PCIB_DEVSIG_MAKE( bus, dev, fun );
0090 return 1;
0091 }
0092 }
0093 return 0;
0094 }
0095
0096 int
0097 pci_find_device(
0098 unsigned short vendorid,
0099 unsigned short deviceid,
0100 int instance,
0101 int *pbus,
0102 int *pdev,
0103 int *pfun
0104 ) {
0105 fd_arg a;
0106 void *h;
0107 a.vid = vendorid;
0108 a.did = deviceid;
0109 a.inst = instance;
0110
0111 if ( (h = BSP_pciScan(0, find_dev_cb, (void*)&a)) ) {
0112 *pbus = PCIB_DEVSIG_BUS( a.inst );
0113 *pdev = PCIB_DEVSIG_DEV( a.inst );
0114 *pfun = PCIB_DEVSIG_FUNC( a.inst );
0115 return 0;
0116 }
0117 return -1;
0118 }
0119
0120 static int
0121 dump_dev_cb(
0122 int bus,
0123 int dev,
0124 int fun,
0125 void *uarg
0126 )
0127 {
0128 uint16_t vi,di;
0129 uint16_t cd,st;
0130 uint32_t b1,b2;
0131 uint8_t il,ip;
0132 FILE *f = uarg;
0133
0134 pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID, &vi);
0135 pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID, &di);
0136 pci_read_config_word (bus, dev, fun, PCI_COMMAND, &cd);
0137 pci_read_config_word (bus, dev, fun, PCI_STATUS, &st);
0138 pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1);
0139 pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2);
0140 pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il);
0141 pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN, &ip);
0142
0143
0144 fprintf(f,"%3d:0x%02x:%d 0x%04x-0x%04x: 0x%04x 0x%04x 0x%08" PRIx32 " 0x%08" PRIx32 " %d -> %3d (=0x%02x)\n",
0145 bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il);
0146 return 0;
0147 }
0148
0149 void
0150 BSP_pciConfigDump(FILE *f)
0151 {
0152 if ( !f )
0153 f = stdout;
0154 fprintf(f,"BUS:SLOT:FUN VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n");
0155 BSP_pciScan(0, dump_dev_cb, f);
0156 }
0157
0158 BSP_PciScanHandle
0159 BSP_pciScan(
0160 BSP_PciScanHandle handle,
0161 BSP_PciScannerCb cb,
0162 void *uarg
0163 ) {
0164
0165 uint32_t d;
0166 unsigned char bus,dev,fun,hd;
0167
0168 bus = PCIB_DEVSIG_BUS( (unsigned long)handle );
0169 dev = PCIB_DEVSIG_DEV( (unsigned long)handle );
0170 fun = PCIB_DEVSIG_FUNC( (unsigned long)handle );
0171
0172 hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1;
0173
0174 for (; bus<pci_bus_count(); bus++, dev=0) {
0175 for (; dev<PCI_MAX_DEVICES; dev++, fun=0) {
0176 for (; fun<hd; fun++) {
0177
0178
0179
0180 if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
0181 break;
0182
0183 (void)pci_read_config_dword(bus,dev,0,PCI_VENDOR_ID,&d);
0184 if (PCI_INVALID_VENDORDEVICEID == d)
0185 continue;
0186
0187 if ( 0 == fun ) {
0188 pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
0189 hd = (hd & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
0190 }
0191
0192 (void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
0193 if (PCI_INVALID_VENDORDEVICEID == d)
0194 continue;
0195 #ifdef PCI_DEBUG
0196 printk("BSP_pciScan: found 0x%08x at %d/x%02x/%d\n",d,bus,dev,fun);
0197 #endif
0198 if ( cb(bus,dev,fun,uarg) > 0 ) {
0199 if ( ++fun >= hd ) {
0200 fun = 0;
0201 if ( ++dev >= PCI_MAX_DEVICES ) {
0202 dev = 0;
0203 bus++;
0204 }
0205 }
0206 return (void*) PCIB_DEVSIG_MAKE(bus,dev,fun);
0207 }
0208 }
0209 }
0210 }
0211 return 0;
0212 }