Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / pci.c
1 /* PCI BIOS.
2  *
3  *  Copyright (c) 2004-2005 Jocelyn Mayer
4  *
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
8  *
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.
13  *
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
17  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include "bios.h"
22
23 //#define DEBUG_PCI 1
24
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
32
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.
39  */
40
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,
49 };
50
51 enum {
52     BRIDGE_TYPE_UNINORTH = 0x0001,
53 };
54
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;
59
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;
67 };
68
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;
77 };
78
79 struct pci_class_t {
80     const unsigned char *name;
81     const unsigned char *type;
82     const pci_subclass_t *subc;
83 };
84
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;
91 };
92
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;
105 };
106
107 struct pci_host_t {
108     pci_device_t dev;
109     pci_bridge_t *bridge;
110     pci_host_t *next;
111 };
112
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;
131 };
132
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;
138 };
139
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);
157 };
158
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 };
163
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)
167 {
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;
176 }
177
178 static uint8_t PREP_config_readb (pci_bridge_t *bridge,
179                                   uint8_t bus, uint8_t devfn,
180                                   uint8_t offset)
181 {
182     uint32_t addr;
183
184     if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
185         return 0xFF;
186     addr = PREP_cfg_addr(bridge, bus, devfn, offset);
187     
188     return *((uint8_t *)addr);
189 }
190
191 static void PREP_config_writeb (pci_bridge_t *bridge,
192                                 uint8_t bus, uint8_t devfn,
193                                 uint8_t offset, uint8_t val)
194 {
195     uint32_t addr;
196
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;
201 }
202
203 static uint16_t PREP_config_readw (pci_bridge_t *bridge,
204                                    uint8_t bus, uint8_t devfn,
205                                    uint8_t offset)
206 {
207     uint32_t addr;
208
209     if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
210         return 0xFFFF;
211     addr = PREP_cfg_addr(bridge, bus, devfn, offset);
212     
213     return ldswap16((uint16_t *)addr);
214 }
215
216 static void PREP_config_writew (pci_bridge_t *bridge,
217                                 uint8_t bus, uint8_t devfn,
218                                 uint8_t offset, uint16_t val)
219 {
220     uint32_t addr;
221
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);
226 }
227
228 static uint32_t PREP_config_readl (pci_bridge_t *bridge,
229                                    uint8_t bus, uint8_t devfn,
230                                    uint8_t offset)
231 {
232     uint32_t addr;
233
234     if (bus != 0 || (devfn >> 3) < 11 || (devfn >> 3) > 21)
235         return 0xFFFFFFFF;
236     addr = PREP_cfg_addr(bridge, bus, devfn, offset);
237     
238     return ldswap32((uint32_t *)addr);
239 }
240
241 static void PREP_config_writel (pci_bridge_t *bridge,
242                                 uint8_t bus, uint8_t devfn,
243                                 uint8_t offset, uint32_t val)
244 {
245     uint32_t addr;
246
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);
251 }
252
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,
257 };
258
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)
263 {
264     uint32_t addr;
265     int i;
266
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;
274         }
275         addr = (1 << (devfn >> 3));
276     } else {
277         addr = (bus << 16) | ((devfn & 0xF8) << 8) | 0x01;
278     }
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;
290     }
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;
298     }
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
306
307     return bridge->cfg_data + offset;
308 }
309
310 static uint8_t uninorth_config_readb (pci_bridge_t *bridge,
311                                       uint8_t bus, uint8_t devfn,
312                                       uint8_t offset)
313 {
314     uint32_t addr;
315
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;
321     
322     return *((uint8_t *)addr);
323 }
324
325 static void uninorth_config_writeb (pci_bridge_t *bridge,
326                                     uint8_t bus, uint8_t devfn,
327                                     uint8_t offset, uint8_t val)
328 {
329     uint32_t addr;
330
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;
336 }
337
338 static uint16_t uninorth_config_readw (pci_bridge_t *bridge,
339                                        uint8_t bus, uint8_t devfn,
340                                        uint8_t offset)
341 {
342     uint32_t addr;
343
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;
349     
350     return ldswap16((uint16_t *)addr);
351 }
352
353 static void uninorth_config_writew (pci_bridge_t *bridge,
354                                     uint8_t bus, uint8_t devfn,
355                                     uint8_t offset, uint16_t val)
356 {
357     uint32_t addr;
358
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);
364 }
365
366 static uint32_t uninorth_config_readl (pci_bridge_t *bridge,
367                                        uint8_t bus, uint8_t devfn,
368                                        uint8_t offset)
369 {
370     uint32_t addr;
371
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;
378     }
379     //    printf("%s: addr=%0x\n", __func__, addr);
380     
381     return ldswap32((uint32_t *)addr);
382 }
383
384 static void uninorth_config_writel (pci_bridge_t *bridge,
385                                     uint8_t bus, uint8_t devfn,
386                                     uint8_t offset, uint32_t val)
387 {
388     uint32_t addr;
389
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);
395 }
396
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,
401 };
402
403 /* Grackle PCI host */
404
405 static uint32_t grackle_cfg_address (pci_bridge_t *bridge,
406                                      uint8_t bus, uint8_t devfn,
407                                      uint8_t offset)
408 {
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);
413 }
414
415 static uint8_t grackle_config_readb (pci_bridge_t *bridge,
416                                       uint8_t bus, uint8_t devfn,
417                                       uint8_t offset)
418 {
419     uint32_t addr;
420     addr = grackle_cfg_address(bridge, bus, devfn, offset);
421     return *((uint8_t *)addr);
422 }
423
424 static void grackle_config_writeb (pci_bridge_t *bridge,
425                                     uint8_t bus, uint8_t devfn,
426                                     uint8_t offset, uint8_t val)
427 {
428     uint32_t addr;
429     addr = grackle_cfg_address(bridge, bus, devfn, offset);
430     *((uint8_t *)addr) = val;
431 }
432
433 static uint16_t grackle_config_readw (pci_bridge_t *bridge,
434                                        uint8_t bus, uint8_t devfn,
435                                        uint8_t offset)
436 {
437     uint32_t addr;
438     addr = grackle_cfg_address(bridge, bus, devfn, offset);
439     return ldswap16((uint16_t *)addr);
440 }
441
442 static void grackle_config_writew (pci_bridge_t *bridge,
443                                     uint8_t bus, uint8_t devfn,
444                                     uint8_t offset, uint16_t val)
445 {
446     uint32_t addr;
447     addr = grackle_cfg_address(bridge, bus, devfn, offset);
448     stswap16((uint16_t *)addr, val);
449 }
450
451 static uint32_t grackle_config_readl (pci_bridge_t *bridge,
452                                        uint8_t bus, uint8_t devfn,
453                                        uint8_t offset)
454 {
455     uint32_t addr;
456     addr = grackle_cfg_address(bridge, bus, devfn, offset);
457     return ldswap32((uint32_t *)addr);
458 }
459
460 static void grackle_config_writel (pci_bridge_t *bridge,
461                                     uint8_t bus, uint8_t devfn,
462                                     uint8_t offset, uint32_t val)
463 {
464     uint32_t addr;
465
466     addr = grackle_cfg_address(bridge, bus, devfn, offset);
467     stswap32((uint32_t *)addr, val);
468 }
469
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,
474 };
475
476 static inline uint8_t pci_config_readb (pci_bridge_t *bridge,
477                                         uint8_t bus, uint8_t devfn,
478                                         uint8_t offset)
479 {
480     return (*bridge->ops->config_readb)(bridge, bus, devfn, offset);
481 }
482
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)
486 {
487     (*bridge->ops->config_writeb)(bridge, bus, devfn, offset, val);
488 }
489
490 static inline uint16_t pci_config_readw (pci_bridge_t *bridge,
491                                          uint8_t bus, uint8_t devfn,
492                                          uint8_t offset)
493 {
494     return (*bridge->ops->config_readw)(bridge, bus, devfn, offset);
495 }
496
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)
500 {
501     (*bridge->ops->config_writew)(bridge, bus, devfn, offset, val);
502 }
503
504 static inline uint32_t pci_config_readl (pci_bridge_t *bridge,
505                                          uint8_t bus, uint8_t devfn,
506                                          uint8_t offset)
507 {
508     return (*bridge->ops->config_readl)(bridge, bus, devfn, offset);
509 }
510
511
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)
515 {
516     (*bridge->ops->config_writel)(bridge, bus, devfn, offset, val);
517 }
518
519 unused static void *get_parent_OF_private (pci_device_t *device)
520 {
521     const pci_u_t *u;
522
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;
526     }
527     
528     return NULL;
529 }
530
531 /* PCI devices database */
532 static pci_subclass_t undef_subclass[] = {
533     {
534         0x00, "misc undefined", NULL, NULL, NULL,
535         NULL, NULL,
536     },
537     {
538         0xFF, NULL, NULL, NULL, NULL,
539         NULL, NULL,
540     },
541 };
542
543 static int ide_config_cb2 (pci_device_t *device)
544 {
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;
551 }
552
553 static pci_dev_t ide_devices[] = {
554     {
555         0x1095, 0x0646, /* CMD646 IDE controller */
556         "pci-ide", "pci-ata", NULL, NULL,
557         0, 0, 0,
558         ide_config_cb2, NULL,
559     },
560     {
561         0xFFFF, 0xFFFF,
562         NULL, NULL, NULL, NULL,
563         -1, -1, -1,
564         NULL, NULL,
565     },
566 };
567
568 #if 0
569 /* should base it on PCI ID, not on arch */
570 static int ide_config_cb (unused pci_device_t *device)
571 {
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;
581     }
582     return 0;
583 }
584
585 static int ata_config_cb (pci_device_t *device)
586 {
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;
596     }
597
598     return 0;
599 }
600 #endif
601
602 static pci_subclass_t mass_subclass[] = {
603     {
604         0x00, "SCSI bus controller",        NULL,  NULL, NULL,
605         NULL, NULL,
606     },
607     {
608         0x01, "IDE controller",             "ide", ide_devices, NULL,
609         NULL, NULL,
610     },
611     {
612         0x02, "Floppy disk controller",     NULL,  NULL, NULL,
613         NULL, NULL,
614     },
615     {
616         0x03, "IPI bus controller",         NULL,  NULL, NULL,
617         NULL, NULL,
618     },
619     {
620         0x04, "RAID controller",            NULL,  NULL, NULL,
621         NULL, NULL,
622     },
623     {
624         0x05, "ATA controller",             "ata", NULL, NULL,
625         NULL, NULL,
626     },
627     {
628         0x80, "misc mass-storage controller", NULL, NULL, NULL,
629         NULL, NULL,
630     },
631     {
632         0xFF, NULL,                        NULL,  NULL,  NULL,
633         NULL, NULL,
634     },
635 };
636
637 static pci_dev_t eth_devices[] = {
638     { 0x10EC, 0x8029,
639       NULL, "NE2000",   "NE2000 PCI",  NULL,
640       0, 0, 0,
641       NULL, "ethernet",
642     },
643     {
644         0xFFFF, 0xFFFF,
645         NULL, NULL, NULL, NULL,
646         -1, -1, -1,
647         NULL, NULL,
648     },
649 };
650
651 static pci_subclass_t net_subclass[] = {
652     {
653         0x00, "ethernet controller",       NULL, eth_devices, NULL,
654         NULL, "ethernet",
655     },
656     {
657         0x01, "token ring controller",      NULL,  NULL, NULL,
658         NULL, NULL,
659     },
660     {
661         0x02, "FDDI controller",            NULL,  NULL, NULL,
662         NULL, NULL,
663     },
664     {
665         0x03, "ATM controller",             NULL,  NULL, NULL,
666         NULL, NULL,
667     },
668     {
669         0x04, "ISDN controller",            NULL,  NULL, NULL,
670         NULL, NULL,
671     },
672     {
673         0x05, "WordFip controller",         NULL,  NULL, NULL,
674         NULL, NULL,
675     },
676     {
677         0x06, "PICMG 2.14 controller",      NULL,  NULL, NULL,
678         NULL, NULL,
679     },
680     {
681         0x80, "misc network controller",    NULL,  NULL, NULL,
682         NULL, NULL,
683     },
684     {
685         0xFF, NULL,                        NULL,  NULL,  NULL,
686         NULL, NULL,
687     },
688 };
689
690 static pci_dev_t vga_devices[] = {
691     {
692         0x1002, 0x5046,
693         NULL, "ATY",      "ATY Rage128", "VGA",
694         0, 0, 0,
695         NULL, NULL,
696     },
697     {
698         0x1234, 0x1111,
699         NULL, "Qemu VGA", "Qemu VGA",    "VGA",
700         0, 0, 0,
701         NULL, NULL,
702     },
703     {
704         0xFFFF, 0xFFFF,
705         NULL, NULL, NULL, NULL,
706         -1, -1, -1,
707         NULL, NULL,
708     },
709 };
710
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)
716 {
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]);
728     }
729     vga_console_register();
730
731     return 0;
732 }
733
734 static struct pci_iface_t vga_iface[] = {
735     { 
736         0x00, "VGA controller", NULL,
737         vga_devices, &vga_config_cb, NULL,
738     },
739     {
740         0x01, "8514 compatible controller", NULL,
741         NULL, NULL, NULL,
742     },
743     {
744         0xFF, NULL, NULL,
745         NULL, NULL, NULL,
746     },
747 };
748
749 static pci_subclass_t displ_subclass[] = {
750     {
751         0x00, "display controller",         NULL,  NULL, vga_iface,
752         NULL, NULL,
753     },
754     {
755         0x01, "XGA display controller",     NULL,  NULL, NULL,
756         NULL, NULL,
757     },
758     {
759         0x02, "3D display controller",      NULL,  NULL, NULL,
760         NULL, NULL,
761     },
762     {
763         0x80, "misc display controller",    NULL,  NULL, NULL,
764         NULL, NULL,
765     },
766     {
767         0xFF, NULL,                        NULL,  NULL,  NULL,
768         NULL, NULL,
769     },
770 };
771
772 static pci_subclass_t media_subclass[] = {
773     {
774         0x00, "video device",              NULL,  NULL, NULL,
775         NULL, NULL,
776     },
777     {
778         0x01, "audio device",              NULL,  NULL, NULL,
779         NULL, NULL,
780     },
781     {
782         0x02, "computer telephony device", NULL,  NULL, NULL,
783         NULL, NULL,
784     },
785     {
786         0x80, "misc multimedia device",    NULL,  NULL, NULL,
787         NULL, NULL,
788     },
789     {
790         0xFF, NULL,                        NULL,  NULL,  NULL,
791         NULL, NULL,
792     },
793 };
794
795 static pci_subclass_t mem_subclass[] = {
796     {
797         0x00, "RAM controller",             NULL,  NULL, NULL,
798         NULL, NULL,
799     },
800     {
801         0x01, "flash controller",           NULL,  NULL, NULL,
802         NULL, NULL,
803     },
804     {
805         0xFF, NULL,                        NULL,  NULL,  NULL,
806         NULL, NULL,
807     },
808 };
809
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,
815 };
816
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,
822 };
823
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,
829 };
830
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,
836 };
837
838 static pci_dev_t hbrg_devices[] = {
839     {
840         0x106B, 0x0020, NULL,
841         "pci", "AAPL,UniNorth", "uni-north",
842         3, 2, 1,
843         NULL, &uninorth_agp_fake_bridge,
844     },
845     {
846         0x106B, 0x001F, NULL, 
847         "pci", "AAPL,UniNorth", "uni-north",
848         3, 2, 1,
849         NULL, &uninorth_fake_bridge,
850     },
851     {
852         0x106B, 0x001E, NULL,
853         "pci", "AAPL,UniNorth", "uni-north",
854         3, 2, 1,
855         NULL, &uninorth_fake_bridge,
856     },
857     {
858         0x1057, 0x0002, "pci",
859         "pci", "MOT,MPC106", "grackle",
860         3, 2, 1,
861         NULL, &grackle_fake_bridge,
862     },
863     {
864         0x1057, 0x4801, NULL,
865         "pci-bridge", "PREP Host PCI Bridge - Motorola Raven", NULL,
866         3, 2, 1,
867         NULL, &PREP_pci_ops,
868     },
869     {
870         0xFFFF, 0xFFFF,
871         NULL, NULL, NULL, NULL,
872         -1, -1, -1,
873         NULL, NULL,
874     },
875 };
876
877 static pci_dev_t PCIbrg_devices[] = {
878     {
879         0x1011, 0x0026, NULL,
880         "pci-bridge", NULL, NULL,
881         3, 2, 1,
882         NULL, &PREP_pci_ops,
883     },
884     {
885         0xFFFF, 0xFFFF,
886         NULL, NULL, NULL, NULL,
887         -1, -1, -1,
888         NULL, NULL,
889     },
890 };
891
892 static pci_subclass_t bridg_subclass[] = {
893     {
894         0x00, "PCI host bridge",           NULL,  hbrg_devices, NULL,
895         NULL, NULL,
896     },
897     {
898         0x01, "ISA bridge",                NULL,  NULL, NULL,
899         NULL, NULL,
900     },
901     {
902         0x02, "EISA bridge",               NULL,  NULL, NULL,
903         NULL, NULL,
904     },
905     {
906         0x03, "MCA bridge",                NULL,  NULL, NULL,
907         NULL, NULL,
908     },
909     {
910         0x04, "PCI-to-PCI bridge",         NULL,  PCIbrg_devices, NULL,
911         NULL, NULL,
912     },
913     {
914         0x05, "PCMCIA bridge",             NULL,  NULL, NULL,
915         NULL, NULL,
916     },
917     {
918         0x06, "NUBUS bridge",              NULL,  NULL, NULL,
919         NULL, NULL,
920     },
921     {
922         0x07, "cardbus bridge",            NULL,  NULL, NULL,
923         NULL, NULL,
924     },
925     {
926         0x08, "raceway bridge",            NULL,  NULL, NULL,
927         NULL, NULL,
928     },
929     {
930         0x09, "semi-transparent PCI-to-PCI bridge", NULL, NULL, NULL,
931         NULL, NULL,
932     },
933     {
934         0x0A, "infiniband-to-PCI bridge",  NULL,  NULL, NULL,
935         NULL, NULL,
936     },
937     {
938         0x80, "misc PCI bridge",           NULL,  NULL, NULL,
939         NULL, NULL,
940     },
941     {
942         0xFF, NULL,                        NULL,  NULL,  NULL,
943         NULL, NULL,
944     },
945 };
946
947 static pci_iface_t serial_iface[] = {
948     {
949         0x00, "XT serial controller", NULL,
950         NULL, NULL, NULL,
951     },
952     {
953         0x01, "16450 serial controller", NULL,
954         NULL, NULL, NULL,
955     },
956     {
957         0x02, "16550 serial controller", NULL,
958         NULL, NULL, NULL,
959     },
960     {
961         0x03, "16650 serial controller", NULL,
962         NULL, NULL, NULL,
963     },
964     {
965         0x04, "16750 serial controller", NULL,
966         NULL, NULL, NULL,
967     },
968     {
969         0x05, "16850 serial controller", NULL,
970         NULL, NULL, NULL,
971     },
972     {
973         0x06, "16950 serial controller", NULL,
974         NULL, NULL, NULL,
975     },
976     {
977         0xFF, NULL, NULL,
978         NULL, NULL, NULL,
979     },
980 };
981
982 static pci_iface_t par_iface[] = {
983     {
984         0x00, "parallel port", NULL,
985         NULL, NULL, NULL,
986     },
987     {
988         0x01, "bi-directional parallel port", NULL,
989         NULL, NULL, NULL,
990     },
991     {
992         0x02, "ECP 1.x parallel port", NULL,
993         NULL, NULL, NULL,
994     },
995     {
996         0x03, "IEEE 1284 controller", NULL,
997         NULL, NULL, NULL,
998     },
999     {
1000         0xFE, "IEEE 1284 device", NULL,
1001         NULL, NULL, NULL,
1002     },
1003     {
1004         0xFF, NULL, NULL,
1005         NULL, NULL, NULL,
1006     },
1007 };
1008
1009 static pci_iface_t modem_iface[] = {
1010     {
1011         0x00, "generic modem", NULL,
1012         NULL, NULL, NULL,
1013     },
1014     {
1015         0x01, "Hayes 16450 modem", NULL,
1016         NULL, NULL, NULL,
1017     },
1018     {
1019         0x02, "Hayes 16550 modem", NULL,
1020         NULL, NULL, NULL,
1021     },
1022     {
1023         0x03, "Hayes 16650 modem", NULL,
1024         NULL, NULL, NULL,
1025     },
1026     {
1027         0x04, "Hayes 16750 modem", NULL,
1028         NULL, NULL, NULL,
1029     },
1030     {
1031         0xFF, NULL, NULL,
1032         NULL, NULL, NULL,
1033     },
1034 };
1035
1036 static pci_subclass_t comm_subclass[] = {
1037     {
1038         0x00, "serial controller",          NULL, NULL, serial_iface,
1039         NULL, NULL,
1040     },
1041     {
1042         0x01, "parallel port",             NULL, NULL, par_iface,
1043         NULL, NULL,
1044     },
1045     {
1046         0x02, "multiport serial controller", NULL, NULL, NULL,
1047         NULL, NULL,
1048     },
1049     {
1050         0x03, "modem",                     NULL, NULL, modem_iface,
1051         NULL, NULL,
1052     },
1053     {
1054         0x04, "GPIB controller",           NULL, NULL, NULL,
1055         NULL, NULL,
1056     },
1057     {
1058         0x05, "smart card",                NULL, NULL, NULL,
1059         NULL, NULL,
1060     },
1061     {
1062         0x80, "misc communication device", NULL, NULL, NULL,
1063         NULL, NULL,
1064     },
1065     {
1066         0xFF, NULL,                        NULL, NULL, NULL,
1067         NULL, NULL,
1068     },
1069 };
1070
1071 static pci_iface_t pic_iface[] = {
1072     {
1073         0x00, "8259 PIC", NULL,
1074         NULL, NULL, NULL,
1075     },
1076     {
1077         0x01, "ISA PIC", NULL,
1078         NULL, NULL, NULL,
1079     },
1080     {
1081         0x02, "EISA PIC", NULL,
1082         NULL, NULL, NULL,
1083     },
1084     {
1085         0x10, "I/O APIC", NULL,
1086         NULL, NULL, NULL,
1087     },
1088     {
1089         0x20, "I/O APIC", NULL,
1090         NULL, NULL, NULL,
1091     },
1092     {
1093         0xFF, NULL, NULL,
1094         NULL, NULL, NULL,
1095     },
1096 };
1097
1098 static pci_iface_t dma_iface[] = {
1099     {
1100         0x00, "8237 DMA controller", NULL,
1101         NULL, NULL, NULL,
1102     },
1103     {
1104         0x01, "ISA DMA controller", NULL,
1105         NULL, NULL, NULL,
1106     },
1107     {
1108         0x02, "EISA DMA controller", NULL,
1109         NULL, NULL, NULL,
1110     },
1111     {
1112         0xFF, NULL, NULL,
1113         NULL, NULL, NULL,
1114     },
1115 };
1116
1117 static pci_iface_t tmr_iface[] = {
1118     {
1119         0x00, "8254 system timer", NULL,
1120         NULL, NULL, NULL,
1121     },
1122     {
1123         0x01, "ISA system timer", NULL,
1124         NULL, NULL, NULL,
1125     },
1126     {
1127         0x02, "EISA system timer", NULL,
1128         NULL, NULL, NULL,
1129     },
1130     {
1131         0xFF, NULL, NULL,
1132         NULL, NULL, NULL,
1133     },
1134 };
1135
1136 static pci_iface_t rtc_iface[] = {
1137     {
1138         0x00, "generic RTC controller", NULL,
1139         NULL, NULL, NULL,
1140     },
1141     {
1142         0x01, "ISA RTC controller", NULL,
1143         NULL, NULL, NULL,
1144     },
1145     {
1146         0xFF, NULL, NULL,
1147         NULL, NULL, NULL,
1148     },
1149 };
1150
1151 static const pci_dev_t sys_devices[] = {
1152     /* IBM MPIC controller */
1153     { 
1154         0x1014, 0x0002,
1155         "open-pic", "MPIC", NULL, "chrp,open-pic",
1156         0, 0, 2,
1157         NULL, NULL,
1158     },
1159     /* IBM MPIC2 controller */
1160     { 
1161         0x1014, 0xFFFF,
1162         "open-pic", "MPIC2", NULL, "chrp,open-pic",
1163         0, 0, 2,
1164         NULL, NULL,
1165     },
1166     {
1167         0xFFFF, 0xFFFF,
1168         NULL, NULL, NULL, NULL,
1169         -1, -1, -1,
1170         NULL, NULL,
1171     },
1172 };
1173
1174 static pci_subclass_t sys_subclass[] = {
1175     {
1176         0x00, "PIC",                       NULL, NULL, pic_iface,
1177         NULL, NULL,
1178     },
1179     {
1180         0x01, "DMA controller",             NULL, NULL, dma_iface,
1181         NULL, NULL,
1182     },
1183     {
1184         0x02, "system timer",              NULL, NULL, tmr_iface,
1185         NULL, NULL,
1186     },
1187     {
1188         0x03, "RTC controller",             NULL, NULL, rtc_iface,
1189         NULL, NULL,
1190     },
1191     {
1192         0x04, "PCI hotplug controller",     NULL, NULL, NULL,
1193         NULL, NULL,
1194     },
1195     {
1196         0x80, "misc system peripheral",    NULL, sys_devices, NULL,
1197         NULL, NULL,
1198     },
1199     {
1200         0xFF, NULL,                        NULL,  NULL,  NULL,
1201         NULL, NULL,
1202     },
1203 };
1204
1205 static pci_subclass_t inp_subclass[] = {
1206     {
1207         0x00, "keyboard controller",        NULL, NULL, NULL,
1208         NULL, NULL,
1209     },
1210     {
1211         0x01, "digitizer",                 NULL, NULL, NULL,
1212         NULL, NULL,
1213     },
1214     {
1215         0x02, "mouse controller",           NULL, NULL, NULL,
1216         NULL, NULL,
1217     },
1218     {
1219         0x03, "scanner controller",         NULL, NULL, NULL,
1220         NULL, NULL,
1221     },
1222     {
1223         0x04, "gameport controller",        NULL, NULL, NULL,
1224         NULL, NULL,
1225     },
1226     {
1227         0x80, "misc input device",         NULL, NULL, NULL,
1228         NULL, NULL,
1229     },
1230     {
1231         0xFF, NULL,                        NULL,  NULL,  NULL,
1232         NULL, NULL,
1233     },
1234 };
1235
1236 static pci_subclass_t dock_subclass[] = {
1237     {
1238         0x00, "generic docking station",   NULL, NULL,  NULL,
1239         NULL, NULL,
1240     },
1241     {
1242         0x80, "misc docking station",      NULL, NULL,  NULL,
1243         NULL, NULL,
1244     },
1245     {
1246         0xFF, NULL,                        NULL,  NULL,  NULL,
1247         NULL, NULL,
1248     },
1249 };
1250
1251 static pci_subclass_t cpu_subclass[] = {
1252     {
1253         0x00, "i386 processor",            NULL, NULL,  NULL,
1254         NULL, NULL,
1255     },
1256     {
1257         0x01, "i486 processor",            NULL, NULL,  NULL,
1258         NULL, NULL,
1259     },
1260     {
1261         0x02, "pentium processor",         NULL, NULL,  NULL,
1262         NULL, NULL,
1263     },
1264     {
1265         0x10, "alpha processor",           NULL, NULL,  NULL,
1266         NULL, NULL,
1267     },
1268     {
1269         0x20, "PowerPC processor",         NULL, NULL,  NULL,
1270         NULL, NULL,
1271     },
1272     {
1273         0x30, "MIPS processor",            NULL, NULL,  NULL,
1274         NULL, NULL,
1275     },
1276     {
1277         0x40, "co-processor",              NULL, NULL,  NULL,
1278         NULL, NULL,
1279     },
1280     {
1281         0xFF, NULL,                        NULL,  NULL,  NULL,
1282         NULL, NULL,
1283     },
1284 };
1285
1286 static pci_iface_t usb_iface[] = {
1287     {
1288         0x00, "UHCI USB controller", NULL,
1289         NULL, NULL, NULL,
1290     },
1291     {
1292         0x10, "OHCI USB controller", NULL,
1293         NULL, NULL, NULL,
1294     },
1295     {
1296         0x20, "EHCI USB controller", NULL,
1297         NULL, NULL, NULL,
1298     },
1299     {
1300         0x80, "misc USB controller", NULL,
1301         NULL, NULL, NULL,
1302     },
1303     {
1304         0xFE, "USB device", NULL,
1305         NULL, NULL, NULL,
1306     },
1307     {
1308         0xFF, NULL, NULL,
1309         NULL, NULL, NULL,
1310     },
1311 };
1312
1313 static pci_iface_t ipmi_iface[] = {
1314     {
1315         0x00, "IPMI SMIC interface", NULL,
1316         NULL, NULL, NULL,
1317     },
1318     {
1319         0x01, "IPMI keyboard interface", NULL,
1320         NULL, NULL, NULL,
1321     },
1322     {
1323         0x02, "IPMI block transfer interface", NULL,
1324         NULL, NULL, NULL,
1325     },
1326     {
1327         0xFF, NULL, NULL,
1328         NULL, NULL, NULL,
1329     },
1330 };
1331
1332 static pci_subclass_t ser_subclass[] = {
1333     {
1334         0x00, "Firewire bus controller",    "ieee1394", NULL, NULL,
1335         NULL, NULL,
1336     },
1337     {
1338         0x01, "ACCESS bus controller",      NULL, NULL,  NULL,
1339         NULL, NULL,
1340     },
1341     {
1342         0x02, "SSA controller",             NULL, NULL,  NULL,
1343         NULL, NULL,
1344     },
1345     {
1346         0x03, "USB controller",             "usb", NULL, usb_iface,
1347         NULL, NULL,
1348     },
1349     {
1350         0x04, "fibre channel controller",   NULL, NULL,  NULL,
1351         NULL, NULL,
1352     },
1353     {
1354         0x05, "SMBus controller",           NULL, NULL,  NULL,
1355         NULL, NULL,
1356     },
1357     {
1358         0x06, "InfiniBand controller",      NULL, NULL,  NULL,
1359         NULL, NULL,
1360     },
1361     {
1362         0x07, "IPMI interface",            NULL, NULL,  ipmi_iface,
1363         NULL, NULL,
1364     },
1365     {
1366         0x08, "SERCOS controller",          NULL, NULL,  ipmi_iface,
1367         NULL, NULL,
1368     },
1369     {
1370         0x09, "CANbus controller",          NULL, NULL,  ipmi_iface,
1371         NULL, NULL,
1372     },
1373     {
1374         0xFF, NULL,                        NULL,  NULL,  NULL,
1375         NULL, NULL,
1376     },
1377 };
1378
1379 static pci_subclass_t wrl_subclass[] = {
1380     {
1381         0x00, "IRDA controller",           NULL, NULL,  NULL,
1382         NULL, NULL,
1383     },
1384     {
1385         0x01, "consumer IR controller",    NULL, NULL,  NULL,
1386         NULL, NULL,
1387     },
1388     {
1389         0x10, "RF controller",             NULL, NULL,  NULL,
1390         NULL, NULL,
1391     },
1392     {
1393         0x11, "bluetooth controller",      NULL, NULL,  NULL,
1394         NULL, NULL,
1395     },
1396     {
1397         0x12, "broadband controller",      NULL, NULL,  NULL,
1398         NULL, NULL,
1399     },
1400     {
1401         0x80, "misc wireless controller",  NULL, NULL,  NULL,
1402         NULL, NULL,
1403     },
1404     {
1405         0xFF, NULL,                        NULL,  NULL,  NULL,
1406         NULL, NULL,
1407     },
1408 };
1409
1410 static pci_subclass_t sat_subclass[] = {
1411     {
1412         0x01, "satellite TV controller",   NULL, NULL,  NULL,
1413         NULL, NULL,
1414     },
1415     {
1416         0x02, "satellite audio controller", NULL, NULL, NULL,
1417         NULL, NULL,
1418     },
1419     {
1420         0x03, "satellite voice controller", NULL, NULL, NULL,
1421         NULL, NULL,
1422     },
1423     {
1424         0x04, "satellite data controller", NULL, NULL,  NULL,
1425         NULL, NULL,
1426     },
1427     {
1428         0xFF, NULL,                        NULL,  NULL,  NULL,
1429         NULL, NULL,
1430     },
1431 };
1432
1433 static pci_subclass_t crypt_subclass[] = {
1434     {
1435         0x00, "cryptographic network controller", NULL, NULL, NULL,
1436         NULL, NULL,
1437     },
1438     {
1439         0x10, "cryptographic entertainment controller", NULL, NULL, NULL,
1440         NULL, NULL,
1441     },
1442     {
1443         0x80, "misc cryptographic controller",    NULL, NULL, NULL,
1444         NULL, NULL,
1445     },
1446     {
1447         0xFF, NULL,                        NULL,  NULL,  NULL,
1448         NULL, NULL,
1449     },
1450 };
1451
1452 static pci_subclass_t spc_subclass[] = {
1453     {
1454         0x00, "DPIO module",               NULL, NULL,  NULL,
1455         NULL, NULL,
1456     },
1457     {
1458         0x01, "performances counters",     NULL, NULL,  NULL,
1459         NULL, NULL,
1460     },
1461     {
1462         0x10, "communication synchronisation", NULL, NULL, NULL,
1463         NULL, NULL,
1464     },
1465     {
1466         0x20, "management card",           NULL, NULL,  NULL,
1467         NULL, NULL,
1468     },
1469     {
1470         0x80, "misc signal processing controller", NULL, NULL, NULL,
1471         NULL, NULL,
1472     },
1473     {
1474         0xFF, NULL,                        NULL,  NULL,  NULL,
1475         NULL, NULL,
1476     },
1477 };
1478
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, },
1516 };
1517
1518 static int macio_config_cb (pci_device_t *device)
1519 {
1520     void *private_data;
1521
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);
1526
1527     return 0;
1528 }
1529
1530 static const pci_dev_t misc_pci[] = {
1531     /* Paddington Mac I/O */
1532     { 
1533         0x106B, 0x0017,
1534         "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
1535         1, 1, 1,
1536         &macio_config_cb, NULL,
1537     },
1538     /* KeyLargo Mac I/O */
1539     { 
1540         0x106B, 0x0022,
1541         "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
1542         1, 1, 2,
1543         &macio_config_cb, NULL,
1544     },
1545     {
1546         0xFFFF, 0xFFFF,
1547         NULL, NULL, NULL, NULL,
1548         -1, -1, -1,
1549         NULL, NULL,
1550     },
1551 };
1552
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)
1556 {
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;
1565
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;
1582     }
1583     if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
1584         name = "invalid PCI device";
1585         type = "invalid";
1586         goto bad_device;
1587     }
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;
1601             }
1602             if (psubclass->private != NULL)
1603                 private = psubclass->private;
1604             if (psubclass->iface != NULL)
1605                 break;
1606             dev = psubclass->devices;
1607             goto find_device;
1608         }
1609     }
1610     for (piface = psubclass->iface; ; piface++) {
1611         if (piface->iface == 0xFF) {
1612             dev = psubclass->devices;
1613             break;
1614         }
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;
1622             }
1623             if (piface->private != NULL)
1624                 private = piface->private;
1625             dev = piface->devices;
1626             break;
1627         }
1628     }
1629     find_device:
1630     for (;; dev++) {
1631         if (dev->vendor == 0xFFFF && dev->product == 0xFFFF) {
1632             goto bad_device;
1633         }
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;
1641             }
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;
1658
1659             return new;
1660         }
1661     }
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);
1665
1666     return NULL;
1667 }
1668
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)
1672 {
1673     comm->type = type;
1674     comm->device = device;
1675     comm->parent = parent;
1676 }
1677
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)
1681 {
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;
1687 }
1688
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)
1693 {
1694     uint32_t cmd, addr;
1695     int i;
1696
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);
1705     }
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);
1721             }
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);
1732             }
1733         }
1734     }
1735 }
1736
1737 static pci_host_t *pci_add_host (pci_host_t **hostp, pci_dev_t *device,
1738                                  uint32_t class_code)
1739 {
1740     pci_host_t *new, **lnk;
1741
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;
1751     
1752     return new;
1753 }
1754
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)
1764 {
1765     pci_u_t *u;
1766     pci_bridge_t *new, **lnk;
1767
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;
1793     
1794     return new;
1795 }
1796
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)
1800 {
1801     pci_u_t *u;
1802     pci_device_t *new, **lnk;
1803
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;
1812
1813     return new;
1814 }
1815
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)
1821 {
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;
1832     
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;
1843     }
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;
1855     }
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;
1862     }
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;
1869     }
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;
1876     }
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;
1883     }
1884     dev = pci_find_device(class, subclass, iface, vendor, product);
1885     if (dev == NULL) {
1886         goto out;
1887     }
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;
1904             }
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;
1912             }
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;
1927             }
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;
1959             }
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...
1971                  */
1972                 printf("Free fake bridge\n");
1973                 newb->devices = host->bridge->devices;
1974                 host->bridge = bridge->next;
1975             }
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;
1989         }
1990         printf("Bridges type %x aren't managed for now\n", subclass);
1991         free(dev);
1992         goto out;
1993     }
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;
2004     }
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);
2016     }
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;
2032         }
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
2039          */
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 */
2058         }
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;
2070         }
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;
2077         }
2078         /* Set region address */
2079         newd->regions[i] = reloc | omask;
2080         newd->sizes[i] = size;
2081     }
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);
2086
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:
2094             {
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);
2102             }
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;
2112         }
2113     }
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);
2121
2122  out:
2123     return ret;
2124 }
2125
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)
2132 {
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;
2138
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,
2162                                      0,
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,
2191                                      0,
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;
2227     }
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;
2240             }
2241         }
2242     }
2243  done:
2244     free(fake_host->bridge);
2245  free_fake_host:
2246     free(fake_host);
2247
2248     return ret;
2249 }
2250
2251 static int pci_check_devices (pci_host_t *host)
2252 {
2253     int bus, devfn;
2254
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);
2261         }
2262     }
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);
2270         }
2271     }
2272
2273     return 0;
2274 }
2275
2276 pci_host_t *pci_init (void)
2277 {
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;
2282
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
2289          */
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++;
2307         }
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++;
2334         }
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
2344          */
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++;
2358         }
2359         for (curh = pci_main; curh->next != NULL; curh = curh->next)
2360             continue;
2361         pci_check_devices(curh);
2362 #endif
2363
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++;
2382         }
2383         for (curh = pci_main; curh->next != NULL; curh = curh->next)
2384             continue;
2385         pci_check_devices(curh);
2386
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++;
2400         }
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;
2409     }
2410     printf("PCI probe done (%p)\n", pci_main);
2411
2412     return pci_main;
2413 }
2414
2415 void pci_get_mem_range (pci_host_t *host, uint32_t *start, uint32_t *len)
2416 {
2417     *start = host->bridge->mem_base;
2418     *len = host->bridge->mem_len;
2419 }