2 #include "libopenbios/bindings.h"
3 #include "drivers/pci.h"
4 #include "libc/vsprintf.h"
6 #include "pci_database.h"
8 /* PCI devices database */
10 typedef struct pci_class_t pci_class_t;
11 typedef struct pci_subclass_t pci_subclass_t;
12 typedef struct pci_iface_t pci_iface_t;
18 const pci_dev_t *devices;
19 int (*config_cb)(const pci_config_t *config);
23 struct pci_subclass_t {
27 const pci_dev_t *devices;
28 const pci_iface_t *iface;
29 int (*config_cb)(const pci_config_t *config);
36 const pci_subclass_t *subc;
39 /* Current machine description */
41 static const pci_subclass_t undef_subclass[] = {
43 0xFF, NULL, NULL, NULL, NULL,
48 static const pci_dev_t scsi_devices[] = {
50 /* Virtio-block controller */
51 PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_BLOCK,
52 NULL, "virtio-blk", NULL,
53 "pci1af4,1001\0pci1af4,1001\0pciclass,01018f\0",
59 NULL, NULL, NULL, NULL,
65 static const pci_dev_t ide_devices[] = {
67 PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, /* CMD646 IDE controller */
68 "pci-ide", "pci-ata", NULL,
69 "pci1095,646\0pci1095,646\0pciclass,01018f\0",
75 NULL, NULL, NULL, NULL,
81 static const pci_subclass_t mass_subclass[] = {
83 PCI_SUBCLASS_STORAGE_SCSI, "SCSI bus controller",
84 "scsi", scsi_devices, NULL,
88 PCI_SUBCLASS_STORAGE_IDE, "IDE controller",
89 "ide", ide_devices, NULL,
93 PCI_SUBCLASS_STORAGE_FLOPPY, "Floppy disk controller",
98 PCI_SUBCLASS_STORAGE_IPI, "IPI bus controller",
103 PCI_SUBCLASS_STORAGE_RAID, "RAID controller",
108 PCI_SUBCLASS_STORAGE_ATA, "ATA controller",
113 PCI_SUBCLASS_STORAGE_OTHER, "misc mass-storage controller",
124 static const pci_dev_t eth_devices[] = {
126 PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_RTL8029,
127 NULL, "NE2000", "NE2000 PCI", NULL,
132 /* Virtio-network controller */
133 PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_NET,
134 NULL, "virtio-net", NULL,
135 "pci1af4,1000\0pci1af4,1000\0pciclass,020000\0",
141 NULL, NULL, NULL, NULL,
147 static const pci_subclass_t net_subclass[] = {
149 PCI_SUBCLASS_NETWORK_ETHERNET, "ethernet controller",
150 NULL, eth_devices, NULL,
151 eth_config_cb, "ethernet",
154 PCI_SUBCLASS_NETWORK_TOKEN_RING, "token ring controller",
159 PCI_SUBCLASS_NETWORK_FDDI, "FDDI controller",
164 PCI_SUBCLASS_NETWORK_ATM, "ATM controller",
169 PCI_SUBCLASS_NETWORK_ISDN, "ISDN controller",
174 PCI_SUBCLASS_NETWORK_WORDFIP, "WordFip controller",
179 PCI_SUBCLASS_NETWORK_PICMG214, "PICMG 2.14 controller",
184 PCI_SUBCLASS_NETWORK_OTHER, "misc network controller",
195 static const pci_dev_t vga_devices[] = {
197 PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
198 NULL, "ATY", "ATY Rage128", "VGA\0",
203 PCI_VENDOR_ID_QEMU, PCI_DEVICE_ID_QEMU_VGA,
204 NULL, "QEMU,VGA", "Qemu VGA", "VGA\0",
210 NULL, NULL, NULL, NULL,
216 static const struct pci_iface_t vga_iface[] = {
218 0x00, "VGA controller", NULL,
219 vga_devices, &vga_config_cb, NULL,
222 0x01, "8514 compatible controller", NULL,
231 static const pci_subclass_t displ_subclass[] = {
233 PCI_SUBCLASS_DISPLAY_VGA, "display controller",
234 NULL, NULL, vga_iface,
238 PCI_SUBCLASS_DISPLAY_XGA, "XGA display controller",
243 PCI_SUBCLASS_DISPLAY_3D, "3D display controller",
248 PCI_SUBCLASS_DISPLAY_OTHER, "misc display controller",
259 static const pci_subclass_t media_subclass[] = {
261 PCI_SUBCLASS_MULTIMEDIA_VIDEO, "video device",
266 PCI_SUBCLASS_MULTIMEDIA_AUDIO, "audio device",
271 PCI_SUBCLASS_MULTIMEDIA_PHONE, "computer telephony device",
276 PCI_SUBCLASS_MULTIMEDIA_OTHER, "misc multimedia device",
287 static const pci_subclass_t mem_subclass[] = {
289 PCI_SUBCLASS_MEMORY_RAM, "RAM controller",
294 PCI_SUBCLASS_MEMORY_FLASH, "flash controller",
306 static const pci_dev_t hbrg_devices[] = {
308 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U3_AGP, NULL,
309 "pci", "AAPL,UniNorth", "u3-agp\0",
311 host_config_cb, NULL,
314 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_AGP, NULL,
315 "pci", "AAPL,UniNorth", "uni-north\0",
317 host_config_cb, NULL,
320 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI, NULL,
321 "pci", "AAPL,UniNorth", "uni-north\0",
323 host_config_cb, NULL,
326 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI, NULL,
327 "pci", "AAPL,UniNorth", "uni-north\0",
332 PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_MPC106, "pci",
333 "pci", "MOT,MPC106", "grackle\0",
338 PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_RAVEN, NULL,
339 "pci", "PREP Host PCI Bridge - Motorola Raven", NULL,
341 host_config_cb, NULL,
344 PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SABRE, NULL,
345 "pci", "SUNW,sabre", "pci108e,a000\0pciclass,0\0",
347 sabre_config_cb, NULL,
351 NULL, NULL, NULL, NULL,
357 static const pci_dev_t PCIbrg_devices[] = {
359 PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154, NULL,
360 "pci-bridge", "DEV,21154", "DEV,21154\0pci-bridge\0",
362 bridge_config_cb, NULL,
365 PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA, NULL,
366 "pci", "SUNW,simba", "pci108e,5000\0pciclass,060400\0",
368 bridge_config_cb, NULL,
372 NULL, NULL, NULL, NULL,
378 static const pci_dev_t miscbrg_devices[] = {
380 PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL,
381 "ebus", "ebus", "pci108e,1000\0pciclass,068000\0",
383 ebus_config_cb, NULL,
387 NULL, NULL, NULL, NULL,
393 static const pci_dev_t isabrg_devices[] = {
395 PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, NULL,
396 "isa", "isa", "pci8086,484\0",
398 i82378_config_cb, NULL,
402 NULL, NULL, NULL, NULL,
408 static const pci_subclass_t bridg_subclass[] = {
410 PCI_SUBCLASS_BRIDGE_HOST, "PCI host bridge",
411 "pci", hbrg_devices, NULL,
415 PCI_SUBCLASS_BRIDGE_ISA, "ISA bridge",
416 "isa", isabrg_devices, NULL,
420 PCI_SUBCLASS_BRIDGE_EISA, "EISA bridge",
425 PCI_SUBCLASS_BRIDGE_MC, "MCA bridge",
430 PCI_SUBCLASS_BRIDGE_PCI, "PCI-to-PCI bridge",
431 "pci", PCIbrg_devices, NULL,
435 PCI_SUBCLASS_BRIDGE_PCMCIA, "PCMCIA bridge",
440 PCI_SUBCLASS_BRIDGE_NUBUS, "NUBUS bridge",
445 PCI_SUBCLASS_BRIDGE_CARDBUS, "cardbus bridge",
450 PCI_SUBCLASS_BRIDGE_RACEWAY, "raceway bridge",
455 PCI_SUBCLASS_BRIDGE_PCI_SEMITP, "semi-transparent PCI-to-PCI bridge",
460 PCI_SUBCLASS_BRIDGE_IB_PCI, "infiniband-to-PCI bridge",
465 PCI_SUBCLASS_BRIDGE_OTHER, "misc PCI bridge",
466 NULL, miscbrg_devices, NULL,
476 static const pci_iface_t serial_iface[] = {
478 0x00, "XT serial controller", NULL,
482 0x01, "16450 serial controller", NULL,
486 0x02, "16550 serial controller", NULL,
490 0x03, "16650 serial controller", NULL,
494 0x04, "16750 serial controller", NULL,
498 0x05, "16850 serial controller", NULL,
502 0x06, "16950 serial controller", NULL,
511 static const pci_iface_t par_iface[] = {
513 0x00, "parallel port", NULL,
517 0x01, "bi-directional parallel port", NULL,
521 0x02, "ECP 1.x parallel port", NULL,
525 0x03, "IEEE 1284 controller", NULL,
529 0xFE, "IEEE 1284 device", NULL,
538 static const pci_iface_t modem_iface[] = {
540 0x00, "generic modem", NULL,
544 0x01, "Hayes 16450 modem", NULL,
548 0x02, "Hayes 16550 modem", NULL,
552 0x03, "Hayes 16650 modem", NULL,
556 0x04, "Hayes 16750 modem", NULL,
565 static const pci_subclass_t comm_subclass[] = {
567 PCI_SUBCLASS_COMMUNICATION_SERIAL, "serial controller",
568 NULL, NULL, serial_iface,
572 PCI_SUBCLASS_COMMUNICATION_PARALLEL, "parallel port",
573 NULL, NULL, par_iface,
577 PCI_SUBCLASS_COMMUNICATION_MULTISERIAL, "multiport serial controller",
582 PCI_SUBCLASS_COMMUNICATION_MODEM, "modem",
583 NULL, NULL, modem_iface,
587 PCI_SUBCLASS_COMMUNICATION_GPIB, "GPIB controller",
592 PCI_SUBCLASS_COMMUNICATION_SC, "smart card",
597 PCI_SUBCLASS_COMMUNICATION_OTHER, "misc communication device",
608 static const pci_iface_t pic_iface[] = {
610 0x00, "8259 PIC", NULL,
614 0x01, "ISA PIC", NULL,
618 0x02, "EISA PIC", NULL,
622 0x10, "I/O APIC", NULL,
626 0x20, "I/O APIC", NULL,
635 static const pci_iface_t dma_iface[] = {
637 0x00, "8237 DMA controller", NULL,
641 0x01, "ISA DMA controller", NULL,
645 0x02, "EISA DMA controller", NULL,
654 static const pci_iface_t tmr_iface[] = {
656 0x00, "8254 system timer", NULL,
660 0x01, "ISA system timer", NULL,
664 0x02, "EISA system timer", NULL,
673 static const pci_iface_t rtc_iface[] = {
675 0x00, "generic RTC controller", NULL,
679 0x01, "ISA RTC controller", NULL,
688 static const pci_dev_t sys_devices[] = {
689 /* IBM MPIC controller */
691 PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC,
692 "open-pic", "MPIC", NULL, "chrp,open-pic\0",
696 /* IBM MPIC2 controller */
698 PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC2,
699 "open-pic", "MPIC2", NULL, "chrp,open-pic\0",
705 NULL, NULL, NULL, NULL,
711 static const pci_subclass_t sys_subclass[] = {
713 PCI_SUBCLASS_SYSTEM_PIC, "PIC",
714 NULL, NULL, pic_iface,
718 PCI_SUBCLASS_SYSTEM_DMA, "DMA controller",
719 NULL, NULL, dma_iface,
723 PCI_SUBCLASS_SYSTEM_TIMER, "system timer",
724 NULL, NULL, tmr_iface,
728 PCI_SUBCLASS_SYSTEM_RTC, "RTC controller",
729 NULL, NULL, rtc_iface,
733 PCI_SUBCLASS_SYSTEM_PCI_HOTPLUG, "PCI hotplug controller",
738 PCI_SUBCLASS_SYSTEM_OTHER, "misc system peripheral",
739 NULL, sys_devices, NULL,
749 static const pci_subclass_t inp_subclass[] = {
751 PCI_SUBCLASS_INPUT_KEYBOARD, "keyboard controller",
756 PCI_SUBCLASS_INPUT_PEN, "digitizer",
761 PCI_SUBCLASS_INPUT_MOUSE, "mouse controller",
766 PCI_SUBCLASS_INPUT_SCANNER, "scanner controller",
771 PCI_SUBCLASS_INPUT_GAMEPORT, "gameport controller",
776 PCI_SUBCLASS_INPUT_OTHER, "misc input device",
787 static const pci_subclass_t dock_subclass[] = {
789 PCI_SUBCLASS_DOCKING_GENERIC, "generic docking station",
794 PCI_SUBCLASS_DOCKING_OTHER, "misc docking station",
805 static const pci_subclass_t cpu_subclass[] = {
807 PCI_SUBCLASS_PROCESSOR_386, "i386 processor",
812 PCI_SUBCLASS_PROCESSOR_486, "i486 processor",
817 PCI_SUBCLASS_PROCESSOR_PENTIUM, "pentium processor",
822 PCI_SUBCLASS_PROCESSOR_ALPHA, "alpha processor",
827 PCI_SUBCLASS_PROCESSOR_POWERPC, "PowerPC processor",
832 PCI_SUBCLASS_PROCESSOR_MIPS, "MIPS processor",
837 PCI_SUBCLASS_PROCESSOR_CO, "co-processor",
848 static const pci_dev_t usb_devices[] = {
849 #if defined(CONFIG_QEMU)
851 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_KEYL_USB,
853 "pci106b,3f\0pciclass,0c0310\0",
860 NULL, NULL, NULL, NULL,
866 static const pci_iface_t usb_iface[] = {
868 0x00, "UHCI USB controller", NULL,
872 0x10, "OHCI USB controller", NULL,
873 usb_devices, &usb_ohci_config_cb, NULL,
876 0x20, "EHCI USB controller", NULL,
880 0x80, "misc USB controller", NULL,
884 0xFE, "USB device", NULL,
893 static const pci_iface_t ipmi_iface[] = {
895 0x00, "IPMI SMIC interface", NULL,
899 0x01, "IPMI keyboard interface", NULL,
903 0x02, "IPMI block transfer interface", NULL,
912 static const pci_subclass_t ser_subclass[] = {
914 PCI_SUBCLASS_SERIAL_FIREWIRE, "Firewire bus controller",
915 "ieee1394", NULL, NULL,
919 PCI_SUBCLASS_SERIAL_ACCESS, "ACCESS bus controller",
924 PCI_SUBCLASS_SERIAL_SSA, "SSA controller",
929 PCI_SUBCLASS_SERIAL_USB, "USB controller",
930 "usb", NULL, usb_iface,
934 PCI_SUBCLASS_SERIAL_FIBER, "fibre channel controller",
939 PCI_SUBCLASS_SERIAL_SMBUS, "SMBus controller",
944 PCI_SUBCLASS_SERIAL_IB, "InfiniBand controller",
949 PCI_SUBCLASS_SERIAL_IPMI, "IPMI interface",
950 NULL, NULL, ipmi_iface,
954 PCI_SUBCLASS_SERIAL_SERCOS, "SERCOS controller",
955 NULL, NULL, ipmi_iface,
959 PCI_SUBCLASS_SERIAL_CANBUS, "CANbus controller",
960 NULL, NULL, ipmi_iface,
970 static const pci_subclass_t wrl_subclass[] = {
972 PCI_SUBCLASS_WIRELESS_IRDA, "IRDA controller",
977 PCI_SUBCLASS_WIRELESS_CIR, "consumer IR controller",
982 PCI_SUBCLASS_WIRELESS_RF_CONTROLLER, "RF controller",
987 PCI_SUBCLASS_WIRELESS_BLUETOOTH, "bluetooth controller",
992 PCI_SUBCLASS_WIRELESS_BROADBAND, "broadband controller",
997 PCI_SUBCLASS_WIRELESS_OTHER, "misc wireless controller",
1008 static const pci_subclass_t sat_subclass[] = {
1010 PCI_SUBCLASS_SATELLITE_TV, "satellite TV controller",
1015 PCI_SUBCLASS_SATELLITE_AUDIO, "satellite audio controller",
1020 PCI_SUBCLASS_SATELLITE_VOICE, "satellite voice controller",
1025 PCI_SUBCLASS_SATELLITE_DATA, "satellite data controller",
1036 static const pci_subclass_t crypt_subclass[] = {
1038 PCI_SUBCLASS_CRYPT_NETWORK, "cryptographic network controller",
1043 PCI_SUBCLASS_CRYPT_ENTERTAINMENT,
1044 "cryptographic entertainment controller",
1049 PCI_SUBCLASS_CRYPT_OTHER, "misc cryptographic controller",
1060 static const pci_subclass_t spc_subclass[] = {
1062 PCI_SUBCLASS_SP_DPIO, "DPIO module",
1067 PCI_SUBCLASS_SP_PERF, "performances counters",
1072 PCI_SUBCLASS_SP_SYNCH, "communication synchronisation",
1077 PCI_SUBCLASS_SP_MANAGEMENT, "management card",
1082 PCI_SUBCLASS_SP_OTHER, "misc signal processing controller",
1093 static const pci_class_t pci_classes[] = {
1095 { "undefined", NULL, undef_subclass, },
1097 { "mass-storage controller", NULL, mass_subclass, },
1099 { "network controller", "network", net_subclass, },
1101 { "display controller", "display", displ_subclass, },
1103 { "multimedia device", NULL, media_subclass, },
1105 { "memory controller", "memory-controller", mem_subclass, },
1107 { "PCI bridge", NULL, bridg_subclass, },
1109 { "communication device", NULL, comm_subclass,},
1111 { "system peripheral", NULL, sys_subclass, },
1113 { "input device", NULL, inp_subclass, },
1115 { "docking station", NULL, dock_subclass, },
1117 { "processor", NULL, cpu_subclass, },
1119 { "serial bus controller", NULL, ser_subclass, },
1121 { "wireless controller", NULL, wrl_subclass, },
1123 { "intelligent I/O controller", NULL, NULL, },
1125 { "satellite communication controller", NULL, sat_subclass, },
1127 { "cryptographic controller", NULL, crypt_subclass, },
1129 { "signal processing controller", NULL, spc_subclass, },
1132 static const pci_dev_t misc_pci[] = {
1133 /* Heathrow Mac I/O */
1135 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1201,
1136 "mac-io", "mac-io", "AAPL,343S1201", "heathrow\0",
1138 &macio_heathrow_config_cb, NULL,
1140 /* Paddington Mac I/O */
1142 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1211,
1143 "mac-io", "mac-io", "AAPL,343S1211", "paddington\0heathrow\0",
1145 &macio_heathrow_config_cb, NULL,
1147 /* KeyLargo Mac I/O */
1149 PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_KEYL,
1150 "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo\0",
1152 &macio_keylargo_config_cb, NULL,
1156 NULL, NULL, NULL, NULL,
1162 const pci_dev_t *pci_find_device (uint8_t class, uint8_t subclass,
1163 uint8_t iface, uint16_t vendor,
1166 int (*config_cb)(const pci_config_t *config);
1167 const pci_class_t *pclass;
1168 const pci_subclass_t *psubclass;
1169 const pci_iface_t *piface;
1170 const pci_dev_t *dev;
1171 const void *private;
1173 const char *name, *type;
1180 if (class == 0x00 && subclass == 0x01) {
1181 /* Special hack for old style VGA devices */
1184 } else if (class == 0xFF) {
1185 /* Special case for misc devices */
1189 if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
1190 name = "invalid PCI device";
1194 pclass = &pci_classes[class];
1195 name = pclass->name;
1196 type = pclass->type;
1197 for (psubclass = pclass->subc; ; psubclass++) {
1198 if (psubclass->subclass == 0xFF)
1200 if (psubclass->subclass == subclass) {
1201 if (psubclass->name != NULL)
1202 name = psubclass->name;
1203 if (psubclass->type != NULL)
1204 type = psubclass->type;
1205 if (psubclass->config_cb != NULL) {
1206 config_cb = psubclass->config_cb;
1208 if (psubclass->private != NULL)
1209 private = psubclass->private;
1210 if (psubclass->iface != NULL)
1212 dev = psubclass->devices;
1216 for (piface = psubclass->iface; ; piface++) {
1217 if (piface->iface == 0xFF) {
1218 dev = psubclass->devices;
1221 if (piface->iface == iface) {
1222 if (piface->name != NULL)
1223 name = piface->name;
1224 if (piface->type != NULL)
1225 type = piface->type;
1226 if (piface->config_cb != NULL) {
1227 config_cb = piface->config_cb;
1229 if (piface->private != NULL)
1230 private = piface->private;
1231 dev = piface->devices;
1239 if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) {
1242 if (dev->vendor == vendor && dev->product == product) {
1243 if (dev->name != NULL)
1245 if (dev->type != NULL)
1247 if (dev->config_cb != NULL) {
1248 config_cb = dev->config_cb;
1250 if (dev->private != NULL)
1251 private = dev->private;
1252 new = malloc(sizeof(pci_dev_t));
1255 new->vendor = vendor;
1256 new->product = product;
1259 new->model = dev->model;
1260 new->compat = dev->compat;
1261 new->acells = dev->acells;
1262 new->scells = dev->scells;
1263 new->icells = dev->icells;
1264 new->config_cb = config_cb;
1265 new->private = private;
1271 printk("Cannot manage '%s' PCI device type '%s':\n %x %x (%x %x %x)\n",
1272 name, type, vendor, product, class, subclass, iface);