File indexing completed on 2025-05-11 08:24:20
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 #include <inttypes.h>
0030 #include <stdio.h>
0031 #include <pci.h>
0032 #include <pci/access.h>
0033
0034
0035 #define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
0036 #define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
0037 #define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
0038 #define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
0039 #define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
0040 #define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
0041
0042 void pci_print_dev(pci_dev_t dev)
0043 {
0044 int maxbars, pos, romadrs;
0045 uint32_t tmp, tmp2, id;
0046 uint16_t irq;
0047 uint8_t irq_pin;
0048 char *str, *str2;
0049 uint32_t base, limit;
0050
0051 maxbars = 6;
0052 romadrs = 0x30;
0053 str = "";
0054 PCI_CFG_R32(dev, PCIR_REVID, &tmp);
0055 tmp >>= 16;
0056 if (tmp == PCID_PCI2PCI_BRIDGE) {
0057 maxbars = 2;
0058 romadrs = 0x38;
0059 str = "(BRIDGE)";
0060 }
0061
0062 PCI_CFG_R32(dev, PCIR_VENDOR, &id);
0063 printf("\nBus %x Slot %x function: %x [0x%x] %s\n",
0064 PCI_DEV_EXPAND(dev), dev, str);
0065 printf("\tVendor id: 0x%" PRIx32 ", device id: 0x%" PRIx32 "\n",
0066 id & 0xffff, id >> 16);
0067 if (maxbars == 2) {
0068 PCI_CFG_R32(dev, PCIR_PRIBUS_1, &tmp);
0069 printf("\tPrimary: %" PRIx32 " Secondary: %" PRIx32
0070 " Subordinate: %" PRIx32 "\n",
0071 tmp & 0xff, (tmp >> 8) & 0xff, (tmp >> 16) & 0xff);
0072 }
0073
0074 PCI_CFG_R16(dev, PCIR_INTLINE, &irq);
0075 irq_pin = irq >> 8;
0076 if ((irq_pin > 0) && (irq_pin < 5))
0077 printf("\tIRQ INT%c# LINE: %d\n",
0078 (irq_pin - 1) + 'A', (irq & 0xff));
0079
0080
0081 for (pos = 0; pos < maxbars; pos++) {
0082 PCI_CFG_R32(dev, PCIR_BAR(0) + pos*4, &tmp);
0083 PCI_CFG_W32(dev, PCIR_BAR(0) + pos*4, 0xffffffff);
0084 PCI_CFG_R32(dev, PCIR_BAR(0) + pos*4, &tmp2);
0085 PCI_CFG_W32(dev, PCIR_BAR(0) + pos*4, tmp);
0086
0087 if (tmp2 != 0 && tmp2 != 0xffffffff && ((tmp2 & 0x1) ||
0088 ((tmp2 & 0x6) == 0))) {
0089 uint32_t mask = ~0xf;
0090 if ((tmp2 & 0x1) == 1) {
0091
0092 mask = ~3;
0093 tmp2 = tmp2 | 0xffffff00;
0094 }
0095 tmp2 &= mask;
0096 tmp2 = ~tmp2+1;
0097 if (tmp2 < 0x1000) {
0098 str = "B";
0099 } else if (tmp2 < 0x100000) {
0100 str = "kB";
0101 tmp2 = tmp2 / 1024;
0102 } else {
0103 str = "MB";
0104 tmp2 = tmp2 / (1024*1024);
0105 }
0106 printf("\tBAR %d: %" PRIx32 " [%" PRIu32 "%s]\n",
0107 pos, tmp, tmp2, str);
0108 }
0109 }
0110
0111
0112 PCI_CFG_R32(dev, romadrs, &tmp);
0113 PCI_CFG_W32(dev, romadrs, 0xffffffff);
0114 PCI_CFG_R32(dev, romadrs, &tmp2);
0115 PCI_CFG_W32(dev, romadrs, tmp);
0116 if (tmp2 & 1) {
0117
0118 tmp2 &= PCIM_BIOS_ADDR_MASK;
0119 tmp2 = (~tmp2 + 1);
0120 if (tmp2 < 0x1000) {
0121 str = "B";
0122 } else if (tmp2 < 0x100000) {
0123 str = "kB";
0124 tmp2 = tmp2 / 1024;
0125 } else {
0126 str = "MB";
0127 tmp2 = tmp2 / (1024*1024);
0128 }
0129 str2 = tmp & 1 ? "ENABLED" : "DISABLED";
0130 printf("\tROM: %08" PRIx32 " [%" PRIu32 "%s] (%s)\n",
0131 tmp, tmp2, str, str2);
0132 }
0133
0134
0135 if (maxbars == 2) {
0136 tmp = 0;
0137 PCI_CFG_R32(dev, 0x1C, &tmp);
0138 if (tmp != 0) {
0139 base = (tmp & 0x00f0) << 8;
0140 limit = (tmp & 0xf000) | 0xfff;
0141 PCI_CFG_R32(dev, 0x30, &tmp);
0142 base |= (tmp & 0xffff) << 16;
0143 limit |= (tmp & 0xffff0000);
0144 str = "ENABLED";
0145 if (limit < base)
0146 str = "DISABLED";
0147 printf("\tI/O: BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
0148 PRIx32 " (%s)\n", base, limit, str);
0149 }
0150
0151 PCI_CFG_R32(dev, 0x20, &tmp);
0152 if (tmp != 0) {
0153 base = (tmp & 0xfff0) << 16;
0154 limit = (tmp & 0xfff00000) | 0xfffff;
0155 str = "ENABLED";
0156 if (limit < base)
0157 str = "DISABLED";
0158 printf("\tMEMIO: BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
0159 PRIx32 " (%s)\n", base, limit, str);
0160 }
0161
0162 PCI_CFG_R32(dev, 0x24, &tmp);
0163 if (tmp != 0) {
0164 base = (tmp & 0xfff0) << 16;
0165 limit = (tmp & 0xfff00000) | 0xfffff;
0166 str = "ENABLED";
0167 if (limit < base)
0168 str = "DISABLED";
0169 printf("\tMEM: BASE: 0x%08" PRIx32 ", LIMIT: 0x%08"
0170 PRIx32 " (%s)\n", base, limit, str);
0171 }
0172 }
0173 printf("\n");
0174 }
0175
0176 void pci_print_device(int bus, int slot, int function)
0177 {
0178 pci_print_dev(PCI_DEV(bus, slot, function));
0179 }
0180
0181 void pci_print(void)
0182 {
0183 int fail, bus, slot, func;
0184 pci_dev_t dev;
0185 uint8_t header;
0186 uint32_t id;
0187
0188 printf("\nPCI devices found and configured:\n");
0189 for (bus = 0; bus < pci_bus_count(); bus++) {
0190 for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
0191 for (func=0; func <= PCI_FUNCMAX; func++) {
0192
0193 dev = PCI_DEV(bus, slot, func);
0194 fail = PCI_CFG_R32(dev, PCIR_VENDOR, &id);
0195
0196 if (!fail && id != PCI_INVALID_VENDORDEVICEID && id != 0) {
0197 pci_print_dev(dev);
0198
0199
0200 if (func == 0) {
0201 PCI_CFG_R8(dev, PCIR_HDRTYPE, &header);
0202 if ((header & PCIM_MFDEV) == 0)
0203 break;
0204 }
0205 } else if (func == 0)
0206 break;
0207 }
0208 }
0209 }
0210 printf("\n");
0211 }