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 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr
)
14 return addr
& 0xffffff;
17 static void pci_vpb_config_writeb (void *opaque
, target_phys_addr_t addr
,
20 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 1);
23 static void pci_vpb_config_writew (void *opaque
, target_phys_addr_t addr
,
26 #ifdef TARGET_WORDS_BIGENDIAN
29 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 2);
32 static void pci_vpb_config_writel (void *opaque
, target_phys_addr_t addr
,
35 #ifdef TARGET_WORDS_BIGENDIAN
38 pci_data_write(opaque
, vpb_pci_config_addr (addr
), val
, 4);
41 static uint32_t pci_vpb_config_readb (void *opaque
, target_phys_addr_t addr
)
44 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 1);
48 static uint32_t pci_vpb_config_readw (void *opaque
, target_phys_addr_t addr
)
51 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 2);
52 #ifdef TARGET_WORDS_BIGENDIAN
58 static uint32_t pci_vpb_config_readl (void *opaque
, target_phys_addr_t addr
)
61 val
= pci_data_read(opaque
, vpb_pci_config_addr (addr
), 4);
62 #ifdef TARGET_WORDS_BIGENDIAN
68 static CPUWriteMemoryFunc
*pci_vpb_config_write
[] = {
69 &pci_vpb_config_writeb
,
70 &pci_vpb_config_writew
,
71 &pci_vpb_config_writel
,
74 static CPUReadMemoryFunc
*pci_vpb_config_read
[] = {
75 &pci_vpb_config_readb
,
76 &pci_vpb_config_readw
,
77 &pci_vpb_config_readl
,
80 static int pci_vpb_irq
;
82 static int pci_vpb_map_irq(PCIDevice
*d
, int irq_num
)
87 static void pci_vpb_set_irq(qemu_irq
*pic
, int irq_num
, int level
)
89 qemu_set_irq(pic
[pci_vpb_irq
+ irq_num
], level
);
92 PCIBus
*pci_vpb_init(qemu_irq
*pic
, int irq
, int realview
)
103 name
= "RealView EB PCI Controller";
106 name
= "Versatile/PB PCI Controller";
108 s
= pci_register_bus(pci_vpb_set_irq
, pci_vpb_map_irq
, pic
, 11 << 3, 4);
109 /* ??? Register memory space. */
111 mem_config
= cpu_register_io_memory(0, pci_vpb_config_read
,
112 pci_vpb_config_write
, s
);
113 /* Selfconfig area. */
114 cpu_register_physical_memory(base
+ 0x01000000, 0x1000000, mem_config
);
115 /* Normal config area. */
116 cpu_register_physical_memory(base
+ 0x02000000, 0x1000000, mem_config
);
118 d
= pci_register_device(s
, name
, sizeof(PCIDevice
), -1, NULL
, NULL
);
121 /* IO memory area. */
122 isa_mmio_init(base
+ 0x03000000, 0x00100000);
125 d
->config
[0x00] = 0xee; // vendor_id
126 d
->config
[0x01] = 0x10;
127 /* Both boards have the same device ID. Oh well. */
128 d
->config
[0x02] = 0x00; // device_id
129 d
->config
[0x03] = 0x03;
130 d
->config
[0x04] = 0x00;
131 d
->config
[0x05] = 0x00;
132 d
->config
[0x06] = 0x20;
133 d
->config
[0x07] = 0x02;
134 d
->config
[0x08] = 0x00; // revision
135 d
->config
[0x09] = 0x00; // programming i/f
136 d
->config
[0x0A] = 0x40; // class_sub = pci host
137 d
->config
[0x0B] = 0x0b; // class_base = PCI_bridge
138 d
->config
[0x0D] = 0x10; // latency_timer