3 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License V2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #if defined (DEBUG_PCI)
26 #define PCI_DPRINTF(fmt, args...) \
27 do { dprintf("PCI %s: " fmt, __func__ , ##args); } while (0)
29 #define PCI_DPRINTF(fmt, args...) \
33 /* On PMAC, there are four kind of PCI bridges:
34 * - uninorth, for all recent machines (all Core99 and more).
35 * - chaos : buggy bandit like
36 * - grackle, for powerbook 1998 & some powermac G3
37 * - bandit : some early PCI powermacs.
38 * For now, only uninorth will be supported, as other ones are deprecated.
43 PCI_FAKE_HOST = 0x00000001,
44 PCI_FAKE_BRIDGE = 0x00000002,
45 /* Device found during PCI probe */
46 PCI_HOST_BRIDGE = 0x00000003,
47 PCI_DEV_BRIDGE = 0x00000004,
48 PCI_DEVICE = 0x00000005,
52 BRIDGE_TYPE_UNINORTH = 0x0001,
55 /* PCI devices database */
56 typedef struct pci_class_t pci_class_t;
57 typedef struct pci_subclass_t pci_subclass_t;
58 typedef struct pci_iface_t pci_iface_t;
62 const unsigned char *name;
63 const unsigned char *type;
64 const pci_dev_t *devices;
65 int (*config_cb)(pci_device_t *device);
69 struct pci_subclass_t {
71 const unsigned char *name;
72 const unsigned char *type;
73 const pci_dev_t *devices;
74 const pci_iface_t *iface;
75 int (*config_cb)(pci_device_t *device);
80 const unsigned char *name;
81 const unsigned char *type;
82 const pci_subclass_t *subc;
85 /* PCI devices tree */
88 const pci_dev_t *device;
89 const pci_u_t *parent;
100 uint16_t max_latency;
102 uint32_t regions[7]; /* the region 6 is the PCI ROM */
109 pci_bridge_t *bridge;
113 struct pci_bridge_t {
128 const pci_ops_t *ops;
129 pci_device_t *devices;
140 /* Low level access helpers */
142 uint8_t (*config_readb)(pci_bridge_t *bridge,
143 uint8_t bus, uint8_t devfn, uint8_t offset);
144 void (*config_writeb)(pci_bridge_t *bridge,
145 uint8_t bus, uint8_t devfn,
146 uint8_t offset, uint8_t val);
147 uint16_t (*config_readw)(pci_bridge_t *bridge,
148 uint8_t bus, uint8_t devfn, uint8_t offset);
149 void (*config_writew)(pci_bridge_t *bridge,
150 uint8_t bus, uint8_t devfn,
151 uint8_t offset, uint16_t val);
152 uint32_t (*config_readl)(pci_bridge_t *bridge,
153 uint8_t bus, uint8_t devfn, uint8_t offset);
154 void (*config_writel)(pci_bridge_t *bridge,
155 uint8_t bus, uint8_t devfn,
156 uint8_t offset, uint32_t val);
159 /* IRQ numbers assigned to PCI IRQs */
160 static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 };
161 static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
162 static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 };
165 static inline uint32_t PREP_cfg_addr (pci_bridge_t *bridge, unused uint8_t bus,
166 uint8_t devfn, uint8_t offset)
169 printf("Translate %0x %0x %d %x %x => %0x",
170 bridge->cfg_addr, bridge->cfg_data, bus, devfn, offset,
172 (1 << (devfn >> 3)) | ((devfn & 7) << 8) | offset);
174 return bridge->cfg_addr |
175 (1 << (devfn >> 3)) | ((devfn & 7) << 8) | offset;
178 static uint8_t PREP_config_readb (pci_bridge_t *bridge,
179 uint8_t bus, uint8_t devfn,
184 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
186 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
188 return *((uint8_t *)addr);
191 static void PREP_config_writeb (pci_bridge_t *bridge,
192 uint8_t bus, uint8_t devfn,
193 uint8_t offset, uint8_t val)
197 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
199 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
200 *((uint8_t *)addr) = val;
203 static uint16_t PREP_config_readw (pci_bridge_t *bridge,
204 uint8_t bus, uint8_t devfn,
209 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
211 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
213 return ldswap16((uint16_t *)addr);
216 static void PREP_config_writew (pci_bridge_t *bridge,
217 uint8_t bus, uint8_t devfn,
218 uint8_t offset, uint16_t val)
222 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
224 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
225 stswap16((uint16_t *)addr, val);
228 static uint32_t PREP_config_readl (pci_bridge_t *bridge,
229 uint8_t bus, uint8_t devfn,
234 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
236 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
238 return ldswap32((uint32_t *)addr);
241 static void PREP_config_writel (pci_bridge_t *bridge,
242 uint8_t bus, uint8_t devfn,
243 uint8_t offset, uint32_t val)
247 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
249 addr = PREP_cfg_addr(bridge, bus, devfn, offset);
250 stswap32((uint32_t *)addr, val);
253 static pci_ops_t PREP_pci_ops = {
254 &PREP_config_readb, &PREP_config_writeb,
255 &PREP_config_readw, &PREP_config_writew,
256 &PREP_config_readl, &PREP_config_writel,
259 /* Uninorth PCI host */
260 static uint32_t macrisc_cfg_address (pci_bridge_t *bridge,
261 uint8_t bus, uint8_t devfn,
267 /* Kind of magic... */
268 if (bridge->cfg_base == 0xF2000000) {
271 printf("Skip bus: %d dev: %x offset: %x\n", bus, devfn, offset);
275 addr = (1 << (devfn >> 3));
277 addr = (bus << 16) | ((devfn & 0xF8) << 8) | 0x01;
279 addr |= ((devfn & 0x07) << 8) | (offset & 0xFC);
280 /* Avoid looping forever */
282 printf("Translate %0x %0x %d %x %x => %0x",
283 bridge->cfg_addr, bridge->cfg_data, bus, devfn, offset, addr);
285 for (i = 0; i < 100; i++) {
286 stswap32((uint32_t *)bridge->cfg_addr, addr);
288 if (ldswap32((uint32_t *)bridge->cfg_addr) == addr)
293 printf("Translate %0x %0x %d %x %x => %0x",
294 bridge->cfg_addr, bridge->cfg_data, bus, devfn, offset, addr);
295 printf("\nTimeout accessing PCI bridge cfg address\n");
299 if (bridge->flags & BRIDGE_TYPE_UNINORTH)
304 printf(" %0x\n", bridge->cfg_data + offset);
307 return bridge->cfg_data + offset;
310 static uint8_t uninorth_config_readb (pci_bridge_t *bridge,
311 uint8_t bus, uint8_t devfn,
316 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
318 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
319 if (addr == (uint32_t)(-1))
322 return *((uint8_t *)addr);
325 static void uninorth_config_writeb (pci_bridge_t *bridge,
326 uint8_t bus, uint8_t devfn,
327 uint8_t offset, uint8_t val)
331 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
333 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
334 if (addr != (uint32_t)(-1))
335 *((uint8_t *)addr) = val;
338 static uint16_t uninorth_config_readw (pci_bridge_t *bridge,
339 uint8_t bus, uint8_t devfn,
344 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
346 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
347 if (addr == (uint32_t)(-1))
350 return ldswap16((uint16_t *)addr);
353 static void uninorth_config_writew (pci_bridge_t *bridge,
354 uint8_t bus, uint8_t devfn,
355 uint8_t offset, uint16_t val)
359 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
361 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
362 if (addr != (uint32_t)(-1))
363 stswap16((uint16_t *)addr, val);
366 static uint32_t uninorth_config_readl (pci_bridge_t *bridge,
367 uint8_t bus, uint8_t devfn,
372 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
374 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
375 if (addr == (uint32_t)(-1)) {
376 // printf("bad address -1\n");
379 // printf("%s: addr=%0x\n", __func__, addr);
381 return ldswap32((uint32_t *)addr);
384 static void uninorth_config_writel (pci_bridge_t *bridge,
385 uint8_t bus, uint8_t devfn,
386 uint8_t offset, uint32_t val)
390 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
392 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
393 if (addr != (uint32_t)(-1))
394 stswap32((uint32_t *)addr, val);
397 static pci_ops_t uninorth_pci_ops = {
398 &uninorth_config_readb, &uninorth_config_writeb,
399 &uninorth_config_readw, &uninorth_config_writew,
400 &uninorth_config_readl, &uninorth_config_writel,
403 /* Grackle PCI host */
405 static uint32_t grackle_cfg_address (pci_bridge_t *bridge,
406 uint8_t bus, uint8_t devfn,
410 addr = 0x80000000 | (bus << 16) | (devfn << 8) | (offset & 0xfc);
411 stswap32((uint32_t *)bridge->cfg_addr, addr);
412 return bridge->cfg_data + (offset & 3);
415 static uint8_t grackle_config_readb (pci_bridge_t *bridge,
416 uint8_t bus, uint8_t devfn,
420 addr = grackle_cfg_address(bridge, bus, devfn, offset);
421 return *((uint8_t *)addr);
424 static void grackle_config_writeb (pci_bridge_t *bridge,
425 uint8_t bus, uint8_t devfn,
426 uint8_t offset, uint8_t val)
429 addr = grackle_cfg_address(bridge, bus, devfn, offset);
430 *((uint8_t *)addr) = val;
433 static uint16_t grackle_config_readw (pci_bridge_t *bridge,
434 uint8_t bus, uint8_t devfn,
438 addr = grackle_cfg_address(bridge, bus, devfn, offset);
439 return ldswap16((uint16_t *)addr);
442 static void grackle_config_writew (pci_bridge_t *bridge,
443 uint8_t bus, uint8_t devfn,
444 uint8_t offset, uint16_t val)
447 addr = grackle_cfg_address(bridge, bus, devfn, offset);
448 stswap16((uint16_t *)addr, val);
451 static uint32_t grackle_config_readl (pci_bridge_t *bridge,
452 uint8_t bus, uint8_t devfn,
456 addr = grackle_cfg_address(bridge, bus, devfn, offset);
457 return ldswap32((uint32_t *)addr);
460 static void grackle_config_writel (pci_bridge_t *bridge,
461 uint8_t bus, uint8_t devfn,
462 uint8_t offset, uint32_t val)
466 addr = grackle_cfg_address(bridge, bus, devfn, offset);
467 stswap32((uint32_t *)addr, val);
470 static pci_ops_t grackle_pci_ops = {
471 &grackle_config_readb, &grackle_config_writeb,
472 &grackle_config_readw, &grackle_config_writew,
473 &grackle_config_readl, &grackle_config_writel,
476 static inline uint8_t pci_config_readb (pci_bridge_t *bridge,
477 uint8_t bus, uint8_t devfn,
480 return (*bridge->ops->config_readb)(bridge, bus, devfn, offset);
483 static inline void pci_config_writeb (pci_bridge_t *bridge,
484 uint8_t bus, uint8_t devfn,
485 uint8_t offset, uint8_t val)
487 (*bridge->ops->config_writeb)(bridge, bus, devfn, offset, val);
490 static inline uint16_t pci_config_readw (pci_bridge_t *bridge,
491 uint8_t bus, uint8_t devfn,
494 return (*bridge->ops->config_readw)(bridge, bus, devfn, offset);
497 static inline void pci_config_writew (pci_bridge_t *bridge,
498 uint8_t bus, uint8_t devfn,
499 uint8_t offset, uint16_t val)
501 (*bridge->ops->config_writew)(bridge, bus, devfn, offset, val);
504 static inline uint32_t pci_config_readl (pci_bridge_t *bridge,
505 uint8_t bus, uint8_t devfn,
508 return (*bridge->ops->config_readl)(bridge, bus, devfn, offset);
512 static inline void pci_config_writel (pci_bridge_t *bridge,
513 uint8_t bus, uint8_t devfn,
514 uint8_t offset, uint32_t val)
516 (*bridge->ops->config_writel)(bridge, bus, devfn, offset, val);
519 unused static void *get_parent_OF_private (pci_device_t *device)
523 for (u = (pci_u_t *)device; u != NULL; u = u->common.parent) {
524 if (u->common.OF_private != NULL)
525 return u->common.OF_private;
531 /* PCI devices database */
532 static pci_subclass_t undef_subclass[] = {
534 0x00, "misc undefined", NULL, NULL, NULL,
538 0xFF, NULL, NULL, NULL, NULL,
543 static int ide_config_cb2 (pci_device_t *device)
545 OF_finalize_pci_ide(device->common.OF_private,
546 device->regions[0] & ~0x0000000F,
547 device->regions[1] & ~0x0000000F,
548 device->regions[2] & ~0x0000000F,
549 device->regions[3] & ~0x0000000F);
553 static pci_dev_t ide_devices[] = {
555 0x1095, 0x0646, /* CMD646 IDE controller */
556 "pci-ide", "pci-ata", NULL, NULL,
558 ide_config_cb2, NULL,
562 NULL, NULL, NULL, NULL,
569 /* should base it on PCI ID, not on arch */
570 static int ide_config_cb (unused pci_device_t *device)
572 printf("Register IDE controller\n");
575 ide_pci_pmac_register(device->regions[0] & ~0x0000000F,
576 device->regions[1] & ~0x0000000F,
577 device->common.OF_private);
585 static int ata_config_cb (pci_device_t *device)
587 printf("Register ATA controller\n");
590 ide_pci_pmac_register(device->regions[0] & ~0x0000000F,
591 device->regions[1] & ~0x0000000F,
592 device->common.OF_private);
602 static pci_subclass_t mass_subclass[] = {
604 0x00, "SCSI bus controller", NULL, NULL, NULL,
608 0x01, "IDE controller", "ide", ide_devices, NULL,
612 0x02, "Floppy disk controller", NULL, NULL, NULL,
616 0x03, "IPI bus controller", NULL, NULL, NULL,
620 0x04, "RAID controller", NULL, NULL, NULL,
624 0x05, "ATA controller", "ata", NULL, NULL,
628 0x80, "misc mass-storage controller", NULL, NULL, NULL,
632 0xFF, NULL, NULL, NULL, NULL,
637 static pci_dev_t eth_devices[] = {
639 NULL, "NE2000", "NE2000 PCI", NULL,
645 NULL, NULL, NULL, NULL,
651 static pci_subclass_t net_subclass[] = {
653 0x00, "ethernet controller", NULL, eth_devices, NULL,
657 0x01, "token ring controller", NULL, NULL, NULL,
661 0x02, "FDDI controller", NULL, NULL, NULL,
665 0x03, "ATM controller", NULL, NULL, NULL,
669 0x04, "ISDN controller", NULL, NULL, NULL,
673 0x05, "WordFip controller", NULL, NULL, NULL,
677 0x06, "PICMG 2.14 controller", NULL, NULL, NULL,
681 0x80, "misc network controller", NULL, NULL, NULL,
685 0xFF, NULL, NULL, NULL, NULL,
690 static pci_dev_t vga_devices[] = {
693 NULL, "ATY", "ATY Rage128", "VGA",
699 NULL, "Qemu VGA", "Qemu VGA", "VGA",
705 NULL, NULL, NULL, NULL,
711 /* VGA configuration */
713 extern int vga_width, vga_height, vga_depth;
714 int vga_console_register (void);
715 static int vga_config_cb (pci_device_t *device)
717 /* Found a VGA device. Let's configure it ! */
718 printf("Set VGA to %0x\n", device->regions[0] & ~0x0000000F);
719 if (device->regions[0] != 0x00000000) {
720 vga_set_mode(vga_width, vga_height, vga_depth);
721 vga_set_address(device->regions[0] & ~0x0000000F);
723 OF_vga_register(device->common.device->name,
724 device->regions[0] & ~0x0000000F,
725 vga_width, vga_height, vga_depth,
726 device->regions[6] & ~0x0000000F,
729 vga_console_register();
734 static struct pci_iface_t vga_iface[] = {
736 0x00, "VGA controller", NULL,
737 vga_devices, &vga_config_cb, NULL,
740 0x01, "8514 compatible controller", NULL,
749 static pci_subclass_t displ_subclass[] = {
751 0x00, "display controller", NULL, NULL, vga_iface,
755 0x01, "XGA display controller", NULL, NULL, NULL,
759 0x02, "3D display controller", NULL, NULL, NULL,
763 0x80, "misc display controller", NULL, NULL, NULL,
767 0xFF, NULL, NULL, NULL, NULL,
772 static pci_subclass_t media_subclass[] = {
774 0x00, "video device", NULL, NULL, NULL,
778 0x01, "audio device", NULL, NULL, NULL,
782 0x02, "computer telephony device", NULL, NULL, NULL,
786 0x80, "misc multimedia device", NULL, NULL, NULL,
790 0xFF, NULL, NULL, NULL, NULL,
795 static pci_subclass_t mem_subclass[] = {
797 0x00, "RAM controller", NULL, NULL, NULL,
801 0x01, "flash controller", NULL, NULL, NULL,
805 0xFF, NULL, NULL, NULL, NULL,
810 static pci_dev_t uninorth_agp_fake_bridge = {
812 "uni-north-agp", "uni-north-agp", NULL, "uni-north-agp",
814 NULL, &uninorth_pci_ops,
817 static pci_dev_t uninorth_fake_bridge = {
819 "uni-north", "uni-north", NULL, "uni-north",
821 NULL, &uninorth_pci_ops,
824 static pci_dev_t PREP_fake_bridge = {
826 "pci", "pci", NULL, "pci",
831 pci_dev_t grackle_fake_bridge = {
833 "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge",
835 NULL, &grackle_pci_ops,
838 static pci_dev_t hbrg_devices[] = {
840 0x106B, 0x0020, NULL,
841 "pci", "AAPL,UniNorth", "uni-north",
843 NULL, &uninorth_agp_fake_bridge,
846 0x106B, 0x001F, NULL,
847 "pci", "AAPL,UniNorth", "uni-north",
849 NULL, &uninorth_fake_bridge,
852 0x106B, 0x001E, NULL,
853 "pci", "AAPL,UniNorth", "uni-north",
855 NULL, &uninorth_fake_bridge,
858 0x1057, 0x0002, "pci",
859 "pci", "MOT,MPC106", "grackle",
861 NULL, &grackle_fake_bridge,
864 0x1057, 0x4801, NULL,
865 "pci-bridge", "PREP Host PCI Bridge - Motorola Raven", NULL,
871 NULL, NULL, NULL, NULL,
877 static pci_dev_t PCIbrg_devices[] = {
879 0x1011, 0x0026, NULL,
880 "pci-bridge", NULL, NULL,
886 NULL, NULL, NULL, NULL,
892 static pci_subclass_t bridg_subclass[] = {
894 0x00, "PCI host bridge", NULL, hbrg_devices, NULL,
898 0x01, "ISA bridge", NULL, NULL, NULL,
902 0x02, "EISA bridge", NULL, NULL, NULL,
906 0x03, "MCA bridge", NULL, NULL, NULL,
910 0x04, "PCI-to-PCI bridge", NULL, PCIbrg_devices, NULL,
914 0x05, "PCMCIA bridge", NULL, NULL, NULL,
918 0x06, "NUBUS bridge", NULL, NULL, NULL,
922 0x07, "cardbus bridge", NULL, NULL, NULL,
926 0x08, "raceway bridge", NULL, NULL, NULL,
930 0x09, "semi-transparent PCI-to-PCI bridge", NULL, NULL, NULL,
934 0x0A, "infiniband-to-PCI bridge", NULL, NULL, NULL,
938 0x80, "misc PCI bridge", NULL, NULL, NULL,
942 0xFF, NULL, NULL, NULL, NULL,
947 static pci_iface_t serial_iface[] = {
949 0x00, "XT serial controller", NULL,
953 0x01, "16450 serial controller", NULL,
957 0x02, "16550 serial controller", NULL,
961 0x03, "16650 serial controller", NULL,
965 0x04, "16750 serial controller", NULL,
969 0x05, "16850 serial controller", NULL,
973 0x06, "16950 serial controller", NULL,
982 static pci_iface_t par_iface[] = {
984 0x00, "parallel port", NULL,
988 0x01, "bi-directional parallel port", NULL,
992 0x02, "ECP 1.x parallel port", NULL,
996 0x03, "IEEE 1284 controller", NULL,
1000 0xFE, "IEEE 1284 device", NULL,
1009 static pci_iface_t modem_iface[] = {
1011 0x00, "generic modem", NULL,
1015 0x01, "Hayes 16450 modem", NULL,
1019 0x02, "Hayes 16550 modem", NULL,
1023 0x03, "Hayes 16650 modem", NULL,
1027 0x04, "Hayes 16750 modem", NULL,
1036 static pci_subclass_t comm_subclass[] = {
1038 0x00, "serial controller", NULL, NULL, serial_iface,
1042 0x01, "parallel port", NULL, NULL, par_iface,
1046 0x02, "multiport serial controller", NULL, NULL, NULL,
1050 0x03, "modem", NULL, NULL, modem_iface,
1054 0x04, "GPIB controller", NULL, NULL, NULL,
1058 0x05, "smart card", NULL, NULL, NULL,
1062 0x80, "misc communication device", NULL, NULL, NULL,
1066 0xFF, NULL, NULL, NULL, NULL,
1071 static pci_iface_t pic_iface[] = {
1073 0x00, "8259 PIC", NULL,
1077 0x01, "ISA PIC", NULL,
1081 0x02, "EISA PIC", NULL,
1085 0x10, "I/O APIC", NULL,
1089 0x20, "I/O APIC", NULL,
1098 static pci_iface_t dma_iface[] = {
1100 0x00, "8237 DMA controller", NULL,
1104 0x01, "ISA DMA controller", NULL,
1108 0x02, "EISA DMA controller", NULL,
1117 static pci_iface_t tmr_iface[] = {
1119 0x00, "8254 system timer", NULL,
1123 0x01, "ISA system timer", NULL,
1127 0x02, "EISA system timer", NULL,
1136 static pci_iface_t rtc_iface[] = {
1138 0x00, "generic RTC controller", NULL,
1142 0x01, "ISA RTC controller", NULL,
1151 static const pci_dev_t sys_devices[] = {
1152 /* IBM MPIC controller */
1155 "open-pic", "MPIC", NULL, "chrp,open-pic",
1159 /* IBM MPIC2 controller */
1162 "open-pic", "MPIC2", NULL, "chrp,open-pic",
1168 NULL, NULL, NULL, NULL,
1174 static pci_subclass_t sys_subclass[] = {
1176 0x00, "PIC", NULL, NULL, pic_iface,
1180 0x01, "DMA controller", NULL, NULL, dma_iface,
1184 0x02, "system timer", NULL, NULL, tmr_iface,
1188 0x03, "RTC controller", NULL, NULL, rtc_iface,
1192 0x04, "PCI hotplug controller", NULL, NULL, NULL,
1196 0x80, "misc system peripheral", NULL, sys_devices, NULL,
1200 0xFF, NULL, NULL, NULL, NULL,
1205 static pci_subclass_t inp_subclass[] = {
1207 0x00, "keyboard controller", NULL, NULL, NULL,
1211 0x01, "digitizer", NULL, NULL, NULL,
1215 0x02, "mouse controller", NULL, NULL, NULL,
1219 0x03, "scanner controller", NULL, NULL, NULL,
1223 0x04, "gameport controller", NULL, NULL, NULL,
1227 0x80, "misc input device", NULL, NULL, NULL,
1231 0xFF, NULL, NULL, NULL, NULL,
1236 static pci_subclass_t dock_subclass[] = {
1238 0x00, "generic docking station", NULL, NULL, NULL,
1242 0x80, "misc docking station", NULL, NULL, NULL,
1246 0xFF, NULL, NULL, NULL, NULL,
1251 static pci_subclass_t cpu_subclass[] = {
1253 0x00, "i386 processor", NULL, NULL, NULL,
1257 0x01, "i486 processor", NULL, NULL, NULL,
1261 0x02, "pentium processor", NULL, NULL, NULL,
1265 0x10, "alpha processor", NULL, NULL, NULL,
1269 0x20, "PowerPC processor", NULL, NULL, NULL,
1273 0x30, "MIPS processor", NULL, NULL, NULL,
1277 0x40, "co-processor", NULL, NULL, NULL,
1281 0xFF, NULL, NULL, NULL, NULL,
1286 static pci_iface_t usb_iface[] = {
1288 0x00, "UHCI USB controller", NULL,
1292 0x10, "OHCI USB controller", NULL,
1296 0x20, "EHCI USB controller", NULL,
1300 0x80, "misc USB controller", NULL,
1304 0xFE, "USB device", NULL,
1313 static pci_iface_t ipmi_iface[] = {
1315 0x00, "IPMI SMIC interface", NULL,
1319 0x01, "IPMI keyboard interface", NULL,
1323 0x02, "IPMI block transfer interface", NULL,
1332 static pci_subclass_t ser_subclass[] = {
1334 0x00, "Firewire bus controller", "ieee1394", NULL, NULL,
1338 0x01, "ACCESS bus controller", NULL, NULL, NULL,
1342 0x02, "SSA controller", NULL, NULL, NULL,
1346 0x03, "USB controller", "usb", NULL, usb_iface,
1350 0x04, "fibre channel controller", NULL, NULL, NULL,
1354 0x05, "SMBus controller", NULL, NULL, NULL,
1358 0x06, "InfiniBand controller", NULL, NULL, NULL,
1362 0x07, "IPMI interface", NULL, NULL, ipmi_iface,
1366 0x08, "SERCOS controller", NULL, NULL, ipmi_iface,
1370 0x09, "CANbus controller", NULL, NULL, ipmi_iface,
1374 0xFF, NULL, NULL, NULL, NULL,
1379 static pci_subclass_t wrl_subclass[] = {
1381 0x00, "IRDA controller", NULL, NULL, NULL,
1385 0x01, "consumer IR controller", NULL, NULL, NULL,
1389 0x10, "RF controller", NULL, NULL, NULL,
1393 0x11, "bluetooth controller", NULL, NULL, NULL,
1397 0x12, "broadband controller", NULL, NULL, NULL,
1401 0x80, "misc wireless controller", NULL, NULL, NULL,
1405 0xFF, NULL, NULL, NULL, NULL,
1410 static pci_subclass_t sat_subclass[] = {
1412 0x01, "satellite TV controller", NULL, NULL, NULL,
1416 0x02, "satellite audio controller", NULL, NULL, NULL,
1420 0x03, "satellite voice controller", NULL, NULL, NULL,
1424 0x04, "satellite data controller", NULL, NULL, NULL,
1428 0xFF, NULL, NULL, NULL, NULL,
1433 static pci_subclass_t crypt_subclass[] = {
1435 0x00, "cryptographic network controller", NULL, NULL, NULL,
1439 0x10, "cryptographic entertainment controller", NULL, NULL, NULL,
1443 0x80, "misc cryptographic controller", NULL, NULL, NULL,
1447 0xFF, NULL, NULL, NULL, NULL,
1452 static pci_subclass_t spc_subclass[] = {
1454 0x00, "DPIO module", NULL, NULL, NULL,
1458 0x01, "performances counters", NULL, NULL, NULL,
1462 0x10, "communication synchronisation", NULL, NULL, NULL,
1466 0x20, "management card", NULL, NULL, NULL,
1470 0x80, "misc signal processing controller", NULL, NULL, NULL,
1474 0xFF, NULL, NULL, NULL, NULL,
1479 static const pci_class_t pci_classes[] = {
1481 { "undefined", NULL, undef_subclass, },
1483 { "mass-storage controller", NULL, mass_subclass, },
1485 { "network controller", "network", net_subclass, },
1487 { "display controller", "display", displ_subclass, },
1489 { "multimedia device", NULL, media_subclass, },
1491 { "memory controller", "memory-controller", mem_subclass, },
1493 { "PCI bridge", "pci", bridg_subclass, },
1495 { "communication device", NULL, comm_subclass,},
1497 { "system peripheral", NULL, sys_subclass, },
1499 { "input device", NULL, inp_subclass, },
1501 { "docking station", NULL, dock_subclass, },
1503 { "processor", NULL, cpu_subclass, },
1505 { "serial bus controller", NULL, ser_subclass, },
1507 { "wireless controller", NULL, wrl_subclass, },
1509 { "intelligent I/O controller", NULL, NULL, },
1511 { "satellite communication controller", NULL, sat_subclass, },
1513 { "cryptographic controller", NULL, crypt_subclass, },
1515 { "signal processing controller", NULL, spc_subclass, },
1518 static int macio_config_cb (pci_device_t *device)
1522 private_data = cuda_init(device->regions[0] + 0x16000);
1523 OF_finalize_pci_macio(device->common.OF_private,
1524 device->regions[0] & ~0x0000000F, device->sizes[0],
1530 static const pci_dev_t misc_pci[] = {
1531 /* Paddington Mac I/O */
1534 "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
1536 &macio_config_cb, NULL,
1538 /* KeyLargo Mac I/O */
1541 "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
1543 &macio_config_cb, NULL,
1547 NULL, NULL, NULL, NULL,
1553 static pci_dev_t *pci_find_device (uint8_t class, uint8_t subclass,
1554 uint8_t iface, uint16_t vendor,
1557 int (*config_cb)(pci_device_t *device);
1558 const pci_class_t *pclass;
1559 const pci_subclass_t *psubclass;
1560 const pci_iface_t *piface;
1561 const pci_dev_t *dev;
1562 const void *private;
1564 const unsigned char *name, *type;
1571 printf("check PCI device : %x %x (%x %x %x)\n",
1572 vendor, product, class, subclass, iface);
1574 if (class == 0x00 && subclass == 0x01) {
1575 /* Special hack for old style VGA devices */
1578 } else if (class == 0xFF) {
1579 /* Special case for misc devices */
1583 if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
1584 name = "invalid PCI device";
1588 pclass = &pci_classes[class];
1589 name = pclass->name;
1590 type = pclass->type;
1591 for (psubclass = pclass->subc; ; psubclass++) {
1592 if (psubclass->subclass == 0xFF)
1594 if (psubclass->subclass == subclass) {
1595 if (psubclass->name != NULL)
1596 name = psubclass->name;
1597 if (psubclass->type != NULL)
1598 type = psubclass->type;
1599 if (psubclass->config_cb != NULL) {
1600 config_cb = psubclass->config_cb;
1602 if (psubclass->private != NULL)
1603 private = psubclass->private;
1604 if (psubclass->iface != NULL)
1606 dev = psubclass->devices;
1610 for (piface = psubclass->iface; ; piface++) {
1611 if (piface->iface == 0xFF) {
1612 dev = psubclass->devices;
1615 if (piface->iface == iface) {
1616 if (piface->name != NULL)
1617 name = piface->name;
1618 if (piface->type != NULL)
1619 type = piface->type;
1620 if (piface->config_cb != NULL) {
1621 config_cb = piface->config_cb;
1623 if (piface->private != NULL)
1624 private = piface->private;
1625 dev = piface->devices;
1631 if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) {
1634 if (dev->vendor == vendor && dev->product == product) {
1635 if (dev->name != NULL)
1637 if (dev->type != NULL)
1639 if (dev->config_cb != NULL) {
1640 config_cb = dev->config_cb;
1642 if (dev->private != NULL)
1643 private = dev->private;
1644 new = malloc(sizeof(pci_dev_t));
1647 new->vendor = vendor;
1648 new->product = product;
1651 new->model = dev->model;
1652 new->compat = dev->compat;
1653 new->acells = dev->acells;
1654 new->scells = dev->scells;
1655 new->icells = dev->icells;
1656 new->config_cb = config_cb;
1657 new->private = private;
1663 printf("Cannot manage '%s' PCI device type '%s':\n %x %x (%x %x %x)\n",
1664 name, type, vendor, product, class, subclass, iface);
1669 /* PCI devices discovery helpers */
1670 static inline void pci_fill_common (pci_common_t *comm, pci_u_t *parent,
1671 int type, pci_dev_t *device)
1674 comm->device = device;
1675 comm->parent = parent;
1678 static inline void pci_fill_device (pci_device_t *device, pci_u_t *parent,
1679 int type, uint8_t bus, uint8_t devfn,
1680 pci_dev_t *dev, uint32_t class_code)
1682 pci_fill_common(&device->common, parent, type, dev);
1684 device->devfn = devfn;
1685 device->class_code = class_code;
1686 device->rev = class_code;
1689 static inline void pci_update_device (pci_bridge_t *bridge,
1690 pci_device_t *device,
1691 uint8_t min_grant, uint8_t max_latency,
1697 device->min_grant = min_grant;
1698 device->max_latency = max_latency;
1699 device->irq_line = irq_line;
1700 if (irq_line != -1) {
1701 pci_config_writeb(bridge, device->bus, device->devfn,
1702 0x3c, device->irq_line);
1703 printf("MAP PCI device %d:%d to IRQ %d\n",
1704 device->bus, device->devfn, irq_line);
1706 for (i = 0; i < 7; i++) {
1707 if ((device->regions[i] & ~0xF) != 0x00000000 &&
1708 (device->regions[i] & ~0xF) != 0xFFFFFFF0) {
1709 printf("Map PCI device %d:%d %d to %0x %0x (%s)\n",
1710 device->bus, device->devfn, i,
1711 device->regions[i], device->sizes[i],
1712 (device->regions[i] & 0x00000001) && i != 6 ? "I/O" :
1715 cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04);
1716 if (device->regions[i] & 0x00000001)
1720 pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd);
1723 addr = 0x30; /* PCI ROM */
1725 addr = 0x10 + (i * sizeof(uint32_t));
1726 if (device->regions[i] & 0x00000001) {
1727 pci_config_writel(bridge, device->bus, device->devfn,
1728 addr, device->regions[i] - 0x80000000);
1730 pci_config_writel(bridge, device->bus, device->devfn,
1731 addr, device->regions[i] - 0xc0000000);
1737 static pci_host_t *pci_add_host (pci_host_t **hostp, pci_dev_t *device,
1738 uint32_t class_code)
1740 pci_host_t *new, **lnk;
1742 new = malloc(sizeof(pci_host_t));
1745 pci_fill_common(&new->dev.common, NULL, PCI_HOST_BRIDGE, device);
1746 new->dev.class_code = class_code;
1747 new->dev.rev = class_code;
1748 for (lnk = hostp; *lnk != NULL; lnk = &((*lnk)->next))
1755 static pci_bridge_t *pci_add_bridge (pci_host_t *host,
1756 uint8_t bus, uint8_t devfn,
1757 pci_dev_t *dev, uint32_t class_code,
1758 uint32_t cfg_base, uint32_t cfg_len,
1759 uint32_t cfg_addr, uint32_t cfg_data,
1760 uint32_t mem_base, uint32_t mem_len,
1761 uint32_t io_base, uint32_t io_len,
1762 uint32_t rbase, uint32_t rlen,
1763 uint32_t flags, const pci_ops_t *ops)
1766 pci_bridge_t *new, **lnk;
1768 new = malloc(sizeof(pci_bridge_t));
1771 u = (pci_u_t *)host;
1772 pci_fill_device(&new->dev, u, PCI_DEV_BRIDGE, bus, devfn, dev, class_code);
1773 new->cfg_base = cfg_base;
1774 new->cfg_len = cfg_len;
1775 new->mem_base = mem_base;
1776 new->mem_len = mem_len;
1777 new->io_base = io_base;
1778 new->io_len = io_len;
1779 new->mem_cur = mem_base;
1780 if (io_base != 0x00000000)
1781 new->io_cur = io_base + 0x1000;
1783 new->io_cur = 0x00000000;
1784 new->cfg_addr = cfg_addr;
1785 new->cfg_data = cfg_data;
1790 for (lnk = &host->bridge; *lnk != NULL; lnk = &((*lnk)->next))
1797 static pci_device_t *pci_add_device (pci_bridge_t *bridge,
1798 uint8_t bus, uint8_t devfn,
1799 pci_dev_t *dev, uint32_t class_code)
1802 pci_device_t *new, **lnk;
1804 new = malloc(sizeof(pci_device_t));
1807 u = (pci_u_t *)bridge;
1808 pci_fill_device(new, u, PCI_DEV_BRIDGE, bus, devfn, dev, class_code);
1809 for (lnk = &bridge->devices; *lnk != NULL; lnk = &((*lnk)->next))
1816 static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
1817 uint8_t bus, uint8_t devfn,
1818 uint16_t checkv, uint16_t checkp,
1819 uint8_t cclass, uint8_t csubclass,
1820 uint8_t ciface, int check_bridges)
1823 pci_host_t *host, *newh;
1824 pci_bridge_t *bridge, *newb;
1827 uint32_t *io_base, *mem_base, *base;
1828 uint32_t ccode, addr, omask, amask, size, smask, reloc, min_align;
1829 uint16_t vendor, product;
1830 uint8_t class, subclass, iface, rev, min_grant, max_latency;
1831 int i, max_areas, irq_line, irq_pin;
1837 bridge = host->bridge;
1838 vendor = pci_config_readw(bridge, bus, devfn, 0x00);
1839 product = pci_config_readw(bridge, bus, devfn, 0x02);
1840 if (vendor == 0xFFFF && product == 0xFFFF) {
1841 /* No device: do nothing */
1844 ccode = pci_config_readl(bridge, bus, devfn, 0x08);
1845 class = ccode >> 24;
1846 subclass = ccode >> 16;
1849 if (checkv != 0xFFFF && vendor != checkv) {
1851 printf("Mismatching vendor for dev %x %x: %x %x\n",
1852 bus, devfn, checkv, vendor);
1856 if (checkp != 0xFFFF && product != checkp) {
1858 printf("Mismatching product for dev %x %x: %x %x\n",
1859 bus, devfn, checkp, product);
1863 if (cclass != 0xFF && class != cclass) {
1865 printf("Mismatching class for dev %x %x: %x %x\n",
1866 bus, devfn, cclass, class);
1870 if (csubclass != 0xFF && subclass != csubclass) {
1872 printf("Mismatching subclass for dev %x %x: %x %x\n",
1873 bus, devfn, csubclass, subclass);
1877 if (ciface != 0xFF && iface != ciface) {
1879 printf("Mismatching iface for dev %x %x: %x %x\n",
1880 bus, devfn, ciface, iface);
1884 dev = pci_find_device(class, subclass, iface, vendor, product);
1888 min_grant = pci_config_readb(bridge, bus, devfn, 0x3C);
1889 max_latency = pci_config_readb(bridge, bus, devfn, 0x3D);
1890 /* Special cases for bridges */
1891 if (class == 0x06) {
1892 if (check_bridges < 1)
1894 if (subclass == 0x00) {
1895 if (check_bridges < 2)
1897 /* host bridge case */
1898 printf("Found new host bridge '%s' '%s' '%s'...\n",
1899 dev->type, dev->model, dev->compat);
1900 newh = pci_add_host(phost, dev, ccode);
1902 printf("Can't allocate new host bridge...\n");
1905 ret = (pci_u_t *)newh;
1907 if ((*hostp)->bridge->dev.common.type != PCI_FAKE_BRIDGE) {
1908 printf("Keep PCI bridge\n");
1909 /* If we already found a PCI bridge, keep it */
1910 newh->bridge = (*phost)->bridge;
1913 printf("Add fake PCI bridge\n");
1914 /* Add fake PCI bridge */
1915 newh->bridge = NULL;
1917 newb = pci_add_bridge(host, bus, devfn, dev, ccode,
1918 bridge->cfg_base, bridge->cfg_len,
1919 bridge->cfg_addr, bridge->cfg_data,
1920 bridge->mem_base, bridge->mem_len,
1921 bridge->io_base, bridge->io_len,
1922 bridge->rbase, bridge->rlen,
1923 bridge->flags, dev->private);
1925 printf("Can't allocate new PCI bridge\n");
1928 newb->dev.common.type = PCI_FAKE_BRIDGE;
1929 newb->devices = bridge->devices;
1931 newh->bridge = (*hostp)->bridge;
1932 newb = newh->bridge;
1934 newd = &bridge->dev;
1936 host->dev.common.OF_private =
1937 OF_register_pci_host(dev, rev, ccode,
1938 bridge->cfg_base, bridge->cfg_len,
1939 bridge->mem_base, bridge->mem_len,
1940 bridge->io_base, bridge->io_len,
1941 bridge->rbase, bridge->rlen,
1942 min_grant, max_latency);
1944 } else if (subclass == 0x04) {
1945 /* PCI-to-PCI bridge case */
1946 printf("Found new PCI bridge '%s' '%s' '%s' '%s' %p...\n",
1947 dev->name, dev->type, dev->model, dev->compat,
1949 newb = pci_add_bridge(host, bus + 1, devfn, dev, ccode,
1950 bridge->cfg_base, bridge->cfg_len,
1951 bridge->cfg_addr, bridge->cfg_data,
1952 bridge->mem_base, bridge->mem_len,
1953 bridge->io_base, bridge->io_len,
1954 bridge->rbase, bridge->rlen,
1957 printf("Can't allocate new PCI bridge...\n");
1960 ret = (pci_u_t *)newb;
1962 printf("Config addr: 0x%0x data: 0x%0x cfg_base: 0x%08x "
1964 newb->cfg_addr, newb->cfg_data, newb->cfg_base, newb->base);
1965 printf("newb: %p hb: %p b: %p next: %p\n", newb,
1966 host->bridge, bridge, host->bridge->next);
1968 if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
1969 /* Free fake bridge if it's still present
1970 * Note: it should always be first...
1972 printf("Free fake bridge\n");
1973 newb->devices = host->bridge->devices;
1974 host->bridge = bridge->next;
1976 bridge = host->bridge;
1977 newd = &bridge->dev;
1979 printf("newb: %p hb: %p b: %p next: %p dev: %p\n", newb,
1980 host->bridge, bridge, host->bridge->next, newd);
1983 bridge->dev.common.OF_private =
1984 OF_register_pci_bridge(host->dev.common.OF_private,
1985 dev, devfn, rev, ccode,
1986 bridge->cfg_base, bridge->cfg_len,
1987 min_grant, max_latency);
1988 goto configure_device;
1990 printf("Bridges type %x aren't managed for now\n", subclass);
1995 printf("Found PCI device %x:%x %d-%d %d %d\n",
1996 vendor, product, bus, devfn, class, subclass);
1997 printf("=> '%s' '%s' '%s' '%s' (%p)\n",
1998 dev->name, dev->type, dev->model, dev->compat, dev->config_cb);
1999 newd = pci_add_device(bridge, bus, devfn, dev, ccode);
2001 printf("Cannot allocate new PCI device: %x %x (%x %x %x) '%s' '%s'\n",
2002 vendor, product, class, subclass, iface, dev->type, dev->name);
2005 ret = (pci_u_t *)newd;
2007 /* register PCI device in OF tree */
2008 if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
2009 newd->common.OF_private =
2010 OF_register_pci_device(host->dev.common.OF_private, dev, devfn,
2011 rev, ccode, min_grant, max_latency);
2013 newd->common.OF_private =
2014 OF_register_pci_device(bridge->dev.common.OF_private, dev, devfn,
2015 rev, ccode, min_grant, max_latency);
2019 printf("Config addr: 0x%08x data: 0x%08x cfg_base: 0x%08x base: 0x%08x\n",
2020 bridge->cfg_addr, bridge->cfg_data, bridge->cfg_base, bridge->base);
2021 printf("ops: %p uni-ops: %p\n", bridge->ops, &uninorth_pci_ops);
2023 io_base = &bridge->io_cur;
2024 mem_base = &bridge->mem_cur;
2026 for (i = 0; i < max_areas; i++) {
2027 newd->regions[i] = 0x00000000;
2028 newd->sizes[i] = 0x00000000;
2029 if ((omask & 0x0000000F) == 0x4) {
2030 /* Handle 64 bits memory mapping */
2034 addr = 0x30; /* PCI ROM */
2036 addr = 0x10 + (i * sizeof(uint32_t));
2038 * Note: we assume it's always a power of 2
2040 pci_config_writel(bridge, bus, devfn, addr, 0xFFFFFFFF);
2041 smask = pci_config_readl(bridge, bus, devfn, addr);
2042 if (smask == 0x00000000 || smask == 0xFFFFFFFF)
2044 if ((smask & 0x00000001) != 0 && i != 6) {
2047 /* Align to a minimum of 256 bytes (arbitrary) */
2053 /* Align to a minimum of 64 kB (arbitrary) */
2054 min_align = 1 << 16;
2057 smask |= 1; /* PCI ROM enable */
2059 omask = smask & amask;
2061 size = (~smask) + 1;
2064 printf("Relocate %s area %d of size %0x to 0x%0x (0x%0x 0x%0x %0x)\n",
2065 omask & 0x00000001 ? "I/O" : "memory", i,
2066 size, reloc, reloc + size, smask);
2068 if (size < min_align) {
2071 /* Align reloc to size */
2072 reloc = (reloc + size - 1) & ~(size - 1);
2073 (*base) = reloc + size;
2074 if (omask & 0x00000001) {
2075 /* I/O resources are offsets */
2076 reloc -= bridge->io_base;
2078 /* Set region address */
2079 newd->regions[i] = reloc | omask;
2080 newd->sizes[i] = size;
2082 /* Realign io-base to 4 kB */
2083 bridge->io_base = (bridge->io_base + (1 << 12) - 1) & ~((1 << 12) - 1);
2084 /* Realign mem-base to 1 MB */
2085 bridge->mem_base = (bridge->mem_base + (1 << 20) - 1) & ~((1 << 20) - 1);
2087 irq_pin = pci_config_readb(bridge, bus, devfn, 0x3d);
2089 /* assign the IRQ */
2090 irq_pin = ((devfn >> 3) + irq_pin - 1) & 3;
2091 /* XXX: should base it on the PCI bridge type, not the arch */
2096 irq_line = prep_pci_irqs[irq_pin];
2097 /* set the IRQ to level-sensitive */
2098 elcr_port = 0x4d0 + (irq_line >> 8);
2099 val = inb(elcr_port);
2100 val |= 1 << (irq_line & 7);
2101 outb(elcr_port, val);
2105 irq_line = pmac_pci_irqs[irq_pin];
2108 irq_line = heathrow_pci_irqs[irq_pin];
2115 pci_update_device(bridge, newd, min_grant, max_latency, irq_line);
2116 OF_finalize_pci_device(newd->common.OF_private, bus, devfn,
2117 newd->regions, newd->sizes, irq_line);
2118 /* Call special inits if needed */
2119 if (dev->config_cb != NULL)
2120 (*dev->config_cb)(newd);
2126 static int pci_check_host (pci_host_t **hostp,
2127 uint32_t cfg_base, uint32_t cfg_len,
2128 uint32_t mem_base, uint32_t mem_len,
2129 uint32_t io_base, uint32_t io_len,
2130 uint32_t rbase, uint32_t rlen,
2131 uint16_t checkv, uint16_t checkp)
2133 pci_host_t *fake_host, *host, **phost;
2134 pci_bridge_t *fake_bridge;
2143 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2146 fake_host = pci_add_host(hostp, dev,
2147 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2148 if (fake_host == NULL)
2150 fake_host->dev.common.type = PCI_FAKE_HOST;
2151 dev = &PREP_fake_bridge;
2153 goto free_fake_host;
2154 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2155 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2157 cfg_base + 0x00800000,
2158 cfg_base + 0x00C00000,
2164 if (fake_bridge == NULL)
2165 goto free_fake_host;
2166 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2172 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2175 fake_host = pci_add_host(hostp, dev,
2176 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2177 if (fake_host == NULL)
2179 fake_host->dev.common.type = PCI_FAKE_HOST;
2180 dev = &grackle_fake_bridge;
2182 goto free_fake_host;
2183 fake_bridge = pci_add_bridge(fake_host, 0, 0, dev,
2184 (0x06 << 24) | (0x04 << 16) | (0xFF << 8),
2186 cfg_base + 0x7ec00000,
2187 cfg_base + 0x7ee00000,
2193 if (fake_bridge == NULL)
2194 goto free_fake_host;
2195 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2198 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2201 fake_host = pci_add_host(hostp, dev,
2202 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2203 if (fake_host == NULL)
2205 fake_host->dev.common.type = PCI_FAKE_HOST;
2206 dev = &uninorth_fake_bridge;
2208 goto free_fake_host;
2209 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2210 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2212 cfg_base + 0x00800000,
2213 cfg_base + 0x00C00000,
2217 BRIDGE_TYPE_UNINORTH,
2219 if (fake_bridge == NULL)
2220 goto free_fake_host;
2221 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2222 fake_bridge->flags |= BRIDGE_TYPE_UNINORTH;
2230 for (bus = 0; bus < 256; bus++) {
2231 for (devfn = 0; devfn < 256; devfn++) {
2232 /* Find host bridge */
2233 pci_check_device(hostp, phost, bus, devfn,
2234 checkv, checkp, 0x06, 0x00, 0xFF, 2);
2237 OF_finalize_pci_host(host->dev.common.OF_private, bus, 1);
2244 free(fake_host->bridge);
2251 static int pci_check_devices (pci_host_t *host)
2255 /* Find all PCI bridges */
2256 printf("Check PCI bridges\n");
2257 for (bus = 0; bus < 256; bus++) {
2258 for (devfn = 0; devfn < 256; devfn++) {
2259 pci_check_device(&host, &host, bus, devfn, 0xFFFF, 0xFFFF,
2260 0x06, 0xFF, 0xFF, 1);
2263 /* Now, find all other devices */
2264 /* XXX: should recurse thru all host and bridges ! */
2265 printf("Check PCI devices\n");
2266 for (bus = 0; bus < 256; bus++) {
2267 for (devfn = 0; devfn < 256; devfn++) {
2268 pci_check_device(&host, &host, bus, devfn, 0xFFFF, 0xFFFF,
2269 0xFF, 0xFF, 0xFF, 0);
2276 pci_host_t *pci_init (void)
2278 pci_host_t *pci_main = NULL, *curh;
2279 uint32_t rbase, rlen, cfg_base, cfg_len;
2280 uint32_t mem_base, mem_len, io_base, io_len;
2283 printf("Probing PCI devices\n");
2284 /* We need to discover PCI bridges and devices */
2287 /* supposed to have 1 host bridge:
2288 * - the Motorola Raven PCI bridge
2290 cfg_base = 0x80000000;
2291 cfg_len = 0x00100000;
2292 mem_base = 0xF0000000;
2293 mem_len = 0x10000000;
2294 io_base = 0x80000000;
2295 io_len = 0x00010000;
2297 rbase = 0x80C00000; /* ? */
2301 rlen = 0x00400000; /* ? */
2302 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2303 mem_base, mem_len, io_base, io_len, rbase, rlen,
2304 0x1057, 0x4801) == 0) {
2305 isa_io_base = io_base;
2308 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2310 pci_check_devices(curh);
2316 cfg_base = 0x80000000;
2317 cfg_len = 0x7f000000;
2318 mem_base = 0x80000000;
2319 mem_len = 0x01000000;
2320 io_base = 0xfe000000;
2321 io_len = 0x00800000;
2329 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2330 mem_base, mem_len, io_base, io_len, rbase, rlen,
2331 0x1057, 0x0002) == 0) {
2332 isa_io_base = io_base;
2335 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2337 pci_check_devices(curh);
2340 /* We are supposed to have 3 host bridges:
2341 * - the uninorth AGP bridge at 0xF0000000
2342 * - the uninorth PCI expansion bridge at 0xF2000000
2343 * - the uninorth PCI internal bridge at 0xF4000000
2345 cfg_base = 0xF0000000;
2346 cfg_len = 0x02000000;
2347 mem_base = 0x90000000;
2348 mem_len = 0x10000000;
2349 io_base = 0xF0000000;
2350 io_len = 0x00800000;
2354 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2355 mem_base, mem_len, io_base, io_len, rbase, rlen,
2356 0x106b, 0x0020) == 0) {
2359 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2361 pci_check_devices(curh);
2364 cfg_base = 0xF2000000;
2365 cfg_len = 0x02000000;
2366 mem_base = 0x80000000;
2367 mem_len = 0x10000000;
2368 io_base = 0xF2000000;
2369 io_len = 0x00800000;
2377 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2378 mem_base, mem_len, io_base, io_len, rbase, rlen,
2379 0x106b, 0x001F) == 0) {
2380 isa_io_base = io_base;
2383 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2385 pci_check_devices(curh);
2388 cfg_base = 0xF4000000;
2389 cfg_len = 0x02000000;
2390 mem_base = 0xA0000000;
2391 mem_len = 0x10000000;
2392 io_base = 0xF4000000;
2393 io_len = 0x00800000;
2396 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2397 mem_base, mem_len, io_base, io_len, rbase, rlen,
2398 0x106b, 0x001F) == 0) {
2401 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2403 pci_check_devices(curh);
2410 printf("PCI probe done (%p)\n", pci_main);
2415 void pci_get_mem_range (pci_host_t *host, uint32_t *start, uint32_t *len)
2417 *start = host->bridge->mem_base;
2418 *len = host->bridge->mem_len;