Let the right reset entry point jump to the currently wrong entry point
[openhackware.git] / src / pci.c
blobd91737005a99ca48ad57ac3e95044ea18daa794a
1 /* PCI BIOS.
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
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include "bios.h"
23 //#define DEBUG_PCI 1
25 #if defined (DEBUG_PCI)
26 #define PCI_DPRINTF(fmt, args...) \
27 do { dprintf("PCI %s: " fmt, __func__ , ##args); } while (0)
28 #else
29 #define PCI_DPRINTF(fmt, args...) \
30 do { } while (0)
31 #endif
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.
41 enum {
42 /* Fake devices */
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,
51 enum {
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;
60 struct pci_iface_t {
61 uint8_t iface;
62 const unsigned char *name;
63 const unsigned char *type;
64 const pci_dev_t *devices;
65 int (*config_cb)(pci_device_t *device);
66 const void *private;
69 struct pci_subclass_t {
70 uint8_t subclass;
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);
76 const void *private;
79 struct pci_class_t {
80 const unsigned char *name;
81 const unsigned char *type;
82 const pci_subclass_t *subc;
85 /* PCI devices tree */
86 struct pci_common_t {
87 int type;
88 const pci_dev_t *device;
89 const pci_u_t *parent;
90 void *OF_private;
93 struct pci_device_t {
94 pci_common_t common;
95 uint8_t bus;
96 uint8_t devfn;
97 uint16_t rev;
98 uint32_t class_code;
99 uint16_t min_grant;
100 uint16_t max_latency;
101 uint8_t irq_line;
102 uint32_t regions[7]; /* the region 6 is the PCI ROM */
103 uint32_t sizes[7];
104 pci_device_t *next;
107 struct pci_host_t {
108 pci_device_t dev;
109 pci_bridge_t *bridge;
110 pci_host_t *next;
113 struct pci_bridge_t {
114 pci_device_t dev;
115 uint32_t cfg_base;
116 uint32_t cfg_len;
117 uint32_t io_base;
118 uint32_t io_len;
119 uint32_t io_cur;
120 uint32_t mem_base;
121 uint32_t mem_len;
122 uint32_t mem_cur;
123 uint32_t rbase;
124 uint32_t rlen;
125 uint32_t cfg_addr;
126 uint32_t cfg_data;
127 uint32_t flags;
128 const pci_ops_t *ops;
129 pci_device_t *devices;
130 pci_bridge_t *next;
133 union pci_u_t {
134 pci_common_t common;
135 pci_host_t host;
136 pci_device_t device;
137 pci_bridge_t bridge;
140 /* Low level access helpers */
141 struct pci_ops_t {
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 };
164 /* PREP PCI host */
165 static inline uint32_t PREP_cfg_addr (pci_bridge_t *bridge, unused uint8_t bus,
166 uint8_t devfn, uint8_t offset)
168 #if 0
169 printf("Translate %0x %0x %d %x %x => %0x",
170 bridge->cfg_addr, bridge->cfg_data, bus, devfn, offset,
171 bridge->cfg_addr |
172 (1 << (devfn >> 3)) | ((devfn & 7) << 8) | offset);
173 #endif
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,
180 uint8_t offset)
182 uint32_t addr;
184 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
185 return 0xFF;
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)
195 uint32_t addr;
197 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
198 return;
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,
205 uint8_t offset)
207 uint32_t addr;
209 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
210 return 0xFFFF;
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)
220 uint32_t addr;
222 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
223 return;
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,
230 uint8_t offset)
232 uint32_t addr;
234 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
235 return 0xFFFFFFFF;
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)
245 uint32_t addr;
247 if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
248 return;
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,
262 uint8_t offset)
264 uint32_t addr;
265 int i;
267 /* Kind of magic... */
268 if (bridge->cfg_base == 0xF2000000) {
269 if (bus != 0) {
270 #if 0
271 printf("Skip bus: %d dev: %x offset: %x\n", bus, devfn, offset);
272 #endif
273 return -1;
275 addr = (1 << (devfn >> 3));
276 } else {
277 addr = (bus << 16) | ((devfn & 0xF8) << 8) | 0x01;
279 addr |= ((devfn & 0x07) << 8) | (offset & 0xFC);
280 /* Avoid looping forever */
281 #if 0
282 printf("Translate %0x %0x %d %x %x => %0x",
283 bridge->cfg_addr, bridge->cfg_data, bus, devfn, offset, addr);
284 #endif
285 for (i = 0; i < 100; i++) {
286 stswap32((uint32_t *)bridge->cfg_addr, addr);
287 eieio();
288 if (ldswap32((uint32_t *)bridge->cfg_addr) == addr)
289 break;
291 if (i == 100) {
292 #if 1
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");
296 #endif
297 return -1;
299 if (bridge->flags & BRIDGE_TYPE_UNINORTH)
300 offset &= 0x07;
301 else
302 offset &= 0x03;
303 #if 0
304 printf(" %0x\n", bridge->cfg_data + offset);
305 #endif
307 return bridge->cfg_data + offset;
310 static uint8_t uninorth_config_readb (pci_bridge_t *bridge,
311 uint8_t bus, uint8_t devfn,
312 uint8_t offset)
314 uint32_t addr;
316 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
317 return 0xFF;
318 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
319 if (addr == (uint32_t)(-1))
320 return 0xFF;
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)
329 uint32_t addr;
331 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
332 return;
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,
340 uint8_t offset)
342 uint32_t addr;
344 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
345 return 0xFFFF;
346 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
347 if (addr == (uint32_t)(-1))
348 return 0xFFFF;
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)
357 uint32_t addr;
359 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
360 return;
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,
368 uint8_t offset)
370 uint32_t addr;
372 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
373 return 0xFFFFFFFF;
374 addr = macrisc_cfg_address(bridge, bus, devfn, offset);
375 if (addr == (uint32_t)(-1)) {
376 // printf("bad address -1\n");
377 return 0xFFFFFFFF;
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)
388 uint32_t addr;
390 if (bridge->cfg_base == 0xF2000000 && (devfn >> 3) < 11)
391 return;
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,
407 uint8_t offset)
409 uint32_t addr;
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,
417 uint8_t offset)
419 uint32_t addr;
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)
428 uint32_t addr;
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,
435 uint8_t offset)
437 uint32_t addr;
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)
446 uint32_t addr;
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,
453 uint8_t offset)
455 uint32_t addr;
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)
464 uint32_t addr;
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,
478 uint8_t offset)
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,
492 uint8_t offset)
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,
506 uint8_t offset)
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)
521 const pci_u_t *u;
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;
528 return NULL;
531 /* PCI devices database */
532 static pci_subclass_t undef_subclass[] = {
534 0x00, "misc undefined", NULL, NULL, NULL,
535 NULL, NULL,
538 0xFF, NULL, NULL, NULL, NULL,
539 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);
550 return 0;
553 static pci_dev_t ide_devices[] = {
555 0x1095, 0x0646, /* CMD646 IDE controller */
556 "pci-ide", "pci-ata", NULL, NULL,
557 0, 0, 0,
558 ide_config_cb2, NULL,
561 0xFFFF, 0xFFFF,
562 NULL, NULL, NULL, NULL,
563 -1, -1, -1,
564 NULL, NULL,
568 #if 0
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");
573 switch (arch) {
574 case ARCH_MAC99:
575 ide_pci_pmac_register(device->regions[0] & ~0x0000000F,
576 device->regions[1] & ~0x0000000F,
577 device->common.OF_private);
578 break;
579 default:
580 break;
582 return 0;
585 static int ata_config_cb (pci_device_t *device)
587 printf("Register ATA controller\n");
588 switch (arch) {
589 case ARCH_MAC99:
590 ide_pci_pmac_register(device->regions[0] & ~0x0000000F,
591 device->regions[1] & ~0x0000000F,
592 device->common.OF_private);
593 break;
594 default:
595 break;
598 return 0;
600 #endif
602 static pci_subclass_t mass_subclass[] = {
604 0x00, "SCSI bus controller", NULL, NULL, NULL,
605 NULL, NULL,
608 0x01, "IDE controller", "ide", ide_devices, NULL,
609 NULL, NULL,
612 0x02, "Floppy disk controller", NULL, NULL, NULL,
613 NULL, NULL,
616 0x03, "IPI bus controller", NULL, NULL, NULL,
617 NULL, NULL,
620 0x04, "RAID controller", NULL, NULL, NULL,
621 NULL, NULL,
624 0x05, "ATA controller", "ata", NULL, NULL,
625 NULL, NULL,
628 0x80, "misc mass-storage controller", NULL, NULL, NULL,
629 NULL, NULL,
632 0xFF, NULL, NULL, NULL, NULL,
633 NULL, NULL,
637 static pci_dev_t eth_devices[] = {
638 { 0x10EC, 0x8029,
639 NULL, "NE2000", "NE2000 PCI", NULL,
640 0, 0, 0,
641 NULL, "ethernet",
644 0xFFFF, 0xFFFF,
645 NULL, NULL, NULL, NULL,
646 -1, -1, -1,
647 NULL, NULL,
651 static pci_subclass_t net_subclass[] = {
653 0x00, "ethernet controller", NULL, eth_devices, NULL,
654 NULL, "ethernet",
657 0x01, "token ring controller", NULL, NULL, NULL,
658 NULL, NULL,
661 0x02, "FDDI controller", NULL, NULL, NULL,
662 NULL, NULL,
665 0x03, "ATM controller", NULL, NULL, NULL,
666 NULL, NULL,
669 0x04, "ISDN controller", NULL, NULL, NULL,
670 NULL, NULL,
673 0x05, "WordFip controller", NULL, NULL, NULL,
674 NULL, NULL,
677 0x06, "PICMG 2.14 controller", NULL, NULL, NULL,
678 NULL, NULL,
681 0x80, "misc network controller", NULL, NULL, NULL,
682 NULL, NULL,
685 0xFF, NULL, NULL, NULL, NULL,
686 NULL, NULL,
690 static pci_dev_t vga_devices[] = {
692 0x1002, 0x5046,
693 NULL, "ATY", "ATY Rage128", "VGA",
694 0, 0, 0,
695 NULL, NULL,
698 0x1234, 0x1111,
699 NULL, "Qemu VGA", "Qemu VGA", "VGA",
700 0, 0, 0,
701 NULL, NULL,
704 0xFFFF, 0xFFFF,
705 NULL, NULL, NULL, NULL,
706 -1, -1, -1,
707 NULL, NULL,
711 /* VGA configuration */
712 /* HACK... */
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);
722 /* VGA 640x480x16 */
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,
727 device->sizes[6]);
729 vga_console_register();
731 return 0;
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,
741 NULL, NULL, NULL,
744 0xFF, NULL, NULL,
745 NULL, NULL, NULL,
749 static pci_subclass_t displ_subclass[] = {
751 0x00, "display controller", NULL, NULL, vga_iface,
752 NULL, NULL,
755 0x01, "XGA display controller", NULL, NULL, NULL,
756 NULL, NULL,
759 0x02, "3D display controller", NULL, NULL, NULL,
760 NULL, NULL,
763 0x80, "misc display controller", NULL, NULL, NULL,
764 NULL, NULL,
767 0xFF, NULL, NULL, NULL, NULL,
768 NULL, NULL,
772 static pci_subclass_t media_subclass[] = {
774 0x00, "video device", NULL, NULL, NULL,
775 NULL, NULL,
778 0x01, "audio device", NULL, NULL, NULL,
779 NULL, NULL,
782 0x02, "computer telephony device", NULL, NULL, NULL,
783 NULL, NULL,
786 0x80, "misc multimedia device", NULL, NULL, NULL,
787 NULL, NULL,
790 0xFF, NULL, NULL, NULL, NULL,
791 NULL, NULL,
795 static pci_subclass_t mem_subclass[] = {
797 0x00, "RAM controller", NULL, NULL, NULL,
798 NULL, NULL,
801 0x01, "flash controller", NULL, NULL, NULL,
802 NULL, NULL,
805 0xFF, NULL, NULL, NULL, NULL,
806 NULL, NULL,
810 static pci_dev_t uninorth_agp_fake_bridge = {
811 0xFFFF, 0xFFFF,
812 "uni-north-agp", "uni-north-agp", NULL, "uni-north-agp",
813 -1, -1, -1,
814 NULL, &uninorth_pci_ops,
817 static pci_dev_t uninorth_fake_bridge = {
818 0xFFFF, 0xFFFF,
819 "uni-north", "uni-north", NULL, "uni-north",
820 -1, -1, -1,
821 NULL, &uninorth_pci_ops,
824 static pci_dev_t PREP_fake_bridge = {
825 0xFFFF, 0xFFFF,
826 "pci", "pci", NULL, "pci",
827 -1, -1, -1,
828 NULL, &PREP_pci_ops,
831 pci_dev_t grackle_fake_bridge = {
832 0xFFFF, 0xFFFF,
833 "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge",
834 -1, -1, -1,
835 NULL, &grackle_pci_ops,
838 static pci_dev_t hbrg_devices[] = {
840 0x106B, 0x0020, NULL,
841 "pci", "AAPL,UniNorth", "uni-north",
842 3, 2, 1,
843 NULL, &uninorth_agp_fake_bridge,
846 0x106B, 0x001F, NULL,
847 "pci", "AAPL,UniNorth", "uni-north",
848 3, 2, 1,
849 NULL, &uninorth_fake_bridge,
852 0x106B, 0x001E, NULL,
853 "pci", "AAPL,UniNorth", "uni-north",
854 3, 2, 1,
855 NULL, &uninorth_fake_bridge,
858 0x1057, 0x0002, "pci",
859 "pci", "MOT,MPC106", "grackle",
860 3, 2, 1,
861 NULL, &grackle_fake_bridge,
864 0x1057, 0x4801, NULL,
865 "pci-bridge", "PREP Host PCI Bridge - Motorola Raven", NULL,
866 3, 2, 1,
867 NULL, &PREP_pci_ops,
870 0xFFFF, 0xFFFF,
871 NULL, NULL, NULL, NULL,
872 -1, -1, -1,
873 NULL, NULL,
877 static pci_dev_t PCIbrg_devices[] = {
879 0x1011, 0x0026, NULL,
880 "pci-bridge", NULL, NULL,
881 3, 2, 1,
882 NULL, &PREP_pci_ops,
885 0xFFFF, 0xFFFF,
886 NULL, NULL, NULL, NULL,
887 -1, -1, -1,
888 NULL, NULL,
892 static pci_subclass_t bridg_subclass[] = {
894 0x00, "PCI host bridge", NULL, hbrg_devices, NULL,
895 NULL, NULL,
898 0x01, "ISA bridge", NULL, NULL, NULL,
899 NULL, NULL,
902 0x02, "EISA bridge", NULL, NULL, NULL,
903 NULL, NULL,
906 0x03, "MCA bridge", NULL, NULL, NULL,
907 NULL, NULL,
910 0x04, "PCI-to-PCI bridge", NULL, PCIbrg_devices, NULL,
911 NULL, NULL,
914 0x05, "PCMCIA bridge", NULL, NULL, NULL,
915 NULL, NULL,
918 0x06, "NUBUS bridge", NULL, NULL, NULL,
919 NULL, NULL,
922 0x07, "cardbus bridge", NULL, NULL, NULL,
923 NULL, NULL,
926 0x08, "raceway bridge", NULL, NULL, NULL,
927 NULL, NULL,
930 0x09, "semi-transparent PCI-to-PCI bridge", NULL, NULL, NULL,
931 NULL, NULL,
934 0x0A, "infiniband-to-PCI bridge", NULL, NULL, NULL,
935 NULL, NULL,
938 0x80, "misc PCI bridge", NULL, NULL, NULL,
939 NULL, NULL,
942 0xFF, NULL, NULL, NULL, NULL,
943 NULL, NULL,
947 static pci_iface_t serial_iface[] = {
949 0x00, "XT serial controller", NULL,
950 NULL, NULL, NULL,
953 0x01, "16450 serial controller", NULL,
954 NULL, NULL, NULL,
957 0x02, "16550 serial controller", NULL,
958 NULL, NULL, NULL,
961 0x03, "16650 serial controller", NULL,
962 NULL, NULL, NULL,
965 0x04, "16750 serial controller", NULL,
966 NULL, NULL, NULL,
969 0x05, "16850 serial controller", NULL,
970 NULL, NULL, NULL,
973 0x06, "16950 serial controller", NULL,
974 NULL, NULL, NULL,
977 0xFF, NULL, NULL,
978 NULL, NULL, NULL,
982 static pci_iface_t par_iface[] = {
984 0x00, "parallel port", NULL,
985 NULL, NULL, NULL,
988 0x01, "bi-directional parallel port", NULL,
989 NULL, NULL, NULL,
992 0x02, "ECP 1.x parallel port", NULL,
993 NULL, NULL, NULL,
996 0x03, "IEEE 1284 controller", NULL,
997 NULL, NULL, NULL,
1000 0xFE, "IEEE 1284 device", NULL,
1001 NULL, NULL, NULL,
1004 0xFF, NULL, NULL,
1005 NULL, NULL, NULL,
1009 static pci_iface_t modem_iface[] = {
1011 0x00, "generic modem", NULL,
1012 NULL, NULL, NULL,
1015 0x01, "Hayes 16450 modem", NULL,
1016 NULL, NULL, NULL,
1019 0x02, "Hayes 16550 modem", NULL,
1020 NULL, NULL, NULL,
1023 0x03, "Hayes 16650 modem", NULL,
1024 NULL, NULL, NULL,
1027 0x04, "Hayes 16750 modem", NULL,
1028 NULL, NULL, NULL,
1031 0xFF, NULL, NULL,
1032 NULL, NULL, NULL,
1036 static pci_subclass_t comm_subclass[] = {
1038 0x00, "serial controller", NULL, NULL, serial_iface,
1039 NULL, NULL,
1042 0x01, "parallel port", NULL, NULL, par_iface,
1043 NULL, NULL,
1046 0x02, "multiport serial controller", NULL, NULL, NULL,
1047 NULL, NULL,
1050 0x03, "modem", NULL, NULL, modem_iface,
1051 NULL, NULL,
1054 0x04, "GPIB controller", NULL, NULL, NULL,
1055 NULL, NULL,
1058 0x05, "smart card", NULL, NULL, NULL,
1059 NULL, NULL,
1062 0x80, "misc communication device", NULL, NULL, NULL,
1063 NULL, NULL,
1066 0xFF, NULL, NULL, NULL, NULL,
1067 NULL, NULL,
1071 static pci_iface_t pic_iface[] = {
1073 0x00, "8259 PIC", NULL,
1074 NULL, NULL, NULL,
1077 0x01, "ISA PIC", NULL,
1078 NULL, NULL, NULL,
1081 0x02, "EISA PIC", NULL,
1082 NULL, NULL, NULL,
1085 0x10, "I/O APIC", NULL,
1086 NULL, NULL, NULL,
1089 0x20, "I/O APIC", NULL,
1090 NULL, NULL, NULL,
1093 0xFF, NULL, NULL,
1094 NULL, NULL, NULL,
1098 static pci_iface_t dma_iface[] = {
1100 0x00, "8237 DMA controller", NULL,
1101 NULL, NULL, NULL,
1104 0x01, "ISA DMA controller", NULL,
1105 NULL, NULL, NULL,
1108 0x02, "EISA DMA controller", NULL,
1109 NULL, NULL, NULL,
1112 0xFF, NULL, NULL,
1113 NULL, NULL, NULL,
1117 static pci_iface_t tmr_iface[] = {
1119 0x00, "8254 system timer", NULL,
1120 NULL, NULL, NULL,
1123 0x01, "ISA system timer", NULL,
1124 NULL, NULL, NULL,
1127 0x02, "EISA system timer", NULL,
1128 NULL, NULL, NULL,
1131 0xFF, NULL, NULL,
1132 NULL, NULL, NULL,
1136 static pci_iface_t rtc_iface[] = {
1138 0x00, "generic RTC controller", NULL,
1139 NULL, NULL, NULL,
1142 0x01, "ISA RTC controller", NULL,
1143 NULL, NULL, NULL,
1146 0xFF, NULL, NULL,
1147 NULL, NULL, NULL,
1151 static const pci_dev_t sys_devices[] = {
1152 /* IBM MPIC controller */
1154 0x1014, 0x0002,
1155 "open-pic", "MPIC", NULL, "chrp,open-pic",
1156 0, 0, 2,
1157 NULL, NULL,
1159 /* IBM MPIC2 controller */
1161 0x1014, 0xFFFF,
1162 "open-pic", "MPIC2", NULL, "chrp,open-pic",
1163 0, 0, 2,
1164 NULL, NULL,
1167 0xFFFF, 0xFFFF,
1168 NULL, NULL, NULL, NULL,
1169 -1, -1, -1,
1170 NULL, NULL,
1174 static pci_subclass_t sys_subclass[] = {
1176 0x00, "PIC", NULL, NULL, pic_iface,
1177 NULL, NULL,
1180 0x01, "DMA controller", NULL, NULL, dma_iface,
1181 NULL, NULL,
1184 0x02, "system timer", NULL, NULL, tmr_iface,
1185 NULL, NULL,
1188 0x03, "RTC controller", NULL, NULL, rtc_iface,
1189 NULL, NULL,
1192 0x04, "PCI hotplug controller", NULL, NULL, NULL,
1193 NULL, NULL,
1196 0x80, "misc system peripheral", NULL, sys_devices, NULL,
1197 NULL, NULL,
1200 0xFF, NULL, NULL, NULL, NULL,
1201 NULL, NULL,
1205 static pci_subclass_t inp_subclass[] = {
1207 0x00, "keyboard controller", NULL, NULL, NULL,
1208 NULL, NULL,
1211 0x01, "digitizer", NULL, NULL, NULL,
1212 NULL, NULL,
1215 0x02, "mouse controller", NULL, NULL, NULL,
1216 NULL, NULL,
1219 0x03, "scanner controller", NULL, NULL, NULL,
1220 NULL, NULL,
1223 0x04, "gameport controller", NULL, NULL, NULL,
1224 NULL, NULL,
1227 0x80, "misc input device", NULL, NULL, NULL,
1228 NULL, NULL,
1231 0xFF, NULL, NULL, NULL, NULL,
1232 NULL, NULL,
1236 static pci_subclass_t dock_subclass[] = {
1238 0x00, "generic docking station", NULL, NULL, NULL,
1239 NULL, NULL,
1242 0x80, "misc docking station", NULL, NULL, NULL,
1243 NULL, NULL,
1246 0xFF, NULL, NULL, NULL, NULL,
1247 NULL, NULL,
1251 static pci_subclass_t cpu_subclass[] = {
1253 0x00, "i386 processor", NULL, NULL, NULL,
1254 NULL, NULL,
1257 0x01, "i486 processor", NULL, NULL, NULL,
1258 NULL, NULL,
1261 0x02, "pentium processor", NULL, NULL, NULL,
1262 NULL, NULL,
1265 0x10, "alpha processor", NULL, NULL, NULL,
1266 NULL, NULL,
1269 0x20, "PowerPC processor", NULL, NULL, NULL,
1270 NULL, NULL,
1273 0x30, "MIPS processor", NULL, NULL, NULL,
1274 NULL, NULL,
1277 0x40, "co-processor", NULL, NULL, NULL,
1278 NULL, NULL,
1281 0xFF, NULL, NULL, NULL, NULL,
1282 NULL, NULL,
1286 static pci_iface_t usb_iface[] = {
1288 0x00, "UHCI USB controller", NULL,
1289 NULL, NULL, NULL,
1292 0x10, "OHCI USB controller", NULL,
1293 NULL, NULL, NULL,
1296 0x20, "EHCI USB controller", NULL,
1297 NULL, NULL, NULL,
1300 0x80, "misc USB controller", NULL,
1301 NULL, NULL, NULL,
1304 0xFE, "USB device", NULL,
1305 NULL, NULL, NULL,
1308 0xFF, NULL, NULL,
1309 NULL, NULL, NULL,
1313 static pci_iface_t ipmi_iface[] = {
1315 0x00, "IPMI SMIC interface", NULL,
1316 NULL, NULL, NULL,
1319 0x01, "IPMI keyboard interface", NULL,
1320 NULL, NULL, NULL,
1323 0x02, "IPMI block transfer interface", NULL,
1324 NULL, NULL, NULL,
1327 0xFF, NULL, NULL,
1328 NULL, NULL, NULL,
1332 static pci_subclass_t ser_subclass[] = {
1334 0x00, "Firewire bus controller", "ieee1394", NULL, NULL,
1335 NULL, NULL,
1338 0x01, "ACCESS bus controller", NULL, NULL, NULL,
1339 NULL, NULL,
1342 0x02, "SSA controller", NULL, NULL, NULL,
1343 NULL, NULL,
1346 0x03, "USB controller", "usb", NULL, usb_iface,
1347 NULL, NULL,
1350 0x04, "fibre channel controller", NULL, NULL, NULL,
1351 NULL, NULL,
1354 0x05, "SMBus controller", NULL, NULL, NULL,
1355 NULL, NULL,
1358 0x06, "InfiniBand controller", NULL, NULL, NULL,
1359 NULL, NULL,
1362 0x07, "IPMI interface", NULL, NULL, ipmi_iface,
1363 NULL, NULL,
1366 0x08, "SERCOS controller", NULL, NULL, ipmi_iface,
1367 NULL, NULL,
1370 0x09, "CANbus controller", NULL, NULL, ipmi_iface,
1371 NULL, NULL,
1374 0xFF, NULL, NULL, NULL, NULL,
1375 NULL, NULL,
1379 static pci_subclass_t wrl_subclass[] = {
1381 0x00, "IRDA controller", NULL, NULL, NULL,
1382 NULL, NULL,
1385 0x01, "consumer IR controller", NULL, NULL, NULL,
1386 NULL, NULL,
1389 0x10, "RF controller", NULL, NULL, NULL,
1390 NULL, NULL,
1393 0x11, "bluetooth controller", NULL, NULL, NULL,
1394 NULL, NULL,
1397 0x12, "broadband controller", NULL, NULL, NULL,
1398 NULL, NULL,
1401 0x80, "misc wireless controller", NULL, NULL, NULL,
1402 NULL, NULL,
1405 0xFF, NULL, NULL, NULL, NULL,
1406 NULL, NULL,
1410 static pci_subclass_t sat_subclass[] = {
1412 0x01, "satellite TV controller", NULL, NULL, NULL,
1413 NULL, NULL,
1416 0x02, "satellite audio controller", NULL, NULL, NULL,
1417 NULL, NULL,
1420 0x03, "satellite voice controller", NULL, NULL, NULL,
1421 NULL, NULL,
1424 0x04, "satellite data controller", NULL, NULL, NULL,
1425 NULL, NULL,
1428 0xFF, NULL, NULL, NULL, NULL,
1429 NULL, NULL,
1433 static pci_subclass_t crypt_subclass[] = {
1435 0x00, "cryptographic network controller", NULL, NULL, NULL,
1436 NULL, NULL,
1439 0x10, "cryptographic entertainment controller", NULL, NULL, NULL,
1440 NULL, NULL,
1443 0x80, "misc cryptographic controller", NULL, NULL, NULL,
1444 NULL, NULL,
1447 0xFF, NULL, NULL, NULL, NULL,
1448 NULL, NULL,
1452 static pci_subclass_t spc_subclass[] = {
1454 0x00, "DPIO module", NULL, NULL, NULL,
1455 NULL, NULL,
1458 0x01, "performances counters", NULL, NULL, NULL,
1459 NULL, NULL,
1462 0x10, "communication synchronisation", NULL, NULL, NULL,
1463 NULL, NULL,
1466 0x20, "management card", NULL, NULL, NULL,
1467 NULL, NULL,
1470 0x80, "misc signal processing controller", NULL, NULL, NULL,
1471 NULL, NULL,
1474 0xFF, NULL, NULL, NULL, NULL,
1475 NULL, NULL,
1479 static const pci_class_t pci_classes[] = {
1480 /* 0x00 */
1481 { "undefined", NULL, undef_subclass, },
1482 /* 0x01 */
1483 { "mass-storage controller", NULL, mass_subclass, },
1484 /* 0x02 */
1485 { "network controller", "network", net_subclass, },
1486 /* 0x03 */
1487 { "display controller", "display", displ_subclass, },
1488 /* 0x04 */
1489 { "multimedia device", NULL, media_subclass, },
1490 /* 0x05 */
1491 { "memory controller", "memory-controller", mem_subclass, },
1492 /* 0x06 */
1493 { "PCI bridge", "pci", bridg_subclass, },
1494 /* 0x07 */
1495 { "communication device", NULL, comm_subclass,},
1496 /* 0x08 */
1497 { "system peripheral", NULL, sys_subclass, },
1498 /* 0x09 */
1499 { "input device", NULL, inp_subclass, },
1500 /* 0x0A */
1501 { "docking station", NULL, dock_subclass, },
1502 /* 0x0B */
1503 { "processor", NULL, cpu_subclass, },
1504 /* 0x0C */
1505 { "serial bus controller", NULL, ser_subclass, },
1506 /* 0x0D */
1507 { "wireless controller", NULL, wrl_subclass, },
1508 /* 0x0E */
1509 { "intelligent I/O controller", NULL, NULL, },
1510 /* 0x0F */
1511 { "satellite communication controller", NULL, sat_subclass, },
1512 /* 0x10 */
1513 { "cryptographic controller", NULL, crypt_subclass, },
1514 /* 0x11 */
1515 { "signal processing controller", NULL, spc_subclass, },
1518 static int macio_config_cb (pci_device_t *device)
1520 void *private_data;
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],
1525 private_data);
1527 return 0;
1530 static const pci_dev_t misc_pci[] = {
1531 /* Paddington Mac I/O */
1533 0x106B, 0x0017,
1534 "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
1535 1, 1, 1,
1536 &macio_config_cb, NULL,
1538 /* KeyLargo Mac I/O */
1540 0x106B, 0x0022,
1541 "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
1542 1, 1, 2,
1543 &macio_config_cb, NULL,
1546 0xFFFF, 0xFFFF,
1547 NULL, NULL, NULL, NULL,
1548 -1, -1, -1,
1549 NULL, NULL,
1553 static pci_dev_t *pci_find_device (uint8_t class, uint8_t subclass,
1554 uint8_t iface, uint16_t vendor,
1555 uint16_t product)
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;
1563 pci_dev_t *new;
1564 const unsigned char *name, *type;
1566 name = "unknown";
1567 type = "unknown";
1568 config_cb = NULL;
1569 private = NULL;
1570 #if 0
1571 printf("check PCI device : %x %x (%x %x %x)\n",
1572 vendor, product, class, subclass, iface);
1573 #endif
1574 if (class == 0x00 && subclass == 0x01) {
1575 /* Special hack for old style VGA devices */
1576 class = 0x03;
1577 subclass = 0x00;
1578 } else if (class == 0xFF) {
1579 /* Special case for misc devices */
1580 dev = misc_pci;
1581 goto find_device;
1583 if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
1584 name = "invalid PCI device";
1585 type = "invalid";
1586 goto bad_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)
1593 goto bad_device;
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)
1605 break;
1606 dev = psubclass->devices;
1607 goto find_device;
1610 for (piface = psubclass->iface; ; piface++) {
1611 if (piface->iface == 0xFF) {
1612 dev = psubclass->devices;
1613 break;
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;
1626 break;
1629 find_device:
1630 for (;; dev++) {
1631 if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) {
1632 goto bad_device;
1634 if (dev->vendor == vendor && dev->product == product) {
1635 if (dev->name != NULL)
1636 name = dev->name;
1637 if (dev->type != NULL)
1638 type = dev->type;
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));
1645 if (new == NULL)
1646 return NULL;
1647 new->vendor = vendor;
1648 new->product = product;
1649 new->type = type;
1650 new->name = name;
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;
1659 return new;
1662 bad_device:
1663 printf("Cannot manage '%s' PCI device type '%s':\n %x %x (%x %x %x)\n",
1664 name, type, vendor, product, class, subclass, iface);
1666 return NULL;
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)
1673 comm->type = type;
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);
1683 device->bus = bus;
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,
1692 int irq_line)
1694 uint32_t cmd, addr;
1695 int i;
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" :
1713 "memory");
1714 if (i != 6) {
1715 cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04);
1716 if (device->regions[i] & 0x00000001)
1717 cmd |= 0x00000001;
1718 else
1719 cmd |= 0x00000002;
1720 pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd);
1722 if (i == 6)
1723 addr = 0x30; /* PCI ROM */
1724 else
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);
1729 } else {
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));
1743 if (new == NULL)
1744 return NULL;
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))
1749 continue;
1750 *lnk = new;
1752 return new;
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)
1765 pci_u_t *u;
1766 pci_bridge_t *new, **lnk;
1768 new = malloc(sizeof(pci_bridge_t));
1769 if (new == NULL)
1770 return NULL;
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;
1782 else
1783 new->io_cur = 0x00000000;
1784 new->cfg_addr = cfg_addr;
1785 new->cfg_data = cfg_data;
1786 new->rbase = rbase;
1787 new->rlen = rlen;
1788 new->flags = flags;
1789 new->ops = ops;
1790 for (lnk = &host->bridge; *lnk != NULL; lnk = &((*lnk)->next))
1791 continue;
1792 *lnk = new;
1794 return new;
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)
1801 pci_u_t *u;
1802 pci_device_t *new, **lnk;
1804 new = malloc(sizeof(pci_device_t));
1805 if (new == NULL)
1806 return NULL;
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))
1810 continue;
1811 *lnk = new;
1813 return new;
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)
1822 pci_u_t *ret;
1823 pci_host_t *host, *newh;
1824 pci_bridge_t *bridge, *newb;
1825 pci_device_t *newd;
1826 pci_dev_t *dev;
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;
1833 ret = NULL;
1834 newd = NULL;
1835 host = *hostp;
1836 irq_line = -1;
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 */
1842 goto out;
1844 ccode = pci_config_readl(bridge, bus, devfn, 0x08);
1845 class = ccode >> 24;
1846 subclass = ccode >> 16;
1847 iface = ccode >> 8;
1848 rev = ccode;
1849 if (checkv != 0xFFFF && vendor != checkv) {
1850 #if 0
1851 printf("Mismatching vendor for dev %x %x: %x %x\n",
1852 bus, devfn, checkv, vendor);
1853 #endif
1854 goto out;
1856 if (checkp != 0xFFFF && product != checkp) {
1857 #if 0
1858 printf("Mismatching product for dev %x %x: %x %x\n",
1859 bus, devfn, checkp, product);
1860 #endif
1861 goto out;
1863 if (cclass != 0xFF && class != cclass) {
1864 #if 0
1865 printf("Mismatching class for dev %x %x: %x %x\n",
1866 bus, devfn, cclass, class);
1867 #endif
1868 goto out;
1870 if (csubclass != 0xFF && subclass != csubclass) {
1871 #if 0
1872 printf("Mismatching subclass for dev %x %x: %x %x\n",
1873 bus, devfn, csubclass, subclass);
1874 #endif
1875 goto out;
1877 if (ciface != 0xFF && iface != ciface) {
1878 #if 0
1879 printf("Mismatching iface for dev %x %x: %x %x\n",
1880 bus, devfn, ciface, iface);
1881 #endif
1882 goto out;
1884 dev = pci_find_device(class, subclass, iface, vendor, product);
1885 if (dev == NULL) {
1886 goto out;
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)
1893 goto out;
1894 if (subclass == 0x00) {
1895 if (check_bridges < 2)
1896 goto out;
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);
1901 if (newh == NULL) {
1902 printf("Can't allocate new host bridge...\n");
1903 goto out;
1905 ret = (pci_u_t *)newh;
1906 #if 0
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;
1911 goto out;
1913 printf("Add fake PCI bridge\n");
1914 /* Add fake PCI bridge */
1915 newh->bridge = NULL;
1916 dev = dev->private;
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);
1924 if (newb == NULL) {
1925 printf("Can't allocate new PCI bridge\n");
1926 goto out;
1928 newb->dev.common.type = PCI_FAKE_BRIDGE;
1929 newb->devices = bridge->devices;
1930 #else
1931 newh->bridge = (*hostp)->bridge;
1932 newb = newh->bridge;
1933 #endif
1934 newd = &bridge->dev;
1935 host = newh;
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);
1943 goto update_device;
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,
1948 dev->private);
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,
1955 0, dev->private);
1956 if (newb == NULL) {
1957 printf("Can't allocate new PCI bridge...\n");
1958 goto out;
1960 ret = (pci_u_t *)newb;
1961 #if 0
1962 printf("Config addr: 0x%0x data: 0x%0x cfg_base: 0x%08x "
1963 "base: 0x%0x\n",
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);
1967 #endif
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;
1978 #if 0
1979 printf("newb: %p hb: %p b: %p next: %p dev: %p\n", newb,
1980 host->bridge, bridge, host->bridge->next, newd);
1981 #endif
1982 max_areas = 2;
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);
1991 free(dev);
1992 goto out;
1994 /* Main case */
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);
2000 if (newd == NULL) {
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);
2003 goto out;
2005 ret = (pci_u_t *)newd;
2006 max_areas = 7;
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);
2012 } else {
2013 newd->common.OF_private =
2014 OF_register_pci_device(bridge->dev.common.OF_private, dev, devfn,
2015 rev, ccode, min_grant, max_latency);
2017 configure_device:
2018 #if 0
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);
2022 #endif
2023 io_base = &bridge->io_cur;
2024 mem_base = &bridge->mem_cur;
2025 omask = 0x00000000;
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 */
2031 continue;
2033 if (i == 6)
2034 addr = 0x30; /* PCI ROM */
2035 else
2036 addr = 0x10 + (i * sizeof(uint32_t));
2037 /* Get region size
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)
2043 continue;
2044 if ((smask & 0x00000001) != 0 && i != 6) {
2045 /* I/O space */
2046 base = io_base;
2047 /* Align to a minimum of 256 bytes (arbitrary) */
2048 min_align = 1 << 8;
2049 amask = 0x00000001;
2050 } else {
2051 /* Memory space */
2052 base = mem_base;
2053 /* Align to a minimum of 64 kB (arbitrary) */
2054 min_align = 1 << 16;
2055 amask = 0x0000000F;
2056 if (i == 6)
2057 smask |= 1; /* PCI ROM enable */
2059 omask = smask & amask;
2060 smask &= ~amask;
2061 size = (~smask) + 1;
2062 reloc = *base;
2063 #if 0
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);
2067 #endif
2068 if (size < min_align) {
2069 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);
2088 if (irq_pin > 0) {
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 */
2092 switch(arch) {
2093 case ARCH_PREP:
2095 int elcr_port, val;
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);
2103 break;
2104 case ARCH_MAC99:
2105 irq_line = pmac_pci_irqs[irq_pin];
2106 break;
2107 case ARCH_HEATHROW:
2108 irq_line = heathrow_pci_irqs[irq_pin];
2109 break;
2110 default:
2111 break;
2114 update_device:
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);
2122 out:
2123 return ret;
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;
2135 pci_dev_t *dev;
2136 int bus, devfn;
2137 int ret;
2139 fake_host = NULL;
2140 ret = -1;
2141 switch (arch) {
2142 case ARCH_PREP:
2143 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2144 if (dev == NULL)
2145 return -1;
2146 fake_host = pci_add_host(hostp, dev,
2147 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2148 if (fake_host == NULL)
2149 return -1;
2150 fake_host->dev.common.type = PCI_FAKE_HOST;
2151 dev = &PREP_fake_bridge;
2152 if (dev == NULL)
2153 goto free_fake_host;
2154 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2155 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2156 cfg_base, cfg_len,
2157 cfg_base + 0x00800000,
2158 cfg_base + 0x00C00000,
2159 mem_base, mem_len,
2160 io_base, io_len,
2161 rbase, rlen,
2163 &PREP_pci_ops);
2164 if (fake_bridge == NULL)
2165 goto free_fake_host;
2166 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2167 break;
2168 case ARCH_CHRP:
2169 /* TODO */
2170 break;
2171 case ARCH_HEATHROW:
2172 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2173 if (dev == NULL)
2174 return -1;
2175 fake_host = pci_add_host(hostp, dev,
2176 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2177 if (fake_host == NULL)
2178 return -1;
2179 fake_host->dev.common.type = PCI_FAKE_HOST;
2180 dev = &grackle_fake_bridge;
2181 if (dev == NULL)
2182 goto free_fake_host;
2183 fake_bridge = pci_add_bridge(fake_host, 0, 0, dev,
2184 (0x06 << 24) | (0x04 << 16) | (0xFF << 8),
2185 cfg_base, cfg_len,
2186 cfg_base + 0x7ec00000,
2187 cfg_base + 0x7ee00000,
2188 mem_base, mem_len,
2189 io_base, io_len,
2190 rbase, rlen,
2192 &grackle_pci_ops);
2193 if (fake_bridge == NULL)
2194 goto free_fake_host;
2195 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2196 break;
2197 case ARCH_MAC99:
2198 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2199 if (dev == NULL)
2200 return -1;
2201 fake_host = pci_add_host(hostp, dev,
2202 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2203 if (fake_host == NULL)
2204 return -1;
2205 fake_host->dev.common.type = PCI_FAKE_HOST;
2206 dev = &uninorth_fake_bridge;
2207 if (dev == NULL)
2208 goto free_fake_host;
2209 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2210 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2211 cfg_base, cfg_len,
2212 cfg_base + 0x00800000,
2213 cfg_base + 0x00C00000,
2214 mem_base, mem_len,
2215 io_base, io_len,
2216 rbase, rlen,
2217 BRIDGE_TYPE_UNINORTH,
2218 &uninorth_pci_ops);
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;
2223 break;
2224 case ARCH_POP:
2225 /* TODO */
2226 break;
2228 host = NULL;
2229 phost = &host;
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);
2235 if (host != NULL) {
2236 *hostp = host;
2237 OF_finalize_pci_host(host->dev.common.OF_private, bus, 1);
2238 ret = 0;
2239 goto done;
2243 done:
2244 free(fake_host->bridge);
2245 free_fake_host:
2246 free(fake_host);
2248 return ret;
2251 static int pci_check_devices (pci_host_t *host)
2253 int bus, devfn;
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);
2273 return 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;
2281 uint8_t busnum;
2283 printf("Probing PCI devices\n");
2284 /* We need to discover PCI bridges and devices */
2285 switch (arch) {
2286 case ARCH_PREP:
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;
2296 #if 0
2297 rbase = 0x80C00000; /* ? */
2298 #else
2299 rbase = 0x00000000;
2300 #endif
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;
2306 busnum++;
2308 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2309 continue;
2310 pci_check_devices(curh);
2311 break;
2312 case ARCH_CHRP:
2313 /* TODO */
2314 break;
2315 case ARCH_HEATHROW:
2316 cfg_base = 0x80000000;
2317 cfg_len = 0x7f000000;
2318 mem_base = 0x80000000;
2319 mem_len = 0x01000000;
2320 io_base = 0xfe000000;
2321 io_len = 0x00800000;
2322 #if 1
2323 rbase = 0xfd000000;
2324 rlen = 0x01000000;
2325 #else
2326 rbase = 0x00000000;
2327 rlen = 0x01000000;
2328 #endif
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;
2333 busnum++;
2335 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2336 continue;
2337 pci_check_devices(curh);
2338 break;
2339 case ARCH_MAC99:
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;
2351 rbase = 0xF1000000;
2352 rlen = 0x01000000;
2353 #if 0
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) {
2357 busnum++;
2359 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2360 continue;
2361 pci_check_devices(curh);
2362 #endif
2364 cfg_base = 0xF2000000;
2365 cfg_len = 0x02000000;
2366 mem_base = 0x80000000;
2367 mem_len = 0x10000000;
2368 io_base = 0xF2000000;
2369 io_len = 0x00800000;
2370 #if 0 // Hack
2371 rbase = 0xF3000000;
2372 rlen = 0x01000000;
2373 #else
2374 rbase = 0x00000000;
2375 rlen = 0x01000000;
2376 #endif
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;
2381 busnum++;
2383 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2384 continue;
2385 pci_check_devices(curh);
2387 #if 0
2388 cfg_base = 0xF4000000;
2389 cfg_len = 0x02000000;
2390 mem_base = 0xA0000000;
2391 mem_len = 0x10000000;
2392 io_base = 0xF4000000;
2393 io_len = 0x00800000;
2394 rbase = 0xF5000000;
2395 rlen = 0x01000000;
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) {
2399 busnum++;
2401 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2402 continue;
2403 pci_check_devices(curh);
2404 #endif
2405 break;
2406 case ARCH_POP:
2407 /* TODO */
2408 break;
2410 printf("PCI probe done (%p)\n", pci_main);
2412 return 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;