Merge branch 'master' of git://git.qemu.org/qemu
[qemu.git] / hw / ppc4xx_pci.c
blob2c69210225fadbf7f124c6d1a076229922a36920
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
14 * Copyright IBM Corp. 2008
16 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 /* This file implements emulation of the 32-bit PCI controller found in some
20 * 4xx SoCs, such as the 440EP. */
22 #include "hw.h"
23 #include "ppc.h"
24 #include "ppc4xx.h"
25 #include "pci.h"
26 #include "pci_host.h"
27 #include "exec-memory.h"
29 #undef DEBUG
30 #ifdef DEBUG
31 #define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0)
32 #else
33 #define DPRINTF(fmt, ...)
34 #endif /* DEBUG */
36 struct PCIMasterMap {
37 uint32_t la;
38 uint32_t ma;
39 uint32_t pcila;
40 uint32_t pciha;
43 struct PCITargetMap {
44 uint32_t ms;
45 uint32_t la;
48 #define PPC4xx_PCI_NR_PMMS 3
49 #define PPC4xx_PCI_NR_PTMS 2
51 struct PPC4xxPCIState {
52 struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS];
53 struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS];
55 PCIHostState pci_state;
56 PCIDevice *pci_dev;
57 MemoryRegion iomem_addr;
58 MemoryRegion iomem_regs;
60 typedef struct PPC4xxPCIState PPC4xxPCIState;
62 #define PCIC0_CFGADDR 0x0
63 #define PCIC0_CFGDATA 0x4
65 /* PLB Memory Map (PMM) registers specify which PLB addresses are translated to
66 * PCI accesses. */
67 #define PCIL0_PMM0LA 0x0
68 #define PCIL0_PMM0MA 0x4
69 #define PCIL0_PMM0PCILA 0x8
70 #define PCIL0_PMM0PCIHA 0xc
71 #define PCIL0_PMM1LA 0x10
72 #define PCIL0_PMM1MA 0x14
73 #define PCIL0_PMM1PCILA 0x18
74 #define PCIL0_PMM1PCIHA 0x1c
75 #define PCIL0_PMM2LA 0x20
76 #define PCIL0_PMM2MA 0x24
77 #define PCIL0_PMM2PCILA 0x28
78 #define PCIL0_PMM2PCIHA 0x2c
80 /* PCI Target Map (PTM) registers specify which PCI addresses are translated to
81 * PLB accesses. */
82 #define PCIL0_PTM1MS 0x30
83 #define PCIL0_PTM1LA 0x34
84 #define PCIL0_PTM2MS 0x38
85 #define PCIL0_PTM2LA 0x3c
86 #define PCI_REG_SIZE 0x40
89 static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr,
90 unsigned size)
92 PPC4xxPCIState *ppc4xx_pci = opaque;
94 return ppc4xx_pci->pci_state.config_reg;
97 static void pci4xx_cfgaddr_write(void *opaque, target_phys_addr_t addr,
98 uint64_t value, unsigned size)
100 PPC4xxPCIState *ppc4xx_pci = opaque;
102 ppc4xx_pci->pci_state.config_reg = value & ~0x3;
105 static const MemoryRegionOps pci4xx_cfgaddr_ops = {
106 .read = pci4xx_cfgaddr_read,
107 .write = pci4xx_cfgaddr_write,
108 .endianness = DEVICE_LITTLE_ENDIAN,
111 static void ppc4xx_pci_reg_write4(void *opaque, target_phys_addr_t offset,
112 uint64_t value, unsigned size)
114 struct PPC4xxPCIState *pci = opaque;
116 /* We ignore all target attempts at PCI configuration, effectively
117 * assuming a bidirectional 1:1 mapping of PLB and PCI space. */
119 switch (offset) {
120 case PCIL0_PMM0LA:
121 pci->pmm[0].la = value;
122 break;
123 case PCIL0_PMM0MA:
124 pci->pmm[0].ma = value;
125 break;
126 case PCIL0_PMM0PCIHA:
127 pci->pmm[0].pciha = value;
128 break;
129 case PCIL0_PMM0PCILA:
130 pci->pmm[0].pcila = value;
131 break;
133 case PCIL0_PMM1LA:
134 pci->pmm[1].la = value;
135 break;
136 case PCIL0_PMM1MA:
137 pci->pmm[1].ma = value;
138 break;
139 case PCIL0_PMM1PCIHA:
140 pci->pmm[1].pciha = value;
141 break;
142 case PCIL0_PMM1PCILA:
143 pci->pmm[1].pcila = value;
144 break;
146 case PCIL0_PMM2LA:
147 pci->pmm[2].la = value;
148 break;
149 case PCIL0_PMM2MA:
150 pci->pmm[2].ma = value;
151 break;
152 case PCIL0_PMM2PCIHA:
153 pci->pmm[2].pciha = value;
154 break;
155 case PCIL0_PMM2PCILA:
156 pci->pmm[2].pcila = value;
157 break;
159 case PCIL0_PTM1MS:
160 pci->ptm[0].ms = value;
161 break;
162 case PCIL0_PTM1LA:
163 pci->ptm[0].la = value;
164 break;
165 case PCIL0_PTM2MS:
166 pci->ptm[1].ms = value;
167 break;
168 case PCIL0_PTM2LA:
169 pci->ptm[1].la = value;
170 break;
172 default:
173 printf("%s: unhandled PCI internal register 0x%lx\n", __func__,
174 (unsigned long)offset);
175 break;
179 static uint64_t ppc4xx_pci_reg_read4(void *opaque, target_phys_addr_t offset,
180 unsigned size)
182 struct PPC4xxPCIState *pci = opaque;
183 uint32_t value;
185 switch (offset) {
186 case PCIL0_PMM0LA:
187 value = pci->pmm[0].la;
188 break;
189 case PCIL0_PMM0MA:
190 value = pci->pmm[0].ma;
191 break;
192 case PCIL0_PMM0PCIHA:
193 value = pci->pmm[0].pciha;
194 break;
195 case PCIL0_PMM0PCILA:
196 value = pci->pmm[0].pcila;
197 break;
199 case PCIL0_PMM1LA:
200 value = pci->pmm[1].la;
201 break;
202 case PCIL0_PMM1MA:
203 value = pci->pmm[1].ma;
204 break;
205 case PCIL0_PMM1PCIHA:
206 value = pci->pmm[1].pciha;
207 break;
208 case PCIL0_PMM1PCILA:
209 value = pci->pmm[1].pcila;
210 break;
212 case PCIL0_PMM2LA:
213 value = pci->pmm[2].la;
214 break;
215 case PCIL0_PMM2MA:
216 value = pci->pmm[2].ma;
217 break;
218 case PCIL0_PMM2PCIHA:
219 value = pci->pmm[2].pciha;
220 break;
221 case PCIL0_PMM2PCILA:
222 value = pci->pmm[2].pcila;
223 break;
225 case PCIL0_PTM1MS:
226 value = pci->ptm[0].ms;
227 break;
228 case PCIL0_PTM1LA:
229 value = pci->ptm[0].la;
230 break;
231 case PCIL0_PTM2MS:
232 value = pci->ptm[1].ms;
233 break;
234 case PCIL0_PTM2LA:
235 value = pci->ptm[1].la;
236 break;
238 default:
239 printf("%s: invalid PCI internal register 0x%lx\n", __func__,
240 (unsigned long)offset);
241 value = 0;
244 return value;
247 static const MemoryRegionOps pci_reg_ops = {
248 .read = ppc4xx_pci_reg_read4,
249 .write = ppc4xx_pci_reg_write4,
250 .endianness = DEVICE_LITTLE_ENDIAN,
253 static void ppc4xx_pci_reset(void *opaque)
255 struct PPC4xxPCIState *pci = opaque;
257 memset(pci->pmm, 0, sizeof(pci->pmm));
258 memset(pci->ptm, 0, sizeof(pci->ptm));
261 /* On Bamboo, all pins from each slot are tied to a single board IRQ. This
262 * may need further refactoring for other boards. */
263 static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
265 int slot = pci_dev->devfn >> 3;
267 DPRINTF("%s: devfn %x irq %d -> %d\n", __func__,
268 pci_dev->devfn, irq_num, slot);
270 return slot - 1;
273 static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
275 qemu_irq *pci_irqs = opaque;
277 DPRINTF("%s: PCI irq %d\n", __func__, irq_num);
278 qemu_set_irq(pci_irqs[irq_num], level);
281 static const VMStateDescription vmstate_pci_master_map = {
282 .name = "pci_master_map",
283 .version_id = 0,
284 .minimum_version_id = 0,
285 .minimum_version_id_old = 0,
286 .fields = (VMStateField[]) {
287 VMSTATE_UINT32(la, struct PCIMasterMap),
288 VMSTATE_UINT32(ma, struct PCIMasterMap),
289 VMSTATE_UINT32(pcila, struct PCIMasterMap),
290 VMSTATE_UINT32(pciha, struct PCIMasterMap),
291 VMSTATE_END_OF_LIST()
295 static const VMStateDescription vmstate_pci_target_map = {
296 .name = "pci_target_map",
297 .version_id = 0,
298 .minimum_version_id = 0,
299 .minimum_version_id_old = 0,
300 .fields = (VMStateField[]) {
301 VMSTATE_UINT32(ms, struct PCITargetMap),
302 VMSTATE_UINT32(la, struct PCITargetMap),
303 VMSTATE_END_OF_LIST()
307 static const VMStateDescription vmstate_ppc4xx_pci = {
308 .name = "ppc4xx_pci",
309 .version_id = 1,
310 .minimum_version_id = 1,
311 .minimum_version_id_old = 1,
312 .fields = (VMStateField[]) {
313 VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState),
314 VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1,
315 vmstate_pci_master_map,
316 struct PCIMasterMap),
317 VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1,
318 vmstate_pci_target_map,
319 struct PCITargetMap),
320 VMSTATE_END_OF_LIST()
324 /* XXX Interrupt acknowledge cycles not supported. */
325 PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
326 target_phys_addr_t config_space,
327 target_phys_addr_t int_ack,
328 target_phys_addr_t special_cycle,
329 target_phys_addr_t registers)
331 PPC4xxPCIState *controller;
332 static int ppc4xx_pci_id;
333 uint8_t *pci_conf;
335 controller = g_malloc0(sizeof(PPC4xxPCIState));
337 controller->pci_state.bus = pci_register_bus(NULL, "pci",
338 ppc4xx_pci_set_irq,
339 ppc4xx_pci_map_irq,
340 pci_irqs,
341 get_system_memory(),
342 get_system_io(),
343 0, 4);
345 controller->pci_dev = pci_register_device(controller->pci_state.bus,
346 "host bridge", sizeof(PCIDevice),
347 0, NULL, NULL);
348 pci_conf = controller->pci_dev->config;
349 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);
350 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_440GX);
351 pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
353 /* CFGADDR */
354 memory_region_init_io(&controller->iomem_addr, &pci4xx_cfgaddr_ops,
355 controller, "pci.cfgaddr", 4);
356 memory_region_add_subregion(get_system_memory(),
357 config_space + PCIC0_CFGADDR,
358 &controller->iomem_addr);
360 /* CFGDATA */
361 memory_region_init_io(&controller->pci_state.data_mem,
362 &pci_host_data_be_ops,
363 &controller->pci_state, "pci-conf-data", 4);
364 memory_region_add_subregion(get_system_memory(),
365 config_space + PCIC0_CFGDATA,
366 &controller->pci_state.data_mem);
368 /* Internal registers */
369 memory_region_init_io(&controller->iomem_regs, &pci_reg_ops, controller,
370 "pci.regs", PCI_REG_SIZE);
371 memory_region_add_subregion(get_system_memory(), registers,
372 &controller->iomem_regs);
374 qemu_register_reset(ppc4xx_pci_reset, controller);
376 /* XXX load/save code not tested. */
377 vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++,
378 &vmstate_ppc4xx_pci, controller);
380 return controller->pci_state.bus;