Revision 13b7fdef hw/ppce500_pci.c
b/hw/ppce500_pci.c | ||
---|---|---|
73 | 73 |
}; |
74 | 74 |
|
75 | 75 |
struct PPCE500PCIState { |
76 |
PCIHostState pci_state; |
|
76 | 77 |
struct pci_outbound pob[PPCE500_PCI_NR_POBS]; |
77 | 78 |
struct pci_inbound pib[PPCE500_PCI_NR_PIBS]; |
78 | 79 |
uint32_t gasket_time; |
79 |
PCIHostState pci_state; |
|
80 |
PCIDevice *pci_dev; |
|
80 |
uint64_t base_addr; |
|
81 | 81 |
}; |
82 | 82 |
|
83 | 83 |
typedef struct PPCE500PCIState PPCE500PCIState; |
... | ... | |
221 | 221 |
PPCE500PCIState *controller = opaque; |
222 | 222 |
int i; |
223 | 223 |
|
224 |
pci_device_save(controller->pci_dev, f);
|
|
224 |
/* pci_device_save(controller->pci_dev, f); */
|
|
225 | 225 |
|
226 | 226 |
for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { |
227 | 227 |
qemu_put_be32s(f, &controller->pob[i].potar); |
... | ... | |
247 | 247 |
if (version_id != 1) |
248 | 248 |
return -EINVAL; |
249 | 249 |
|
250 |
pci_device_load(controller->pci_dev, f);
|
|
250 |
/* pci_device_load(controller->pci_dev, f); */
|
|
251 | 251 |
|
252 | 252 |
for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { |
253 | 253 |
qemu_get_be32s(f, &controller->pob[i].potar); |
... | ... | |
269 | 269 |
|
270 | 270 |
PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers) |
271 | 271 |
{ |
272 |
PPCE500PCIState *controller; |
|
272 |
DeviceState *dev; |
|
273 |
PCIBus *b; |
|
274 |
PCIHostState *h; |
|
275 |
PPCE500PCIState *s; |
|
273 | 276 |
PCIDevice *d; |
274 |
int index; |
|
275 | 277 |
static int ppce500_pci_id; |
276 | 278 |
|
277 |
controller = qemu_mallocz(sizeof(PPCE500PCIState)); |
|
279 |
dev = qdev_create(NULL, "e500-pcihost"); |
|
280 |
h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); |
|
281 |
s = DO_UPCAST(PPCE500PCIState, pci_state, h); |
|
282 |
|
|
283 |
qdev_prop_set_uint64(dev, "base_addr", registers); |
|
284 |
b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq, |
|
285 |
mpc85xx_pci_map_irq, pci_irqs, PCI_DEVFN(0x11, 0), 4); |
|
286 |
|
|
287 |
s->pci_state.bus = b; |
|
288 |
qdev_init_nofail(dev); |
|
289 |
d = pci_create_simple(b, 0, "e500-host-bridge"); |
|
290 |
|
|
291 |
/* XXX load/save code not tested. */ |
|
292 |
register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++, |
|
293 |
1, ppce500_pci_save, ppce500_pci_load, s); |
|
278 | 294 |
|
279 |
controller->pci_state.bus = pci_register_bus(NULL, "pci", |
|
280 |
mpc85xx_pci_set_irq, |
|
281 |
mpc85xx_pci_map_irq, |
|
282 |
pci_irqs, PCI_DEVFN(0x11, 0), |
|
283 |
4); |
|
284 |
d = pci_register_device(controller->pci_state.bus, |
|
285 |
"host bridge", sizeof(PCIDevice), |
|
286 |
0, NULL, NULL); |
|
295 |
return b; |
|
296 |
} |
|
287 | 297 |
|
288 |
pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_FREESCALE); |
|
289 |
pci_config_set_device_id(d->config, PCI_DEVICE_ID_MPC8533E); |
|
290 |
pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_POWERPC); |
|
298 |
static int e500_pcihost_initfn(SysBusDevice *dev) |
|
299 |
{ |
|
300 |
PCIHostState *h; |
|
301 |
PPCE500PCIState *s; |
|
302 |
target_phys_addr_t registers; |
|
303 |
int index; |
|
291 | 304 |
|
292 |
controller->pci_dev = d; |
|
305 |
h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); |
|
306 |
s = DO_UPCAST(PPCE500PCIState, pci_state, h); |
|
307 |
registers = (target_phys_addr_t)s->base_addr; |
|
293 | 308 |
|
294 | 309 |
/* CFGADDR */ |
295 |
index = pci_host_conf_register_mmio(&controller->pci_state, 0);
|
|
310 |
index = pci_host_conf_register_mmio(&s->pci_state, 0);
|
|
296 | 311 |
if (index < 0) |
297 |
goto free;
|
|
312 |
return -1;
|
|
298 | 313 |
cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index); |
299 | 314 |
|
300 | 315 |
/* CFGDATA */ |
301 |
index = pci_host_data_register_mmio(&controller->pci_state, 0);
|
|
316 |
index = pci_host_data_register_mmio(&s->pci_state, 0);
|
|
302 | 317 |
if (index < 0) |
303 |
goto free;
|
|
318 |
return -1;
|
|
304 | 319 |
cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index); |
305 | 320 |
|
306 | 321 |
index = cpu_register_io_memory(e500_pci_reg_read, |
307 |
e500_pci_reg_write, controller);
|
|
322 |
e500_pci_reg_write, s);
|
|
308 | 323 |
if (index < 0) |
309 |
goto free;
|
|
324 |
return -1;
|
|
310 | 325 |
cpu_register_physical_memory(registers + PCIE500_REG_BASE, |
311 | 326 |
PCIE500_REG_SIZE, index); |
327 |
return 0; |
|
328 |
} |
|
312 | 329 |
|
313 |
/* XXX load/save code not tested. */ |
|
314 |
register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++, |
|
315 |
1, ppce500_pci_save, ppce500_pci_load, controller); |
|
330 |
static int e500_host_bridge_initfn(PCIDevice *dev) |
|
331 |
{ |
|
332 |
pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_FREESCALE); |
|
333 |
pci_config_set_device_id(dev->config, PCI_DEVICE_ID_MPC8533E); |
|
334 |
pci_config_set_class(dev->config, PCI_CLASS_PROCESSOR_POWERPC); |
|
335 |
|
|
336 |
return 0; |
|
337 |
} |
|
338 |
|
|
339 |
static PCIDeviceInfo e500_host_bridge_info = { |
|
340 |
.qdev.name = "e500-host-bridge", |
|
341 |
.qdev.desc = "Host bridge", |
|
342 |
.qdev.size = sizeof(PCIDevice), |
|
343 |
.qdev.no_user = 1, |
|
344 |
.init = e500_host_bridge_initfn, |
|
345 |
}; |
|
316 | 346 |
|
317 |
return controller->pci_state.bus; |
|
347 |
static SysBusDeviceInfo e500_pcihost_info = { |
|
348 |
.init = e500_pcihost_initfn, |
|
349 |
.qdev.name = "e500-pcihost", |
|
350 |
.qdev.size = sizeof(PPCE500PCIState), |
|
351 |
.qdev.no_user = 1, |
|
352 |
.qdev.props = (Property[]) { |
|
353 |
DEFINE_PROP_UINT64("base_addr", PPCE500PCIState, base_addr, 0), |
|
354 |
DEFINE_PROP_END_OF_LIST(), |
|
355 |
} |
|
356 |
}; |
|
318 | 357 |
|
319 |
free:
|
|
320 |
printf("%s error\n", __func__);
|
|
321 |
qemu_free(controller);
|
|
322 |
return NULL;
|
|
358 |
static void e500_pci_register(void)
|
|
359 |
{
|
|
360 |
sysbus_register_withprop(&e500_pcihost_info);
|
|
361 |
pci_qdev_register(&e500_host_bridge_info);
|
|
323 | 362 |
} |
363 |
device_init(e500_pci_register); |
Also available in: Unified diff