Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / drivers / pci_database.c
1 #include "config.h"
2 #include "libopenbios/bindings.h"
3 #include "drivers/pci.h"
4 #include "libc/vsprintf.h"
5
6 #include "pci_database.h"
7
8 /* PCI devices database */
9
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;
13
14 struct pci_iface_t {
15     uint8_t iface;
16     const char *name;
17     const char *type;
18     const pci_dev_t *devices;
19     int (*config_cb)(const pci_config_t *config);
20     const void *private;
21 };
22
23 struct pci_subclass_t {
24     uint8_t subclass;
25     const char *name;
26     const char *type;
27     const pci_dev_t *devices;
28     const pci_iface_t *iface;
29     int (*config_cb)(const pci_config_t *config);
30     const void *private;
31 };
32
33 struct pci_class_t {
34     const char *name;
35     const char *type;
36     const pci_subclass_t *subc;
37 };
38
39 /* Current machine description */
40
41 static const pci_subclass_t undef_subclass[] = {
42     {
43         0xFF, NULL, NULL, NULL, NULL,
44         NULL, NULL,
45     },
46 };
47
48 static const pci_dev_t scsi_devices[] = {
49     {
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",
54         0, 0, 0,
55         NULL, NULL,
56     },
57     {
58         0xFFFF, 0xFFFF,
59         NULL, NULL, NULL, NULL,
60         -1, -1, -1,
61         NULL, NULL,
62     },
63 };
64
65 static const pci_dev_t ide_devices[] = {
66     {
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",
70         0, 0, 0,
71         ide_config_cb2, NULL,
72     },
73     {
74         0xFFFF, 0xFFFF,
75         NULL, NULL, NULL, NULL,
76         -1, -1, -1,
77         NULL, NULL,
78     },
79 };
80
81 static const pci_subclass_t mass_subclass[] = {
82     {
83         PCI_SUBCLASS_STORAGE_SCSI, "SCSI bus controller",
84         "scsi", scsi_devices, NULL,
85         NULL, NULL,
86     },
87     {
88         PCI_SUBCLASS_STORAGE_IDE, "IDE controller",
89         "ide", ide_devices, NULL,
90         NULL, NULL,
91     },
92     {
93         PCI_SUBCLASS_STORAGE_FLOPPY, "Floppy disk controller",
94         NULL, NULL, NULL,
95         NULL, NULL,
96     },
97     {
98         PCI_SUBCLASS_STORAGE_IPI, "IPI bus controller",
99         NULL, NULL, NULL,
100         NULL, NULL,
101     },
102     {
103         PCI_SUBCLASS_STORAGE_RAID, "RAID controller",
104         NULL, NULL, NULL,
105         NULL, NULL,
106     },
107     {
108         PCI_SUBCLASS_STORAGE_ATA, "ATA controller",
109         "ata", NULL, NULL,
110         NULL, NULL,
111     },
112     {
113         PCI_SUBCLASS_STORAGE_OTHER, "misc mass-storage controller",
114         NULL, NULL, NULL,
115         NULL, NULL,
116     },
117     {
118         0xFF, NULL,
119         NULL, NULL, NULL,
120         NULL, NULL,
121     },
122 };
123
124 static const pci_dev_t eth_devices[] = {
125     {
126         PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_RTL8029,
127         NULL, "NE2000",   "NE2000 PCI",  NULL,
128         0, 0, 0,
129         NULL, "ethernet",
130     },
131     {
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",
136         0, 0, 0,
137         NULL, NULL,
138     },
139     {
140         0xFFFF, 0xFFFF,
141         NULL, NULL, NULL, NULL,
142         -1, -1, -1,
143         NULL, NULL,
144     },
145 };
146
147 static const pci_subclass_t net_subclass[] = {
148     {
149         PCI_SUBCLASS_NETWORK_ETHERNET, "ethernet controller",
150         NULL, eth_devices, NULL,
151         eth_config_cb, "ethernet",
152     },
153     {
154         PCI_SUBCLASS_NETWORK_TOKEN_RING, "token ring controller",
155         NULL, NULL, NULL,
156         NULL, NULL,
157     },
158     {
159         PCI_SUBCLASS_NETWORK_FDDI, "FDDI controller",
160         NULL, NULL, NULL,
161         NULL, NULL,
162     },
163     {
164         PCI_SUBCLASS_NETWORK_ATM, "ATM controller",
165         NULL, NULL, NULL,
166         NULL, NULL,
167     },
168     {
169         PCI_SUBCLASS_NETWORK_ISDN, "ISDN controller",
170         NULL, NULL, NULL,
171         NULL, NULL,
172     },
173     {
174         PCI_SUBCLASS_NETWORK_WORDFIP, "WordFip controller",
175         NULL, NULL, NULL,
176         NULL, NULL,
177     },
178     {
179         PCI_SUBCLASS_NETWORK_PICMG214, "PICMG 2.14 controller",
180         NULL, NULL, NULL,
181         NULL, NULL,
182     },
183     {
184         PCI_SUBCLASS_NETWORK_OTHER, "misc network controller",
185         NULL, NULL, NULL,
186         NULL, NULL,
187     },
188     {
189         0xFF, NULL,
190         NULL, NULL, NULL,
191         NULL, NULL,
192     },
193 };
194
195 static const pci_dev_t vga_devices[] = {
196     {
197         PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
198         NULL, "ATY",      "ATY Rage128", "VGA\0",
199         0, 0, 0,
200         NULL, NULL,
201     },
202     {
203         PCI_VENDOR_ID_QEMU, PCI_DEVICE_ID_QEMU_VGA,
204         NULL, "QEMU,VGA", "Qemu VGA",    "VGA\0",
205         0, 0, 0,
206         NULL, NULL,
207     },
208     {
209         0xFFFF, 0xFFFF,
210         NULL, NULL, NULL, NULL,
211         -1, -1, -1,
212         NULL, NULL,
213     },
214 };
215
216 static const struct pci_iface_t vga_iface[] = {
217     {
218         0x00, "VGA controller", NULL,
219         vga_devices, &vga_config_cb, NULL,
220     },
221     {
222         0x01, "8514 compatible controller", NULL,
223         NULL, NULL, NULL,
224     },
225     {
226         0xFF, NULL, NULL,
227         NULL, NULL, NULL,
228     },
229 };
230
231 static const pci_subclass_t displ_subclass[] = {
232     {
233         PCI_SUBCLASS_DISPLAY_VGA, "display controller",
234         NULL, NULL, vga_iface,
235         NULL, NULL,
236     },
237     {
238         PCI_SUBCLASS_DISPLAY_XGA, "XGA display controller",
239         NULL, NULL, NULL,
240         NULL, NULL,
241     },
242     {
243         PCI_SUBCLASS_DISPLAY_3D, "3D display controller",
244         NULL, NULL, NULL,
245         NULL, NULL,
246     },
247     {
248         PCI_SUBCLASS_DISPLAY_OTHER, "misc display controller",
249         NULL, NULL, NULL,
250         NULL, NULL,
251     },
252     {
253         0xFF, NULL,
254         NULL, NULL, NULL,
255         NULL, NULL,
256     },
257 };
258
259 static const pci_subclass_t media_subclass[] = {
260     {
261         PCI_SUBCLASS_MULTIMEDIA_VIDEO, "video device",
262         NULL, NULL, NULL,
263         NULL, NULL,
264     },
265     {
266         PCI_SUBCLASS_MULTIMEDIA_AUDIO, "audio device",
267         NULL, NULL, NULL,
268         NULL, NULL,
269     },
270     {
271         PCI_SUBCLASS_MULTIMEDIA_PHONE, "computer telephony device",
272         NULL, NULL, NULL,
273         NULL, NULL,
274     },
275     {
276         PCI_SUBCLASS_MULTIMEDIA_OTHER, "misc multimedia device",
277         NULL, NULL, NULL,
278         NULL, NULL,
279     },
280     {
281         0xFF, NULL,
282         NULL, NULL, NULL,
283         NULL, NULL,
284     },
285 };
286
287 static const pci_subclass_t mem_subclass[] = {
288     {
289         PCI_SUBCLASS_MEMORY_RAM, "RAM controller",
290         NULL, NULL, NULL,
291         NULL, NULL,
292     },
293     {
294         PCI_SUBCLASS_MEMORY_FLASH, "flash controller",
295         NULL, NULL, NULL,
296         NULL, NULL,
297     },
298     {
299         0xFF, NULL,
300         NULL, NULL, NULL,
301         NULL, NULL,
302     },
303 };
304
305
306 static const pci_dev_t hbrg_devices[] = {
307     {
308         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U3_AGP, NULL,
309         "pci", "AAPL,UniNorth", "u3-agp\0",
310         3, 2, 1,
311         host_config_cb, NULL,
312     },
313     {
314         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_AGP, NULL,
315         "pci", "AAPL,UniNorth", "uni-north\0",
316         3, 2, 1,
317         host_config_cb, NULL,
318     },
319     {
320         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI, NULL,
321         "pci", "AAPL,UniNorth", "uni-north\0",
322         3, 2, 1,
323         host_config_cb, NULL,
324     },
325     {
326         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI, NULL,
327         "pci", "AAPL,UniNorth", "uni-north\0",
328         3, 2, 1,
329         NULL, NULL
330     },
331     {
332         PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_MPC106, "pci",
333         "pci", "MOT,MPC106", "grackle\0",
334         3, 2, 1,
335         host_config_cb, NULL
336     },
337     {
338         PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_RAVEN, NULL,
339         "pci", "PREP Host PCI Bridge - Motorola Raven", NULL,
340         3, 2, 1,
341         host_config_cb, NULL,
342     },
343     {
344         PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SABRE, NULL,
345         "pci", "SUNW,sabre", "pci108e,a000\0pciclass,0\0",
346         3, 2, 1,
347         sabre_config_cb, NULL,
348     },
349     {
350         0xFFFF, 0xFFFF,
351         NULL, NULL, NULL, NULL,
352         -1, -1, -1,
353         NULL, NULL,
354     },
355 };
356
357 static const pci_dev_t PCIbrg_devices[] = {
358     {
359         PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21154, NULL,
360         "pci-bridge", "DEV,21154", "DEV,21154\0pci-bridge\0",
361         3, 2, 1,
362         bridge_config_cb, NULL,
363     },
364     {
365         PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA, NULL,
366         "pci", "SUNW,simba", "pci108e,5000\0pciclass,060400\0",
367         3, 2, 1,
368         bridge_config_cb, NULL,
369     },
370     {
371         0xFFFF, 0xFFFF,
372         NULL, NULL, NULL, NULL,
373         -1, -1, -1,
374         NULL, NULL,
375     },
376 };
377
378 static const pci_dev_t miscbrg_devices[] = {
379     {
380         PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL,
381         "ebus", "ebus", "pci108e,1000\0pciclass,068000\0",
382         2, 1, 1,
383         ebus_config_cb, NULL,
384     },
385     {
386         0xFFFF, 0xFFFF,
387         NULL, NULL, NULL, NULL,
388         -1, -1, -1,
389         NULL, NULL,
390     },
391 };
392
393 static const pci_dev_t isabrg_devices[] = {
394     {
395         PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, NULL,
396         "isa", "isa", "pci8086,484\0",
397         1, 1, 1,
398         i82378_config_cb, NULL,
399     },
400     {
401         0xFFFF, 0xFFFF,
402         NULL, NULL, NULL, NULL,
403         -1, -1, -1,
404         NULL, NULL,
405     },
406 };
407
408 static const pci_subclass_t bridg_subclass[] = {
409     {
410         PCI_SUBCLASS_BRIDGE_HOST, "PCI host bridge",
411         "pci", hbrg_devices, NULL,
412         NULL, NULL,
413     },
414     {
415         PCI_SUBCLASS_BRIDGE_ISA, "ISA bridge",
416         "isa", isabrg_devices, NULL,
417         NULL, NULL,
418     },
419     {
420         PCI_SUBCLASS_BRIDGE_EISA, "EISA bridge",
421         NULL, NULL, NULL,
422         NULL, NULL,
423     },
424     {
425         PCI_SUBCLASS_BRIDGE_MC, "MCA bridge",
426         NULL, NULL, NULL,
427         NULL, NULL,
428     },
429     {
430         PCI_SUBCLASS_BRIDGE_PCI, "PCI-to-PCI bridge",
431         "pci", PCIbrg_devices, NULL,
432         NULL, NULL,
433     },
434     {
435         PCI_SUBCLASS_BRIDGE_PCMCIA, "PCMCIA bridge",
436         NULL, NULL, NULL,
437         NULL, NULL,
438     },
439     {
440         PCI_SUBCLASS_BRIDGE_NUBUS, "NUBUS bridge",
441         NULL, NULL, NULL,
442         NULL, NULL,
443     },
444     {
445         PCI_SUBCLASS_BRIDGE_CARDBUS, "cardbus bridge",
446         NULL, NULL, NULL,
447         NULL, NULL,
448     },
449     {
450         PCI_SUBCLASS_BRIDGE_RACEWAY, "raceway bridge",
451         NULL, NULL, NULL,
452         NULL, NULL,
453     },
454     {
455         PCI_SUBCLASS_BRIDGE_PCI_SEMITP, "semi-transparent PCI-to-PCI bridge",
456         NULL, NULL, NULL,
457         NULL, NULL,
458     },
459     {
460         PCI_SUBCLASS_BRIDGE_IB_PCI, "infiniband-to-PCI bridge",
461         NULL, NULL, NULL,
462         NULL, NULL,
463     },
464     {
465         PCI_SUBCLASS_BRIDGE_OTHER, "misc PCI bridge",
466         NULL, miscbrg_devices, NULL,
467         NULL, NULL,
468     },
469     {
470         0xFF, NULL,
471         NULL, NULL, NULL,
472         NULL, NULL,
473     },
474 };
475
476 static const pci_iface_t serial_iface[] = {
477     {
478         0x00, "XT serial controller", NULL,
479         NULL, NULL, NULL,
480     },
481     {
482         0x01, "16450 serial controller", NULL,
483         NULL, NULL, NULL,
484     },
485     {
486         0x02, "16550 serial controller", NULL,
487         NULL, NULL, NULL,
488     },
489     {
490         0x03, "16650 serial controller", NULL,
491         NULL, NULL, NULL,
492     },
493     {
494         0x04, "16750 serial controller", NULL,
495         NULL, NULL, NULL,
496     },
497     {
498         0x05, "16850 serial controller", NULL,
499         NULL, NULL, NULL,
500     },
501     {
502         0x06, "16950 serial controller", NULL,
503         NULL, NULL, NULL,
504     },
505     {
506         0xFF, NULL, NULL,
507         NULL, NULL, NULL,
508     },
509 };
510
511 static const pci_iface_t par_iface[] = {
512     {
513         0x00, "parallel port", NULL,
514         NULL, NULL, NULL,
515     },
516     {
517         0x01, "bi-directional parallel port", NULL,
518         NULL, NULL, NULL,
519     },
520     {
521         0x02, "ECP 1.x parallel port", NULL,
522         NULL, NULL, NULL,
523     },
524     {
525         0x03, "IEEE 1284 controller", NULL,
526         NULL, NULL, NULL,
527     },
528     {
529         0xFE, "IEEE 1284 device", NULL,
530         NULL, NULL, NULL,
531     },
532     {
533         0xFF, NULL, NULL,
534         NULL, NULL, NULL,
535     },
536 };
537
538 static const pci_iface_t modem_iface[] = {
539     {
540         0x00, "generic modem", NULL,
541         NULL, NULL, NULL,
542     },
543     {
544         0x01, "Hayes 16450 modem", NULL,
545         NULL, NULL, NULL,
546     },
547     {
548         0x02, "Hayes 16550 modem", NULL,
549         NULL, NULL, NULL,
550     },
551     {
552         0x03, "Hayes 16650 modem", NULL,
553         NULL, NULL, NULL,
554     },
555     {
556         0x04, "Hayes 16750 modem", NULL,
557         NULL, NULL, NULL,
558     },
559     {
560         0xFF, NULL, NULL,
561         NULL, NULL, NULL,
562     },
563 };
564
565 static const pci_subclass_t comm_subclass[] = {
566     {
567         PCI_SUBCLASS_COMMUNICATION_SERIAL, "serial controller",
568         NULL, NULL, serial_iface,
569         NULL, NULL,
570     },
571     {
572         PCI_SUBCLASS_COMMUNICATION_PARALLEL, "parallel port",
573         NULL, NULL, par_iface,
574         NULL, NULL,
575     },
576     {
577         PCI_SUBCLASS_COMMUNICATION_MULTISERIAL, "multiport serial controller",
578         NULL, NULL, NULL,
579         NULL, NULL,
580     },
581     {
582         PCI_SUBCLASS_COMMUNICATION_MODEM, "modem",
583         NULL, NULL, modem_iface,
584         NULL, NULL,
585     },
586     {
587         PCI_SUBCLASS_COMMUNICATION_GPIB, "GPIB controller",
588         NULL, NULL, NULL,
589         NULL, NULL,
590     },
591     {
592         PCI_SUBCLASS_COMMUNICATION_SC, "smart card",
593         NULL, NULL, NULL,
594         NULL, NULL,
595     },
596     {
597         PCI_SUBCLASS_COMMUNICATION_OTHER, "misc communication device",
598         NULL, NULL, NULL,
599         NULL, NULL,
600     },
601     {
602         0xFF, NULL,
603         NULL, NULL, NULL,
604         NULL, NULL,
605     },
606 };
607
608 static const pci_iface_t pic_iface[] = {
609     {
610         0x00, "8259 PIC", NULL,
611         NULL, NULL, NULL,
612     },
613     {
614         0x01, "ISA PIC", NULL,
615         NULL, NULL, NULL,
616     },
617     {
618         0x02, "EISA PIC", NULL,
619         NULL, NULL, NULL,
620     },
621     {
622         0x10, "I/O APIC", NULL,
623         NULL, NULL, NULL,
624     },
625     {
626         0x20, "I/O APIC", NULL,
627         NULL, NULL, NULL,
628     },
629     {
630         0xFF, NULL, NULL,
631         NULL, NULL, NULL,
632     },
633 };
634
635 static const pci_iface_t dma_iface[] = {
636     {
637         0x00, "8237 DMA controller", NULL,
638         NULL, NULL, NULL,
639     },
640     {
641         0x01, "ISA DMA controller", NULL,
642         NULL, NULL, NULL,
643     },
644     {
645         0x02, "EISA DMA controller", NULL,
646         NULL, NULL, NULL,
647     },
648     {
649         0xFF, NULL, NULL,
650         NULL, NULL, NULL,
651     },
652 };
653
654 static const pci_iface_t tmr_iface[] = {
655     {
656         0x00, "8254 system timer", NULL,
657         NULL, NULL, NULL,
658     },
659     {
660         0x01, "ISA system timer", NULL,
661         NULL, NULL, NULL,
662     },
663     {
664         0x02, "EISA system timer", NULL,
665         NULL, NULL, NULL,
666     },
667     {
668         0xFF, NULL, NULL,
669         NULL, NULL, NULL,
670     },
671 };
672
673 static const pci_iface_t rtc_iface[] = {
674     {
675         0x00, "generic RTC controller", NULL,
676         NULL, NULL, NULL,
677     },
678     {
679         0x01, "ISA RTC controller", NULL,
680         NULL, NULL, NULL,
681     },
682     {
683         0xFF, NULL, NULL,
684         NULL, NULL, NULL,
685     },
686 };
687
688 static const pci_dev_t sys_devices[] = {
689     /* IBM MPIC controller */
690     {
691         PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC,
692         "open-pic", "MPIC", NULL, "chrp,open-pic\0",
693         0, 0, 2,
694         NULL, NULL,
695     },
696     /* IBM MPIC2 controller */
697     {
698         PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OPENPIC2,
699         "open-pic", "MPIC2", NULL, "chrp,open-pic\0",
700         0, 0, 2,
701         NULL, NULL,
702     },
703     {
704         0xFFFF, 0xFFFF,
705         NULL, NULL, NULL, NULL,
706         -1, -1, -1,
707         NULL, NULL,
708     },
709 };
710
711 static const pci_subclass_t sys_subclass[] = {
712     {
713         PCI_SUBCLASS_SYSTEM_PIC, "PIC",
714         NULL, NULL, pic_iface,
715         NULL, NULL,
716     },
717     {
718         PCI_SUBCLASS_SYSTEM_DMA, "DMA controller",
719         NULL, NULL, dma_iface,
720         NULL, NULL,
721     },
722     {
723         PCI_SUBCLASS_SYSTEM_TIMER, "system timer",
724         NULL, NULL, tmr_iface,
725         NULL, NULL,
726     },
727     {
728         PCI_SUBCLASS_SYSTEM_RTC, "RTC controller",
729         NULL, NULL, rtc_iface,
730         NULL, NULL,
731     },
732     {
733         PCI_SUBCLASS_SYSTEM_PCI_HOTPLUG, "PCI hotplug controller",
734         NULL, NULL, NULL,
735         NULL, NULL,
736     },
737     {
738         PCI_SUBCLASS_SYSTEM_OTHER, "misc system peripheral",
739         NULL, sys_devices, NULL,
740         NULL, NULL,
741     },
742     {
743         0xFF, NULL,
744         NULL, NULL, NULL,
745         NULL, NULL,
746     },
747 };
748
749 static const pci_subclass_t inp_subclass[] = {
750     {
751         PCI_SUBCLASS_INPUT_KEYBOARD, "keyboard controller",
752         NULL, NULL, NULL,
753         NULL, NULL,
754     },
755     {
756         PCI_SUBCLASS_INPUT_PEN, "digitizer",
757         NULL, NULL, NULL,
758         NULL, NULL,
759     },
760     {
761         PCI_SUBCLASS_INPUT_MOUSE, "mouse controller",
762         NULL, NULL, NULL,
763         NULL, NULL,
764     },
765     {
766         PCI_SUBCLASS_INPUT_SCANNER, "scanner controller",
767         NULL, NULL, NULL,
768         NULL, NULL,
769     },
770     {
771         PCI_SUBCLASS_INPUT_GAMEPORT, "gameport controller",
772         NULL, NULL, NULL,
773         NULL, NULL,
774     },
775     {
776         PCI_SUBCLASS_INPUT_OTHER, "misc input device",
777         NULL, NULL, NULL,
778         NULL, NULL,
779     },
780     {
781         0xFF, NULL,
782         NULL, NULL, NULL,
783         NULL, NULL,
784     },
785 };
786
787 static const pci_subclass_t dock_subclass[] = {
788     {
789         PCI_SUBCLASS_DOCKING_GENERIC, "generic docking station",
790         NULL, NULL, NULL,
791         NULL, NULL,
792     },
793     {
794         PCI_SUBCLASS_DOCKING_OTHER, "misc docking station",
795         NULL, NULL, NULL,
796         NULL, NULL,
797     },
798     {
799         0xFF, NULL,
800         NULL, NULL, NULL,
801         NULL, NULL,
802     },
803 };
804
805 static const pci_subclass_t cpu_subclass[] = {
806     {
807         PCI_SUBCLASS_PROCESSOR_386, "i386 processor",
808         NULL, NULL, NULL,
809         NULL, NULL,
810     },
811     {
812         PCI_SUBCLASS_PROCESSOR_486, "i486 processor",
813         NULL, NULL, NULL,
814         NULL, NULL,
815     },
816     {
817         PCI_SUBCLASS_PROCESSOR_PENTIUM, "pentium processor",
818         NULL, NULL, NULL,
819         NULL, NULL,
820     },
821     {
822         PCI_SUBCLASS_PROCESSOR_ALPHA, "alpha processor",
823         NULL, NULL, NULL,
824         NULL, NULL,
825     },
826     {
827         PCI_SUBCLASS_PROCESSOR_POWERPC, "PowerPC processor",
828         NULL, NULL, NULL,
829         NULL, NULL,
830     },
831     {
832         PCI_SUBCLASS_PROCESSOR_MIPS, "MIPS processor",
833         NULL, NULL, NULL,
834         NULL, NULL,
835     },
836     {
837         PCI_SUBCLASS_PROCESSOR_CO, "co-processor",
838         NULL, NULL, NULL,
839         NULL, NULL,
840     },
841     {
842         0xFF, NULL,
843         NULL, NULL, NULL,
844         NULL, NULL,
845     },
846 };
847
848 static const pci_dev_t usb_devices[] = {
849 #if defined(CONFIG_QEMU)
850     {
851         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_KEYL_USB,
852         "usb", "usb", NULL,
853         "pci106b,3f\0pciclass,0c0310\0",
854         1, 0, 0,
855         NULL, NULL,
856     },
857 #endif
858     {
859         0xFFFF, 0xFFFF,
860         NULL, NULL, NULL, NULL,
861         -1, -1, -1,
862         NULL, NULL,
863     },
864 };
865
866 static const pci_iface_t usb_iface[] = {
867     {
868         0x00, "UHCI USB controller", NULL,
869         NULL, NULL, NULL,
870     },
871     {
872         0x10, "OHCI USB controller", NULL,
873         usb_devices, &usb_ohci_config_cb, NULL,
874     },
875     {
876         0x20, "EHCI USB controller", NULL,
877         NULL, NULL, NULL,
878     },
879     {
880         0x80, "misc USB controller", NULL,
881         NULL, NULL, NULL,
882     },
883     {
884         0xFE, "USB device", NULL,
885         NULL, NULL, NULL,
886     },
887     {
888         0xFF, NULL, NULL,
889         NULL, NULL, NULL,
890     },
891 };
892
893 static const pci_iface_t ipmi_iface[] = {
894     {
895         0x00, "IPMI SMIC interface", NULL,
896         NULL, NULL, NULL,
897     },
898     {
899         0x01, "IPMI keyboard interface", NULL,
900         NULL, NULL, NULL,
901     },
902     {
903         0x02, "IPMI block transfer interface", NULL,
904         NULL, NULL, NULL,
905     },
906     {
907         0xFF, NULL, NULL,
908         NULL, NULL, NULL,
909     },
910 };
911
912 static const pci_subclass_t ser_subclass[] = {
913     {
914         PCI_SUBCLASS_SERIAL_FIREWIRE, "Firewire bus controller",
915         "ieee1394", NULL, NULL,
916         NULL, NULL,
917     },
918     {
919         PCI_SUBCLASS_SERIAL_ACCESS, "ACCESS bus controller",
920         NULL, NULL, NULL,
921         NULL, NULL,
922     },
923     {
924         PCI_SUBCLASS_SERIAL_SSA, "SSA controller",
925         NULL, NULL, NULL,
926         NULL, NULL,
927     },
928     {
929         PCI_SUBCLASS_SERIAL_USB, "USB controller",
930         "usb", NULL, usb_iface,
931         NULL, NULL,
932     },
933     {
934         PCI_SUBCLASS_SERIAL_FIBER, "fibre channel controller",
935         NULL, NULL, NULL,
936         NULL, NULL,
937     },
938     {
939         PCI_SUBCLASS_SERIAL_SMBUS, "SMBus controller",
940         NULL, NULL, NULL,
941         NULL, NULL,
942     },
943     {
944         PCI_SUBCLASS_SERIAL_IB, "InfiniBand controller",
945         NULL, NULL, NULL,
946         NULL, NULL,
947     },
948     {
949         PCI_SUBCLASS_SERIAL_IPMI, "IPMI interface",
950         NULL, NULL, ipmi_iface,
951         NULL, NULL,
952     },
953     {
954         PCI_SUBCLASS_SERIAL_SERCOS, "SERCOS controller",
955         NULL, NULL, ipmi_iface,
956         NULL, NULL,
957     },
958     {
959         PCI_SUBCLASS_SERIAL_CANBUS, "CANbus controller",
960         NULL, NULL, ipmi_iface,
961         NULL, NULL,
962     },
963     {
964         0xFF, NULL,
965         NULL, NULL, NULL,
966         NULL, NULL,
967     },
968 };
969
970 static const pci_subclass_t wrl_subclass[] = {
971     {
972         PCI_SUBCLASS_WIRELESS_IRDA, "IRDA controller",
973         NULL, NULL, NULL,
974         NULL, NULL,
975     },
976     {
977         PCI_SUBCLASS_WIRELESS_CIR, "consumer IR controller",
978         NULL, NULL, NULL,
979         NULL, NULL,
980     },
981     {
982         PCI_SUBCLASS_WIRELESS_RF_CONTROLLER, "RF controller",
983         NULL, NULL, NULL,
984         NULL, NULL,
985     },
986     {
987         PCI_SUBCLASS_WIRELESS_BLUETOOTH, "bluetooth controller",
988         NULL, NULL, NULL,
989         NULL, NULL,
990     },
991     {
992         PCI_SUBCLASS_WIRELESS_BROADBAND, "broadband controller",
993         NULL, NULL, NULL,
994         NULL, NULL,
995     },
996     {
997         PCI_SUBCLASS_WIRELESS_OTHER, "misc wireless controller",
998         NULL, NULL, NULL,
999         NULL, NULL,
1000     },
1001     {
1002         0xFF, NULL,
1003         NULL, NULL, NULL,
1004         NULL, NULL,
1005     },
1006 };
1007
1008 static const pci_subclass_t sat_subclass[] = {
1009     {
1010         PCI_SUBCLASS_SATELLITE_TV, "satellite TV controller",
1011         NULL, NULL, NULL,
1012         NULL, NULL,
1013     },
1014     {
1015         PCI_SUBCLASS_SATELLITE_AUDIO, "satellite audio controller",
1016         NULL, NULL, NULL,
1017         NULL, NULL,
1018     },
1019     {
1020         PCI_SUBCLASS_SATELLITE_VOICE, "satellite voice controller",
1021         NULL, NULL, NULL,
1022         NULL, NULL,
1023     },
1024     {
1025         PCI_SUBCLASS_SATELLITE_DATA, "satellite data controller",
1026         NULL, NULL, NULL,
1027         NULL, NULL,
1028     },
1029     {
1030         0xFF, NULL,
1031         NULL, NULL, NULL,
1032         NULL, NULL,
1033     },
1034 };
1035
1036 static const pci_subclass_t crypt_subclass[] = {
1037     {
1038         PCI_SUBCLASS_CRYPT_NETWORK, "cryptographic network controller",
1039         NULL, NULL, NULL,
1040         NULL, NULL,
1041     },
1042     {
1043         PCI_SUBCLASS_CRYPT_ENTERTAINMENT,
1044         "cryptographic entertainment controller",
1045         NULL, NULL, NULL,
1046         NULL, NULL,
1047     },
1048     {
1049         PCI_SUBCLASS_CRYPT_OTHER, "misc cryptographic controller",
1050         NULL, NULL, NULL,
1051         NULL, NULL,
1052     },
1053     {
1054         0xFF, NULL,
1055         NULL, NULL, NULL,
1056         NULL, NULL,
1057     },
1058 };
1059
1060 static const pci_subclass_t spc_subclass[] = {
1061     {
1062         PCI_SUBCLASS_SP_DPIO, "DPIO module",
1063         NULL, NULL, NULL,
1064         NULL, NULL,
1065     },
1066     {
1067         PCI_SUBCLASS_SP_PERF, "performances counters",
1068         NULL, NULL, NULL,
1069         NULL, NULL,
1070     },
1071     {
1072         PCI_SUBCLASS_SP_SYNCH, "communication synchronisation",
1073         NULL, NULL, NULL,
1074         NULL, NULL,
1075     },
1076     {
1077         PCI_SUBCLASS_SP_MANAGEMENT, "management card",
1078         NULL, NULL, NULL,
1079         NULL, NULL,
1080     },
1081     {
1082         PCI_SUBCLASS_SP_OTHER, "misc signal processing controller",
1083         NULL, NULL, NULL,
1084         NULL, NULL,
1085     },
1086     {
1087         0xFF, NULL,
1088         NULL, NULL, NULL,
1089         NULL, NULL,
1090     },
1091 };
1092
1093 static const pci_class_t pci_classes[] = {
1094     /* 0x00 */
1095     { "undefined",                         NULL,             undef_subclass, },
1096     /* 0x01 */
1097     { "mass-storage controller",           NULL,              mass_subclass, },
1098     /* 0x02 */
1099     { "network controller",                "network",          net_subclass, },
1100     /* 0x03 */
1101     { "display controller",                "display",        displ_subclass, },
1102     /* 0x04 */
1103     { "multimedia device",                 NULL,             media_subclass, },
1104     /* 0x05 */
1105     { "memory controller",                 "memory-controller", mem_subclass, },
1106     /* 0x06 */
1107     { "PCI bridge",                        NULL,             bridg_subclass, },
1108     /* 0x07 */
1109     { "communication device",              NULL,               comm_subclass,},
1110     /* 0x08 */
1111     { "system peripheral",                 NULL,               sys_subclass, },
1112     /* 0x09 */
1113     { "input device",                      NULL,               inp_subclass, },
1114     /* 0x0A */
1115     { "docking station",                   NULL,              dock_subclass, },
1116     /* 0x0B */
1117     { "processor",                         NULL,               cpu_subclass, },
1118     /* 0x0C */
1119     { "serial bus controller",             NULL,               ser_subclass, },
1120     /* 0x0D */
1121     { "wireless controller",               NULL,               wrl_subclass, },
1122     /* 0x0E */
1123     { "intelligent I/O controller",        NULL,               NULL,         },
1124     /* 0x0F */
1125     { "satellite communication controller", NULL,               sat_subclass, },
1126     /* 0x10 */
1127     { "cryptographic controller",           NULL,             crypt_subclass, },
1128     /* 0x11 */
1129     { "signal processing controller",       NULL,               spc_subclass, },
1130 };
1131
1132 static const pci_dev_t misc_pci[] = {
1133     /* Heathrow Mac I/O */
1134     {
1135         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1201,
1136         "mac-io", "mac-io", "AAPL,343S1201", "heathrow\0",
1137         1, 1, 1,
1138         &macio_heathrow_config_cb, NULL,
1139     },
1140     /* Paddington Mac I/O */
1141     {
1142         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_343S1211,
1143         "mac-io", "mac-io", "AAPL,343S1211", "paddington\0heathrow\0",
1144         1, 1, 1,
1145         &macio_heathrow_config_cb, NULL,
1146     },
1147     /* KeyLargo Mac I/O */
1148     {
1149         PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_KEYL,
1150         "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo\0",
1151         1, 1, 1,
1152         &macio_keylargo_config_cb, NULL,
1153     },
1154     {
1155         0xFFFF, 0xFFFF,
1156         NULL, NULL, NULL, NULL,
1157         -1, -1, -1,
1158         NULL, NULL,
1159     },
1160 };
1161
1162 const pci_dev_t *pci_find_device (uint8_t class, uint8_t subclass,
1163                                   uint8_t iface, uint16_t vendor,
1164                                   uint16_t product)
1165 {
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;
1172     pci_dev_t *new;
1173     const char *name, *type;
1174
1175     name = "unknown";
1176     type = "unknown";
1177     config_cb = NULL;
1178     private = NULL;
1179
1180     if (class == 0x00 && subclass == 0x01) {
1181         /* Special hack for old style VGA devices */
1182         class = 0x03;
1183         subclass = 0x00;
1184     } else if (class == 0xFF) {
1185         /* Special case for misc devices */
1186         dev = misc_pci;
1187         goto find_device;
1188     }
1189     if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
1190         name = "invalid PCI device";
1191         type = "invalid";
1192         goto bad_device;
1193     }
1194     pclass = &pci_classes[class];
1195     name = pclass->name;
1196     type = pclass->type;
1197     for (psubclass = pclass->subc; ; psubclass++) {
1198         if (psubclass->subclass == 0xFF)
1199             goto bad_device;
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;
1207             }
1208             if (psubclass->private != NULL)
1209                 private = psubclass->private;
1210             if (psubclass->iface != NULL)
1211                 break;
1212             dev = psubclass->devices;
1213             goto find_device;
1214         }
1215     }
1216     for (piface = psubclass->iface; ; piface++) {
1217         if (piface->iface == 0xFF) {
1218             dev = psubclass->devices;
1219             break;
1220         }
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;
1228             }
1229             if (piface->private != NULL)
1230                 private = piface->private;
1231             dev = piface->devices;
1232             break;
1233         }
1234     }
1235 find_device:
1236     if (dev == NULL)
1237         goto bad_device;
1238     for (;; dev++) {
1239         if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) {
1240             goto bad_device;
1241         }
1242         if (dev->vendor == vendor && dev->product == product) {
1243             if (dev->name != NULL)
1244                 name = dev->name;
1245             if (dev->type != NULL)
1246                 type = dev->type;
1247             if (dev->config_cb != NULL) {
1248                 config_cb = dev->config_cb;
1249             }
1250             if (dev->private != NULL)
1251                 private = dev->private;
1252             new = malloc(sizeof(pci_dev_t));
1253             if (new == NULL)
1254                 return NULL;
1255             new->vendor = vendor;
1256             new->product = product;
1257             new->type = type;
1258             new->name = name;
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;
1266
1267             return new;
1268         }
1269     }
1270 bad_device:
1271     printk("Cannot manage '%s' PCI device type '%s':\n %x %x (%x %x %x)\n",
1272            name, type, vendor, product, class, subclass, iface);
1273
1274     return NULL;
1275 }