Warning, cross-references for /kernel/drivers/pci/pci.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "drivers/pci/pci.h"
0019 #include "drivers/pci/pcidb.h"
0020 #include "arch/i386.h"
0021 #include "util/printf.h"
0022 #include "smp/smp.h"
0023 #include "smp/apic.h"
0024 #include "kernel.h"
0025
0026 #define DEBUG_PCI
0027
0028 #ifdef DEBUG_PCI
0029 #define DLOG(fmt,...) DLOG_PREFIX("PCI",fmt,##__VA_ARGS__)
0030 #else
0031 #define DLOG(fmt,...) ;
0032 #endif
0033
0034
0035 #define READ(bus, slot, func, reg, type) \
0036 pci_read_##type (pci_addr (bus, slot, func, reg))
0037 #define WRITE(bus, slot, func, reg, type, val) \
0038 pci_write_##type (pci_addr (bus, slot, func, reg), val)
0039
0040
0041 bool
0042 pci_search_ven_table (uint32 vendor, PCI_VENTABLE* e)
0043 {
0044 uint32 i;
0045 for (i=0; i<PCI_VENTABLE_LEN; i++)
0046 if (PciVenTable[i].VenId == vendor) {
0047 *e = PciVenTable[i];
0048 return TRUE;
0049 }
0050 return FALSE;
0051 }
0052
0053 bool
0054 pci_search_dev_table (uint32 vendor, uint32 dev, PCI_DEVTABLE* e)
0055 {
0056 uint32 i;
0057 for (i=0; i<PCI_DEVTABLE_LEN; i++)
0058 if (PciDevTable[i].VenId == vendor && PciDevTable[i].DevId == dev) {
0059 *e = PciDevTable[i];
0060 return TRUE;
0061 }
0062 return FALSE;
0063 }
0064
0065 bool
0066 pci_search_class_code_table (uint32 base, uint32 sub, uint32 prog,
0067 PCI_CLASSCODETABLE* e)
0068 {
0069 uint32 i;
0070 for (i=0; i<PCI_CLASSCODETABLE_LEN; i++)
0071 if (PciClassCodeTable[i].BaseClass == base &&
0072 PciClassCodeTable[i].SubClass == sub &&
0073 PciClassCodeTable[i].ProgIf == prog) {
0074 *e = PciClassCodeTable[i];
0075 return TRUE;
0076 }
0077 return FALSE;
0078 }
0079
0080
0081
0082 static pci_device devices[PCI_MAX_DEVICES];
0083 static uint32 num_devices = 0;
0084
0085
0086 static void
0087 probe (void)
0088 {
0089 uint32 bus, slot, func, i;
0090 #ifdef DEBUG_PCI
0091 PCI_VENTABLE ven;
0092 PCI_DEVTABLE dev;
0093 PCI_CLASSCODETABLE cc;
0094 #endif
0095
0096 for (bus=0; bus <= PCI_MAX_BUS_NUM; bus++)
0097 for (slot=0; slot <= PCI_MAX_DEV_NUM; slot++)
0098 for (func=0; func <= PCI_MAX_FUNC_NUM; func++)
0099 if (READ (bus, slot, func, 0x00, dword) != 0xFFFFFFFF) {
0100
0101 uint16 vendorID = READ (bus, slot, func, 0x00, word);
0102 uint16 deviceID = READ (bus, slot, func, 0x02, word);
0103 uint8 classID = READ (bus, slot, func, 0x0B, byte);
0104 uint8 subclID = READ (bus, slot, func, 0x0A, byte);
0105 uint8 prgIFID = READ (bus, slot, func, 0x09, byte);
0106 uint8 header = READ (bus, slot, func, 0x0E, byte);
0107
0108 for (i=0; i<0x10; i++)
0109 devices[num_devices].data[i] =
0110
0111
0112 READ (bus, slot, func, i<<2, dword);
0113
0114 #ifdef DEBUG_PCI
0115 DLOG ("%.02x:%.02x.%x", bus, slot, func);
0116 DLOG (" %.08x %.08x %.08x %.08x",
0117 devices[num_devices].data[0],
0118 devices[num_devices].data[1],
0119 devices[num_devices].data[2],
0120 devices[num_devices].data[3]);
0121 DLOG (" %.08x %.08x %.08x %.08x",
0122 devices[num_devices].data[4],
0123 devices[num_devices].data[5],
0124 devices[num_devices].data[6],
0125 devices[num_devices].data[7]);
0126 DLOG (" %.08x %.08x %.08x %.08x",
0127 devices[num_devices].data[8],
0128 devices[num_devices].data[9],
0129 devices[num_devices].data[10],
0130 devices[num_devices].data[11]);
0131 DLOG (" %.08x %.08x %.08x %.08x",
0132 devices[num_devices].data[12],
0133 devices[num_devices].data[13],
0134 devices[num_devices].data[14],
0135 devices[num_devices].data[15]);
0136 #endif
0137
0138 #ifdef DEBUG_PCI
0139 if (classID == 0x02 && subclID == 0)
0140 printf ("PCI ethernet: %x %x\n", vendorID, deviceID);
0141 if (classID == 0x0C && subclID == 0x03)
0142 printf ("USB host controller: %x %x\n", vendorID, deviceID);
0143 if (pci_search_ven_table (vendorID, &ven))
0144 DLOG (" %s (0x%x)", ven.VenFull, vendorID);
0145 else
0146 DLOG (" 0x%x", vendorID);
0147 if (pci_search_dev_table (vendorID, deviceID, &dev))
0148 DLOG (" %s (0x%x)", dev.ChipDesc, deviceID);
0149 else
0150 DLOG (" 0x%x", deviceID);
0151 if (pci_search_class_code_table (classID, subclID, prgIFID, &cc))
0152 DLOG (" %s (%x) %s (%x) %s (%x)",
0153 cc.BaseDesc, classID,
0154 cc.SubDesc, subclID,
0155 cc.ProgDesc, prgIFID);
0156 #endif
0157
0158 devices[num_devices].vendor = vendorID;
0159 devices[num_devices].device = deviceID;
0160 devices[num_devices].bus = bus;
0161 devices[num_devices].slot = slot;
0162 devices[num_devices].func = func;
0163 devices[num_devices].classcode = classID;
0164 devices[num_devices].subclass = subclID;
0165 devices[num_devices].progIF = prgIFID;
0166 devices[num_devices].headerType = header;
0167 devices[num_devices].index = num_devices;
0168
0169 if ((header & 0x7F) == 0) {
0170
0171 for (i=0; i<6; i++) {
0172 devices[num_devices].bar[i].raw = devices[num_devices].data[4+i];
0173 if (devices[num_devices].bar[i].raw != 0) {
0174
0175 uint32 raw = devices[num_devices].bar[i].raw;
0176 #ifdef DEBUG_PCI
0177 DLOG (" BAR%d raw: %p", i, devices[num_devices].bar[i].raw);
0178 #endif
0179
0180 WRITE (bus, slot, func, 0x10 + i*4, dword, ~0);
0181
0182 uint32 mask = READ (bus, slot, func, 0x10 + i*4, dword);
0183 #ifdef DEBUG_PCI
0184 DLOG (" BAR%d mask: %p", i, mask);
0185 #endif
0186 devices[num_devices].bar[i].mask = mask;
0187
0188 WRITE (bus, slot, func, 0x10 + i*4, dword, raw);
0189 }
0190 }
0191 }
0192 num_devices++;
0193 if (num_devices >= PCI_MAX_DEVICES)
0194 return;
0195 }
0196
0197 }
0198
0199 bool
0200 pci_init (void)
0201 {
0202 DLOG("init");
0203 probe ();
0204 return TRUE;
0205 }
0206
0207 bool
0208 pci_get_device (uint n, pci_device *dev)
0209 {
0210 if (n < num_devices) {
0211 memcpy (dev, &devices[n], sizeof (pci_device));
0212 return TRUE;
0213 }
0214 return FALSE;
0215 }
0216
0217 bool
0218 pci_find_device (uint16 vendor, uint16 device,
0219 uint8 classcode, uint8 subclass,
0220 uint start_index,
0221 uint* index)
0222 {
0223 #ifdef DEBUG_PCI
0224 DLOG ("find_device (%p,%p,%p,%p,%p) num_devices=%d",
0225 vendor, device, classcode, subclass, start_index, num_devices);
0226 #endif
0227 uint i;
0228 for (i=start_index; i<num_devices; i++) {
0229 if ((vendor == 0xFFFF || vendor == devices[i].vendor) &&
0230 (device == 0xFFFF || device == devices[i].device) &&
0231 (classcode == 0xFF || classcode == devices[i].classcode) &&
0232 (subclass == 0xFF || subclass == devices[i].subclass)) {
0233 *index = i;
0234 return TRUE;
0235 }
0236 }
0237 return FALSE;
0238 }
0239
0240 bool
0241 pci_decode_bar (uint index, uint bar_index,
0242 uint* mem_addr, uint* io_addr, uint* mask)
0243 {
0244 pci_device *dev;
0245 pci_bar *bar;
0246
0247 if (index >= num_devices) return FALSE;
0248
0249 dev = &devices[index];
0250
0251 if ((dev->headerType & 0x7F) == 0) {
0252
0253 if (bar_index >= 6) return FALSE;
0254
0255 bar = &dev->bar[bar_index];
0256
0257 DLOG ("pci_decode_bar (%d, %d) bar->raw=%p", index, bar_index, bar->raw);
0258 if (bar->raw & 0x1) {
0259
0260 if (io_addr)
0261 *io_addr = bar->ioBAR.ioPort << 2;
0262 if (mem_addr)
0263 *mem_addr = 0;
0264 if (mask)
0265 *mask = bar->mask;
0266 } else {
0267
0268 if (io_addr)
0269 *io_addr = 0;
0270 if (mem_addr)
0271 *mem_addr = bar->memBAR.baseAddr << 4;
0272 if (mask)
0273 *mask = bar->mask;
0274 }
0275
0276 return TRUE;
0277 }
0278
0279 return FALSE;
0280 }
0281
0282 bool
0283 pci_get_interrupt (uint index, uint* line, uint* pin)
0284 {
0285 if (index >= num_devices) return FALSE;
0286
0287 *line = devices[index].data[0xF] & 0xFF;
0288 *pin = (devices[index].data[0xF] >> 8) & 0xFF;
0289 return TRUE;
0290 }
0291
0292 #include "module/header.h"
0293
0294 static const struct module_ops mod_ops = {
0295 .init = pci_init
0296 };
0297
0298 DEF_MODULE (pci, "PCI bus driver", &mod_ops, {});
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309