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