Fix compilation with biarch compilers
[openhackware.git] / src / pci.c
blob38aad27acffbd83e84ff50b0856db5b808c90cb0
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 pci_config_writel(bridge, device->bus, device->devfn,
1727 addr, device->regions[i]);
1732 static pci_host_t *pci_add_host (pci_host_t **hostp, pci_dev_t *device,
1733 uint32_t class_code)
1735 pci_host_t *new, **lnk;
1737 new = malloc(sizeof(pci_host_t));
1738 if (new == NULL)
1739 return NULL;
1740 pci_fill_common(&new->dev.common, NULL, PCI_HOST_BRIDGE, device);
1741 new->dev.class_code = class_code;
1742 new->dev.rev = class_code;
1743 for (lnk = hostp; *lnk != NULL; lnk = &((*lnk)->next))
1744 continue;
1745 *lnk = new;
1747 return new;
1750 static pci_bridge_t *pci_add_bridge (pci_host_t *host,
1751 uint8_t bus, uint8_t devfn,
1752 pci_dev_t *dev, uint32_t class_code,
1753 uint32_t cfg_base, uint32_t cfg_len,
1754 uint32_t cfg_addr, uint32_t cfg_data,
1755 uint32_t mem_base, uint32_t mem_len,
1756 uint32_t io_base, uint32_t io_len,
1757 uint32_t rbase, uint32_t rlen,
1758 uint32_t flags, const pci_ops_t *ops)
1760 pci_u_t *u;
1761 pci_bridge_t *new, **lnk;
1763 new = malloc(sizeof(pci_bridge_t));
1764 if (new == NULL)
1765 return NULL;
1766 u = (pci_u_t *)host;
1767 pci_fill_device(&new->dev, u, PCI_DEV_BRIDGE, bus, devfn, dev, class_code);
1768 new->cfg_base = cfg_base;
1769 new->cfg_len = cfg_len;
1770 new->mem_base = mem_base;
1771 new->mem_len = mem_len;
1772 new->io_base = io_base;
1773 new->io_len = io_len;
1774 new->mem_cur = mem_base;
1775 if (io_base != 0x00000000)
1776 new->io_cur = io_base + 0x1000;
1777 else
1778 new->io_cur = 0x00000000;
1779 new->cfg_addr = cfg_addr;
1780 new->cfg_data = cfg_data;
1781 new->rbase = rbase;
1782 new->rlen = rlen;
1783 new->flags = flags;
1784 new->ops = ops;
1785 for (lnk = &host->bridge; *lnk != NULL; lnk = &((*lnk)->next))
1786 continue;
1787 *lnk = new;
1789 return new;
1792 static pci_device_t *pci_add_device (pci_bridge_t *bridge,
1793 uint8_t bus, uint8_t devfn,
1794 pci_dev_t *dev, uint32_t class_code)
1796 pci_u_t *u;
1797 pci_device_t *new, **lnk;
1799 new = malloc(sizeof(pci_device_t));
1800 if (new == NULL)
1801 return NULL;
1802 u = (pci_u_t *)bridge;
1803 pci_fill_device(new, u, PCI_DEV_BRIDGE, bus, devfn, dev, class_code);
1804 for (lnk = &bridge->devices; *lnk != NULL; lnk = &((*lnk)->next))
1805 continue;
1806 *lnk = new;
1808 return new;
1811 static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
1812 uint8_t bus, uint8_t devfn,
1813 uint16_t checkv, uint16_t checkp,
1814 uint8_t cclass, uint8_t csubclass,
1815 uint8_t ciface, int check_bridges)
1817 pci_u_t *ret;
1818 pci_host_t *host, *newh;
1819 pci_bridge_t *bridge, *newb;
1820 pci_device_t *newd;
1821 pci_dev_t *dev;
1822 uint32_t *io_base, *mem_base, *base;
1823 uint32_t ccode, addr, omask, amask, size, smask, reloc, min_align;
1824 uint16_t vendor, product;
1825 uint8_t class, subclass, iface, rev, min_grant, max_latency;
1826 int i, max_areas, irq_line, irq_pin;
1828 ret = NULL;
1829 newd = NULL;
1830 host = *hostp;
1831 irq_line = -1;
1832 bridge = host->bridge;
1833 vendor = pci_config_readw(bridge, bus, devfn, 0x00);
1834 product = pci_config_readw(bridge, bus, devfn, 0x02);
1835 if (vendor == 0xFFFF && product == 0xFFFF) {
1836 /* No device: do nothing */
1837 goto out;
1839 ccode = pci_config_readl(bridge, bus, devfn, 0x08);
1840 class = ccode >> 24;
1841 subclass = ccode >> 16;
1842 iface = ccode >> 8;
1843 rev = ccode;
1844 if (checkv != 0xFFFF && vendor != checkv) {
1845 #if 0
1846 printf("Mismatching vendor for dev %x %x: %x %x\n",
1847 bus, devfn, checkv, vendor);
1848 #endif
1849 goto out;
1851 if (checkp != 0xFFFF && product != checkp) {
1852 #if 0
1853 printf("Mismatching product for dev %x %x: %x %x\n",
1854 bus, devfn, checkp, product);
1855 #endif
1856 goto out;
1858 if (cclass != 0xFF && class != cclass) {
1859 #if 0
1860 printf("Mismatching class for dev %x %x: %x %x\n",
1861 bus, devfn, cclass, class);
1862 #endif
1863 goto out;
1865 if (csubclass != 0xFF && subclass != csubclass) {
1866 #if 0
1867 printf("Mismatching subclass for dev %x %x: %x %x\n",
1868 bus, devfn, csubclass, subclass);
1869 #endif
1870 goto out;
1872 if (ciface != 0xFF && iface != ciface) {
1873 #if 0
1874 printf("Mismatching iface for dev %x %x: %x %x\n",
1875 bus, devfn, ciface, iface);
1876 #endif
1877 goto out;
1879 dev = pci_find_device(class, subclass, iface, vendor, product);
1880 if (dev == NULL) {
1881 goto out;
1883 min_grant = pci_config_readb(bridge, bus, devfn, 0x3C);
1884 max_latency = pci_config_readb(bridge, bus, devfn, 0x3D);
1885 /* Special cases for bridges */
1886 if (class == 0x06) {
1887 if (check_bridges < 1)
1888 goto out;
1889 if (subclass == 0x00) {
1890 if (check_bridges < 2)
1891 goto out;
1892 /* host bridge case */
1893 printf("Found new host bridge '%s' '%s' '%s'...\n",
1894 dev->type, dev->model, dev->compat);
1895 newh = pci_add_host(phost, dev, ccode);
1896 if (newh == NULL) {
1897 printf("Can't allocate new host bridge...\n");
1898 goto out;
1900 ret = (pci_u_t *)newh;
1901 #if 0
1902 if ((*hostp)->bridge->dev.common.type != PCI_FAKE_BRIDGE) {
1903 printf("Keep PCI bridge\n");
1904 /* If we already found a PCI bridge, keep it */
1905 newh->bridge = (*phost)->bridge;
1906 goto out;
1908 printf("Add fake PCI bridge\n");
1909 /* Add fake PCI bridge */
1910 newh->bridge = NULL;
1911 dev = dev->private;
1912 newb = pci_add_bridge(host, bus, devfn, dev, ccode,
1913 bridge->cfg_base, bridge->cfg_len,
1914 bridge->cfg_addr, bridge->cfg_data,
1915 bridge->mem_base, bridge->mem_len,
1916 bridge->io_base, bridge->io_len,
1917 bridge->rbase, bridge->rlen,
1918 bridge->flags, dev->private);
1919 if (newb == NULL) {
1920 printf("Can't allocate new PCI bridge\n");
1921 goto out;
1923 newb->dev.common.type = PCI_FAKE_BRIDGE;
1924 newb->devices = bridge->devices;
1925 #else
1926 newh->bridge = (*hostp)->bridge;
1927 newb = newh->bridge;
1928 #endif
1929 newd = &bridge->dev;
1930 host = newh;
1931 host->dev.common.OF_private =
1932 OF_register_pci_host(dev, rev, ccode,
1933 bridge->cfg_base, bridge->cfg_len,
1934 bridge->mem_base, bridge->mem_len,
1935 bridge->io_base, bridge->io_len,
1936 bridge->rbase, bridge->rlen,
1937 min_grant, max_latency);
1938 goto update_device;
1939 } else if (subclass == 0x04) {
1940 /* PCI-to-PCI bridge case */
1941 printf("Found new PCI bridge '%s' '%s' '%s' '%s' %p...\n",
1942 dev->name, dev->type, dev->model, dev->compat,
1943 dev->private);
1944 newb = pci_add_bridge(host, bus + 1, devfn, dev, ccode,
1945 bridge->cfg_base, bridge->cfg_len,
1946 bridge->cfg_addr, bridge->cfg_data,
1947 bridge->mem_base, bridge->mem_len,
1948 bridge->io_base, bridge->io_len,
1949 bridge->rbase, bridge->rlen,
1950 0, dev->private);
1951 if (newb == NULL) {
1952 printf("Can't allocate new PCI bridge...\n");
1953 goto out;
1955 ret = (pci_u_t *)newb;
1956 #if 0
1957 printf("Config addr: 0x%0x data: 0x%0x cfg_base: 0x%08x "
1958 "base: 0x%0x\n",
1959 newb->cfg_addr, newb->cfg_data, newb->cfg_base, newb->base);
1960 printf("newb: %p hb: %p b: %p next: %p\n", newb,
1961 host->bridge, bridge, host->bridge->next);
1962 #endif
1963 if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
1964 /* Free fake bridge if it's still present
1965 * Note: it should always be first...
1967 printf("Free fake bridge\n");
1968 newb->devices = host->bridge->devices;
1969 host->bridge = bridge->next;
1971 bridge = host->bridge;
1972 newd = &bridge->dev;
1973 #if 0
1974 printf("newb: %p hb: %p b: %p next: %p dev: %p\n", newb,
1975 host->bridge, bridge, host->bridge->next, newd);
1976 #endif
1977 max_areas = 2;
1978 bridge->dev.common.OF_private =
1979 OF_register_pci_bridge(host->dev.common.OF_private,
1980 dev, devfn, rev, ccode,
1981 bridge->cfg_base, bridge->cfg_len,
1982 min_grant, max_latency);
1983 goto configure_device;
1985 printf("Bridges type %x aren't managed for now\n", subclass);
1986 free(dev);
1987 goto out;
1989 /* Main case */
1990 printf("Found PCI device %x:%x %d-%d %d %d\n",
1991 vendor, product, bus, devfn, class, subclass);
1992 printf("=> '%s' '%s' '%s' '%s' (%p)\n",
1993 dev->name, dev->type, dev->model, dev->compat, dev->config_cb);
1994 newd = pci_add_device(bridge, bus, devfn, dev, ccode);
1995 if (newd == NULL) {
1996 printf("Cannot allocate new PCI device: %x %x (%x %x %x) '%s' '%s'\n",
1997 vendor, product, class, subclass, iface, dev->type, dev->name);
1998 goto out;
2000 ret = (pci_u_t *)newd;
2001 max_areas = 7;
2002 /* register PCI device in OF tree */
2003 if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
2004 newd->common.OF_private =
2005 OF_register_pci_device(host->dev.common.OF_private, dev, devfn,
2006 rev, ccode, min_grant, max_latency);
2007 } else {
2008 newd->common.OF_private =
2009 OF_register_pci_device(bridge->dev.common.OF_private, dev, devfn,
2010 rev, ccode, min_grant, max_latency);
2012 configure_device:
2013 #if 0
2014 printf("Config addr: 0x%08x data: 0x%08x cfg_base: 0x%08x base: 0x%08x\n",
2015 bridge->cfg_addr, bridge->cfg_data, bridge->cfg_base, bridge->base);
2016 printf("ops: %p uni-ops: %p\n", bridge->ops, &uninorth_pci_ops);
2017 #endif
2018 io_base = &bridge->io_cur;
2019 mem_base = &bridge->mem_cur;
2020 omask = 0x00000000;
2021 for (i = 0; i < max_areas; i++) {
2022 newd->regions[i] = 0x00000000;
2023 newd->sizes[i] = 0x00000000;
2024 if ((omask & 0x0000000F) == 0x4) {
2025 /* Handle 64 bits memory mapping */
2026 continue;
2028 if (i == 6)
2029 addr = 0x30; /* PCI ROM */
2030 else
2031 addr = 0x10 + (i * sizeof(uint32_t));
2032 /* Get region size
2033 * Note: we assume it's always a power of 2
2035 pci_config_writel(bridge, bus, devfn, addr, 0xFFFFFFFF);
2036 smask = pci_config_readl(bridge, bus, devfn, addr);
2037 if (smask == 0x00000000 || smask == 0xFFFFFFFF)
2038 continue;
2039 if ((smask & 0x00000001) != 0 && i != 6) {
2040 /* I/O space */
2041 base = io_base;
2042 /* Align to a minimum of 256 bytes (arbitrary) */
2043 min_align = 1 << 8;
2044 amask = 0x00000001;
2045 } else {
2046 /* Memory space */
2047 base = mem_base;
2048 /* Align to a minimum of 64 kB (arbitrary) */
2049 min_align = 1 << 16;
2050 amask = 0x0000000F;
2051 if (i == 6)
2052 smask |= 1; /* PCI ROM enable */
2054 omask = smask & amask;
2055 smask &= ~amask;
2056 size = (~smask) + 1;
2057 reloc = *base;
2058 #if 0
2059 printf("Relocate %s area %d of size %0x to 0x%0x (0x%0x 0x%0x %0x)\n",
2060 omask & 0x00000001 ? "I/O" : "memory", i,
2061 size, reloc, reloc + size, smask);
2062 #endif
2063 if (size < min_align) {
2064 size = min_align;
2066 /* Align reloc to size */
2067 reloc = (reloc + size - 1) & ~(size - 1);
2068 (*base) = reloc + size;
2069 if (omask & 0x00000001) {
2070 /* I/O resources are offsets */
2071 reloc -= bridge->io_base;
2073 /* Set region address */
2074 newd->regions[i] = reloc | omask;
2075 newd->sizes[i] = size;
2077 /* Realign io-base to 4 kB */
2078 bridge->io_base = (bridge->io_base + (1 << 12) - 1) & ~((1 << 12) - 1);
2079 /* Realign mem-base to 1 MB */
2080 bridge->mem_base = (bridge->mem_base + (1 << 20) - 1) & ~((1 << 20) - 1);
2082 irq_pin = pci_config_readb(bridge, bus, devfn, 0x3d);
2083 if (irq_pin > 0) {
2084 /* assign the IRQ */
2085 irq_pin = ((devfn >> 3) + irq_pin - 1) & 3;
2086 /* XXX: should base it on the PCI bridge type, not the arch */
2087 switch(arch) {
2088 case ARCH_PREP:
2090 int elcr_port, val;
2091 irq_line = prep_pci_irqs[irq_pin];
2092 /* set the IRQ to level-sensitive */
2093 elcr_port = 0x4d0 + (irq_line >> 8);
2094 val = inb(elcr_port);
2095 val |= 1 << (irq_line & 7);
2096 outb(elcr_port, val);
2098 break;
2099 case ARCH_MAC99:
2100 irq_line = pmac_pci_irqs[irq_pin];
2101 break;
2102 case ARCH_HEATHROW:
2103 irq_line = heathrow_pci_irqs[irq_pin];
2104 break;
2105 default:
2106 break;
2109 update_device:
2110 pci_update_device(bridge, newd, min_grant, max_latency, irq_line);
2111 OF_finalize_pci_device(newd->common.OF_private, bus, devfn,
2112 newd->regions, newd->sizes, irq_line);
2113 /* Call special inits if needed */
2114 if (dev->config_cb != NULL)
2115 (*dev->config_cb)(newd);
2117 out:
2118 return ret;
2121 static int pci_check_host (pci_host_t **hostp,
2122 uint32_t cfg_base, uint32_t cfg_len,
2123 uint32_t mem_base, uint32_t mem_len,
2124 uint32_t io_base, uint32_t io_len,
2125 uint32_t rbase, uint32_t rlen,
2126 uint16_t checkv, uint16_t checkp)
2128 pci_host_t *fake_host, *host, **phost;
2129 pci_bridge_t *fake_bridge;
2130 pci_dev_t *dev;
2131 int bus, devfn;
2132 int ret;
2134 fake_host = NULL;
2135 ret = -1;
2136 switch (arch) {
2137 case ARCH_PREP:
2138 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2139 if (dev == NULL)
2140 return -1;
2141 fake_host = pci_add_host(hostp, dev,
2142 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2143 if (fake_host == NULL)
2144 return -1;
2145 fake_host->dev.common.type = PCI_FAKE_HOST;
2146 dev = &PREP_fake_bridge;
2147 if (dev == NULL)
2148 goto free_fake_host;
2149 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2150 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2151 cfg_base, cfg_len,
2152 cfg_base + 0x00800000,
2153 cfg_base + 0x00C00000,
2154 mem_base, mem_len,
2155 io_base, io_len,
2156 rbase, rlen,
2158 &PREP_pci_ops);
2159 if (fake_bridge == NULL)
2160 goto free_fake_host;
2161 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2162 break;
2163 case ARCH_CHRP:
2164 /* TODO */
2165 break;
2166 case ARCH_HEATHROW:
2167 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2168 if (dev == NULL)
2169 return -1;
2170 fake_host = pci_add_host(hostp, dev,
2171 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2172 if (fake_host == NULL)
2173 return -1;
2174 fake_host->dev.common.type = PCI_FAKE_HOST;
2175 dev = &grackle_fake_bridge;
2176 if (dev == NULL)
2177 goto free_fake_host;
2178 fake_bridge = pci_add_bridge(fake_host, 0, 0, dev,
2179 (0x06 << 24) | (0x04 << 16) | (0xFF << 8),
2180 cfg_base, cfg_len,
2181 cfg_base + 0x7ec00000,
2182 cfg_base + 0x7ee00000,
2183 mem_base, mem_len,
2184 io_base, io_len,
2185 rbase, rlen,
2187 &grackle_pci_ops);
2188 if (fake_bridge == NULL)
2189 goto free_fake_host;
2190 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2191 break;
2192 case ARCH_MAC99:
2193 dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
2194 if (dev == NULL)
2195 return -1;
2196 fake_host = pci_add_host(hostp, dev,
2197 (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
2198 if (fake_host == NULL)
2199 return -1;
2200 fake_host->dev.common.type = PCI_FAKE_HOST;
2201 dev = &uninorth_fake_bridge;
2202 if (dev == NULL)
2203 goto free_fake_host;
2204 fake_bridge = pci_add_bridge(fake_host, 0, 11, dev,
2205 (0x06 << 24) | (0x00 << 16) | (0xFF << 8),
2206 cfg_base, cfg_len,
2207 cfg_base + 0x00800000,
2208 cfg_base + 0x00C00000,
2209 mem_base, mem_len,
2210 io_base, io_len,
2211 rbase, rlen,
2212 BRIDGE_TYPE_UNINORTH,
2213 &uninorth_pci_ops);
2214 if (fake_bridge == NULL)
2215 goto free_fake_host;
2216 fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
2217 fake_bridge->flags |= BRIDGE_TYPE_UNINORTH;
2218 break;
2219 case ARCH_POP:
2220 /* TODO */
2221 break;
2223 host = NULL;
2224 phost = &host;
2225 for (bus = 0; bus < 256; bus++) {
2226 for (devfn = 0; devfn < 256; devfn++) {
2227 /* Find host bridge */
2228 pci_check_device(hostp, phost, bus, devfn,
2229 checkv, checkp, 0x06, 0x00, 0xFF, 2);
2230 if (host != NULL) {
2231 *hostp = host;
2232 OF_finalize_pci_host(host->dev.common.OF_private, bus, 1);
2233 ret = 0;
2234 goto done;
2238 done:
2239 free(fake_host->bridge);
2240 free_fake_host:
2241 free(fake_host);
2243 return ret;
2246 static int pci_check_devices (pci_host_t *host)
2248 int bus, devfn;
2250 /* Find all PCI bridges */
2251 printf("Check PCI bridges\n");
2252 for (bus = 0; bus < 256; bus++) {
2253 for (devfn = 0; devfn < 256; devfn++) {
2254 pci_check_device(&host, &host, bus, devfn, 0xFFFF, 0xFFFF,
2255 0x06, 0xFF, 0xFF, 1);
2258 /* Now, find all other devices */
2259 /* XXX: should recurse thru all host and bridges ! */
2260 printf("Check PCI devices\n");
2261 for (bus = 0; bus < 256; bus++) {
2262 for (devfn = 0; devfn < 256; devfn++) {
2263 pci_check_device(&host, &host, bus, devfn, 0xFFFF, 0xFFFF,
2264 0xFF, 0xFF, 0xFF, 0);
2268 return 0;
2271 pci_host_t *pci_init (void)
2273 pci_host_t *pci_main = NULL, *curh;
2274 uint32_t rbase, rlen, cfg_base, cfg_len;
2275 uint32_t mem_base, mem_len, io_base, io_len;
2276 uint8_t busnum;
2278 printf("Probing PCI devices\n");
2279 /* We need to discover PCI bridges and devices */
2280 switch (arch) {
2281 case ARCH_PREP:
2282 /* supposed to have 1 host bridge:
2283 * - the Motorola Raven PCI bridge
2285 cfg_base = 0x80000000;
2286 cfg_len = 0x00100000;
2287 mem_base = 0xF0000000;
2288 mem_len = 0x10000000;
2289 io_base = 0x80000000;
2290 io_len = 0x00010000;
2291 #if 0
2292 rbase = 0x80C00000; /* ? */
2293 #else
2294 rbase = 0x00000000;
2295 #endif
2296 rlen = 0x00400000; /* ? */
2297 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2298 mem_base, mem_len, io_base, io_len, rbase, rlen,
2299 0x1057, 0x4801) == 0) {
2300 isa_io_base = io_base;
2301 busnum++;
2303 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2304 continue;
2305 pci_check_devices(curh);
2306 break;
2307 case ARCH_CHRP:
2308 /* TODO */
2309 break;
2310 case ARCH_HEATHROW:
2311 cfg_base = 0x80000000;
2312 cfg_len = 0x7f000000;
2313 mem_base = 0x80000000;
2314 mem_len = 0x01000000;
2315 io_base = 0xfe000000;
2316 io_len = 0x00800000;
2317 #if 1
2318 rbase = 0xfd000000;
2319 rlen = 0x01000000;
2320 #else
2321 rbase = 0x00000000;
2322 rlen = 0x01000000;
2323 #endif
2324 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2325 mem_base, mem_len, io_base, io_len, rbase, rlen,
2326 0x1057, 0x0002) == 0) {
2327 isa_io_base = io_base;
2328 busnum++;
2330 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2331 continue;
2332 pci_check_devices(curh);
2333 break;
2334 case ARCH_MAC99:
2335 /* We are supposed to have 3 host bridges:
2336 * - the uninorth AGP bridge at 0xF0000000
2337 * - the uninorth PCI expansion bridge at 0xF2000000
2338 * - the uninorth PCI internal bridge at 0xF4000000
2340 cfg_base = 0xF0000000;
2341 cfg_len = 0x02000000;
2342 mem_base = 0x90000000;
2343 mem_len = 0x10000000;
2344 io_base = 0xF0000000;
2345 io_len = 0x00800000;
2346 rbase = 0xF1000000;
2347 rlen = 0x01000000;
2348 #if 0
2349 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2350 mem_base, mem_len, io_base, io_len, rbase, rlen,
2351 0x106b, 0x0020) == 0) {
2352 busnum++;
2354 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2355 continue;
2356 pci_check_devices(curh);
2357 #endif
2359 cfg_base = 0xF2000000;
2360 cfg_len = 0x02000000;
2361 mem_base = 0x80000000;
2362 mem_len = 0x10000000;
2363 io_base = 0xF2000000;
2364 io_len = 0x00800000;
2365 #if 0 // Hack
2366 rbase = 0xF3000000;
2367 rlen = 0x01000000;
2368 #else
2369 rbase = 0x00000000;
2370 rlen = 0x01000000;
2371 #endif
2372 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2373 mem_base, mem_len, io_base, io_len, rbase, rlen,
2374 0x106b, 0x001F) == 0) {
2375 isa_io_base = io_base;
2376 busnum++;
2378 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2379 continue;
2380 pci_check_devices(curh);
2382 #if 0
2383 cfg_base = 0xF4000000;
2384 cfg_len = 0x02000000;
2385 mem_base = 0xA0000000;
2386 mem_len = 0x10000000;
2387 io_base = 0xF4000000;
2388 io_len = 0x00800000;
2389 rbase = 0xF5000000;
2390 rlen = 0x01000000;
2391 if (pci_check_host(&pci_main, cfg_base, cfg_len,
2392 mem_base, mem_len, io_base, io_len, rbase, rlen,
2393 0x106b, 0x001F) == 0) {
2394 busnum++;
2396 for (curh = pci_main; curh->next != NULL; curh = curh->next)
2397 continue;
2398 pci_check_devices(curh);
2399 #endif
2400 break;
2401 case ARCH_POP:
2402 /* TODO */
2403 break;
2405 printf("PCI probe done (%p)\n", pci_main);
2407 return pci_main;
2410 void pci_get_mem_range (pci_host_t *host, uint32_t *start, uint32_t *len)
2412 *start = host->bridge->mem_base;
2413 *len = host->bridge->mem_len;