2 * ARM Versatile/PB PCI host controller
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licenced under the LGPL.
12 #include "primecell.h"
14 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr
)
16 return addr
& 0xffffff;
19 static void pci_vpb_config_writeb (void *opaque
, target_phys_addr_t addr
,
22 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 1);
25 static void pci_vpb_config_writew (void *opaque
, target_phys_addr_t addr
,
28 #ifdef TARGET_WORDS_BIGENDIAN
31 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 2);
34 static void pci_vpb_config_writel (void *opaque
, target_phys_addr_t addr
,
37 #ifdef TARGET_WORDS_BIGENDIAN
40 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 4);
43 static uint32_t pci_vpb_config_readb (void *opaque
, target_phys_addr_t addr
)
46 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 1);
50 static uint32_t pci_vpb_config_readw (void *opaque
, target_phys_addr_t addr
)
53 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 2);
54 #ifdef TARGET_WORDS_BIGENDIAN
60 static uint32_t pci_vpb_config_readl (void *opaque
, target_phys_addr_t addr
)
63 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 4);
64 #ifdef TARGET_WORDS_BIGENDIAN
70 static CPUWriteMemoryFunc
*pci_vpb_config_write
[] = {
71 &pci_vpb_config_writeb
,
72 &pci_vpb_config_writew
,
73 &pci_vpb_config_writel
,
76 static CPUReadMemoryFunc
*pci_vpb_config_read
[] = {
77 &pci_vpb_config_readb
,
78 &pci_vpb_config_readw
,
79 &pci_vpb_config_readl
,
82 static int pci_vpb_irq
;
84 static int pci_vpb_map_irq(PCIDevice
*d
, int irq_num
)
89 static void pci_vpb_set_irq(qemu_irq
*pic
, int irq_num
, int level
)
91 qemu_set_irq(pic
[pci_vpb_irq
+ irq_num
], level
);
94 PCIBus
*pci_vpb_init(qemu_irq
*pic
, int irq
, int realview
)
105 name
= "RealView EB PCI Controller";
108 name
= "Versatile/PB PCI Controller";
110 s
= pci_register_bus(pci_vpb_set_irq
, pci_vpb_map_irq
, pic
, 11 << 3, 4);
111 /* ??? Register memory space. */
113 mem_config
= cpu_register_io_memory(0, pci_vpb_config_read
,
114 pci_vpb_config_write
, s
);
115 /* Selfconfig area. */
116 cpu_register_physical_memory(base
+ 0x01000000, 0x1000000, mem_config
);
117 /* Normal config area. */
118 cpu_register_physical_memory(base
+ 0x02000000, 0x1000000, mem_config
);
120 d
= pci_register_device(s
, name
, sizeof(PCIDevice
), -1, NULL
, NULL
);
123 /* IO memory area. */
124 isa_mmio_init(base
+ 0x03000000, 0x00100000);
127 d
->config
[0x00] = 0xee; // vendor_id
128 d
->config
[0x01] = 0x10;
129 /* Both boards have the same device ID. Oh well. */
130 d
->config
[0x02] = 0x00; // device_id
131 d
->config
[0x03] = 0x03;
132 d
->config
[0x04] = 0x00;
133 d
->config
[0x05] = 0x00;
134 d
->config
[0x06] = 0x20;
135 d
->config
[0x07] = 0x02;
136 d
->config
[0x08] = 0x00; // revision
137 d
->config
[0x09] = 0x00; // programming i/f
138 d
->config
[0x0A] = 0x40; // class_sub = pci host
139 d
->config
[0x0B] = 0x0b; // class_base = PCI_bridge
140 d
->config
[0x0D] = 0x10; // latency_timer