File indexing completed on 2025-05-11 08:24:05
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
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 #include <rtems/pci.h>
0062 #include <rtems/bspIo.h>
0063 #include <inttypes.h>
0064 #include <stdio.h>
0065
0066
0067
0068
0069 void pci_dump(FILE *f);
0070
0071
0072
0073
0074
0075 #define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
0076 #define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
0077 #define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
0078 #define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
0079
0080
0081
0082
0083 typedef int (*pci_scan_helper_t)(
0084 int bus,
0085 int dev,
0086 int fun,
0087 void *uarg
0088 );
0089
0090
0091
0092
0093 static uint32_t pci_scan(
0094 uint32_t handle,
0095 pci_scan_helper_t helper,
0096 void *uarg
0097 );
0098
0099 typedef struct {
0100 uint16_t vendor_id;
0101 uint16_t device_id;
0102 int instance;
0103 uint8_t bus;
0104 uint8_t device;
0105 uint8_t function;
0106 } pci_scan_arg_t;
0107
0108 static int find_dev_helper(
0109 int bus,
0110 int device,
0111 int function,
0112 void *uarg
0113 )
0114 {
0115 pci_scan_arg_t *scan = uarg;
0116 uint16_t vendor_tmp;
0117 uint16_t device_tmp;
0118
0119 pci_read_config_word(bus, device, function, PCI_VENDOR_ID, &vendor_tmp);
0120 if (scan->vendor_id == vendor_tmp) {
0121 pci_read_config_word(bus, device, function, PCI_DEVICE_ID, &device_tmp);
0122 if (scan->device_id == device_tmp && scan->instance-- == 0) {
0123 scan->bus = bus;
0124 scan->device = device;
0125 scan->function = function;
0126
0127 return 1;
0128 }
0129 }
0130 return 0;
0131 }
0132
0133 int pci_find_device(
0134 uint16_t vendorid,
0135 uint16_t deviceid,
0136 int instance,
0137 int *bus,
0138 int *device,
0139 int *function
0140 )
0141 {
0142 pci_scan_arg_t scan;
0143
0144 scan.instance = instance;
0145 scan.vendor_id = vendorid;
0146 scan.device_id = deviceid;
0147
0148 if ( pci_scan(0, find_dev_helper, (void*)&scan) != 0 ) {
0149 *bus = scan.bus;
0150 *device = scan.device;
0151 *function = scan.function;
0152 return 0;
0153 }
0154 return -1;
0155 }
0156
0157 static int dump_dev_helper(
0158 int bus,
0159 int device,
0160 int function,
0161 void *arg
0162 )
0163 {
0164 uint16_t vendor_id;
0165 uint16_t device_id;
0166 uint16_t cmd;
0167 uint16_t status;
0168 uint32_t base0;
0169 uint32_t base1;
0170 uint8_t irq_pin;
0171 uint8_t int_line;
0172 FILE *fp = arg;
0173
0174 pci_read_config_word (bus, device, function, PCI_VENDOR_ID, &vendor_id);
0175 pci_read_config_word (bus, device, function, PCI_DEVICE_ID, &device_id);
0176 pci_read_config_word (bus, device, function, PCI_COMMAND, &cmd);
0177 pci_read_config_word (bus, device, function, PCI_STATUS, &status);
0178 pci_read_config_dword(bus, device, function, PCI_BASE_ADDRESS_0, &base0);
0179 pci_read_config_dword(bus, device, function, PCI_BASE_ADDRESS_1, &base1);
0180 pci_read_config_byte (bus, device, function, PCI_INTERRUPT_PIN, &irq_pin);
0181 pci_read_config_byte (bus, device, function, PCI_INTERRUPT_LINE, &int_line);
0182
0183 fprintf(
0184 fp,
0185 "%3d:0x%02x:%d 0x%04x:0x%04x 0x%04x 0x%04x 0x%08" PRIx32 " 0x%08" PRIx32 " %d %3d(0x%02x)\n",
0186 bus,
0187 device,
0188 function,
0189 vendor_id,
0190 device_id,
0191 cmd,
0192 status,
0193 base0,
0194 base1,
0195 irq_pin,
0196 int_line,
0197 int_line
0198 );
0199 return 0;
0200 }
0201
0202 void pci_dump(
0203 FILE *fp
0204 )
0205 {
0206 if ( !fp )
0207 fp = stdout;
0208 fprintf(
0209 fp,
0210 "BUS:SLOT:FUN VENDOR:DEV_ID CMD STAT BASE_ADDR0 BASE_ADDR1 INTn IRQ_LINE\n"
0211 );
0212 pci_scan(0, dump_dev_helper, fp);
0213 }
0214
0215 static uint32_t pci_scan(
0216 uint32_t handle,
0217 pci_scan_helper_t helper,
0218 void *arg
0219 )
0220 {
0221 uint32_t vendor;
0222 uint8_t bus;
0223 uint8_t dev;
0224 uint8_t fun;
0225 uint8_t hd;
0226
0227 bus = PCIB_DEVSIG_BUS( (unsigned long)handle );
0228 dev = PCIB_DEVSIG_DEV( (unsigned long)handle );
0229 fun = PCIB_DEVSIG_FUNC( (unsigned long)handle );
0230
0231 hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1;
0232
0233 for (; bus<pci_bus_count(); bus++, dev=0) {
0234 for (; dev<PCI_MAX_DEVICES; dev++, fun=0) {
0235 for (; fun<hd; fun++) {
0236
0237
0238
0239 if ((PCI_MAX_DEVICES-1 == dev) && (PCI_MAX_FUNCTIONS-1 == fun) )
0240 break;
0241
0242 (void)pci_read_config_dword(bus, dev, 0, PCI_VENDOR_ID, &vendor);
0243 if (PCI_INVALID_VENDORDEVICEID == vendor)
0244 continue;
0245
0246 if ( fun == 0 ) {
0247 pci_read_config_byte(bus,dev, 0, PCI_HEADER_TYPE, &hd);
0248 hd = (hd & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
0249 }
0250
0251 (void)pci_read_config_dword(bus, dev, fun, PCI_VENDOR_ID, &vendor);
0252 if (PCI_INVALID_VENDORDEVICEID == vendor)
0253 continue;
0254 #ifdef PCI_DEBUG
0255 fprintf(
0256 stderr,
0257 "pci_scan: found 0x%08" PRIx32 " at %d/x%02x/%d\n", vendor, bus, dev, fun
0258 );
0259 #endif
0260 if ( (*helper)(bus, dev, fun, arg) > 0 ) {
0261 if ( ++fun >= hd ) {
0262 fun = 0;
0263 if ( ++dev >= PCI_MAX_DEVICES ) {
0264 dev = 0;
0265 bus++;
0266 }
0267 }
0268 return PCIB_DEVSIG_MAKE(bus,dev,fun);
0269 }
0270 }
0271 }
0272 }
0273 return 0;
0274 }