[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 7/7] PPC: Qdev'ify e500 pci
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 7/7] PPC: Qdev'ify e500 pci |
Date: |
Tue, 10 May 2011 00:15:26 +0200 |
The e500 PCI controller isn't qdev'ified yet. This leads to severe issues
when running with -drive.
To be able to use a virtio disk with an e500 VM, let's convert the PCI
controller over to qdev.
Reviewed-by: Paul Brook <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
v2 -> v3:
- rebase to current code base
- fix endian issue
- use sysbus helpers
v3 -> v4:
- drop base_addr
v4 -> v5:
- model qdev conversion similar to versatilepb (pbrook)
v5 -> v6:
- use qdev.vmsd for vmstate registration (pbrook)
---
hw/ppce500.h | 22 --------
hw/ppce500_mpc8544ds.c | 16 +++---
hw/ppce500_pci.c | 136 +++++++++++++++++++++++++++---------------------
3 files changed, 84 insertions(+), 90 deletions(-)
delete mode 100644 hw/ppce500.h
diff --git a/hw/ppce500.h b/hw/ppce500.h
deleted file mode 100644
index 24d49bb..0000000
--- a/hw/ppce500.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * QEMU PowerPC E500 emulation shared definitions
- *
- * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Yu Liu, <address@hidden>
- *
- * This file is derived from hw/ppc440.h
- * the copyright for that material belongs to the original owners.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#if !defined(PPC_E500_H)
-#define PPC_E500_H
-
-PCIBus *ppce500_pci_init(qemu_irq *pic, target_phys_addr_t registers);
-
-#endif /* !defined(PPC_E500_H) */
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 96c37df..17b0165 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -29,9 +29,9 @@
#include "device_tree.h"
#include "openpic.h"
#include "ppc.h"
-#include "ppce500.h"
#include "loader.h"
#include "elf.h"
+#include "sysbus.h"
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
#define UIMAGE_LOAD_BASE 0
@@ -222,7 +222,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
target_long initrd_size=0;
int i=0;
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
- qemu_irq *irqs, *mpic, *pci_irqs;
+ qemu_irq *irqs, *mpic;
+ DeviceState *dev;
struct boot_info *boot_info;
/* Setup CPU */
@@ -270,12 +271,11 @@ static void mpc8544ds_init(ram_addr_t ram_size,
}
/* PCI */
- pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
- pci_irqs[0] = mpic[pci_irq_nrs[0]];
- pci_irqs[1] = mpic[pci_irq_nrs[1]];
- pci_irqs[2] = mpic[pci_irq_nrs[2]];
- pci_irqs[3] = mpic[pci_irq_nrs[3]];
- pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE);
+ dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
+ mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
+ mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
+ NULL);
+ pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
if (!pci_bus)
printf("couldn't create PCI controller!\n");
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 83a20e4..069af96 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -15,7 +15,6 @@
*/
#include "hw.h"
-#include "ppce500.h"
#include "pci.h"
#include "pci_host.h"
#include "bswap.h"
@@ -29,7 +28,8 @@
#define PCIE500_CFGADDR 0x0
#define PCIE500_CFGDATA 0x4
#define PCIE500_REG_BASE 0xC00
-#define PCIE500_REG_SIZE (0x1000 - PCIE500_REG_BASE)
+#define PCIE500_ALL_SIZE 0x1000
+#define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE)
#define PPCE500_PCI_CONFIG_ADDR 0x0
#define PPCE500_PCI_CONFIG_DATA 0x4
@@ -73,11 +73,15 @@ struct pci_inbound {
};
struct PPCE500PCIState {
+ PCIHostState pci_state;
struct pci_outbound pob[PPCE500_PCI_NR_POBS];
struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
uint32_t gasket_time;
- PCIHostState pci_state;
- PCIDevice *pci_dev;
+ qemu_irq irq[4];
+ /* mmio maps */
+ int cfgaddr;
+ int cfgdata;
+ int reg;
};
typedef struct PPCE500PCIState PPCE500PCIState;
@@ -250,7 +254,6 @@ static const VMStateDescription vmstate_ppce500_pci = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPCE500PCIState),
VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1,
vmstate_pci_outbound, struct pci_outbound),
VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1,
@@ -260,60 +263,73 @@ static const VMStateDescription vmstate_ppce500_pci = {
}
};
-PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
+static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
+{
+ PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+ PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
+
+ cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr);
+ cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata);
+ cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
+ s->reg);
+}
+
+static int e500_pcihost_initfn(SysBusDevice *dev)
+{
+ PCIHostState *h;
+ PPCE500PCIState *s;
+ PCIBus *b;
+ int i;
+
+ h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+ s = DO_UPCAST(PPCE500PCIState, pci_state, h);
+
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
+ sysbus_init_irq(dev, &s->irq[i]);
+ }
+
+ b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
+ mpc85xx_pci_map_irq, s->irq, PCI_DEVFN(0x11, 0), 4);
+ s->pci_state.bus = b;
+
+ pci_create_simple(b, 0, "e500-host-bridge");
+
+ s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN);
+ s->cfgdata = pci_host_data_register_mmio(&s->pci_state,
+ DEVICE_LITTLE_ENDIAN);
+ s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
+ DEVICE_BIG_ENDIAN);
+ sysbus_init_mmio_cb(dev, PCIE500_ALL_SIZE, e500_pci_map);
+
+ return 0;
+}
+
+static int e500_host_bridge_initfn(PCIDevice *dev)
+{
+ pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_FREESCALE);
+ pci_config_set_device_id(dev->config, PCI_DEVICE_ID_MPC8533E);
+ pci_config_set_class(dev->config, PCI_CLASS_PROCESSOR_POWERPC);
+
+ return 0;
+}
+
+static PCIDeviceInfo e500_host_bridge_info = {
+ .qdev.name = "e500-host-bridge",
+ .qdev.desc = "Host bridge",
+ .qdev.size = sizeof(PCIDevice),
+ .init = e500_host_bridge_initfn,
+};
+
+static SysBusDeviceInfo e500_pcihost_info = {
+ .init = e500_pcihost_initfn,
+ .qdev.name = "e500-pcihost",
+ .qdev.size = sizeof(PPCE500PCIState),
+ .qdev.vmsd = &vmstate_ppce500_pci,
+};
+
+static void e500_pci_register(void)
{
- PPCE500PCIState *controller;
- PCIDevice *d;
- int index;
- static int ppce500_pci_id;
-
- controller = qemu_mallocz(sizeof(PPCE500PCIState));
-
- controller->pci_state.bus = pci_register_bus(NULL, "pci",
- mpc85xx_pci_set_irq,
- mpc85xx_pci_map_irq,
- pci_irqs, PCI_DEVFN(0x11, 0),
- 4);
- d = pci_register_device(controller->pci_state.bus,
- "host bridge", sizeof(PCIDevice),
- 0, NULL, NULL);
-
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_FREESCALE);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_MPC8533E);
- pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_POWERPC);
-
- controller->pci_dev = d;
-
- /* CFGADDR */
- index = pci_host_conf_register_mmio(&controller->pci_state,
- DEVICE_BIG_ENDIAN);
- if (index < 0)
- goto free;
- cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
-
- /* CFGDATA */
- index = pci_host_data_register_mmio(&controller->pci_state,
- DEVICE_BIG_ENDIAN);
- if (index < 0)
- goto free;
- cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
-
- index = cpu_register_io_memory(e500_pci_reg_read,
- e500_pci_reg_write, controller,
- DEVICE_NATIVE_ENDIAN);
- if (index < 0)
- goto free;
- cpu_register_physical_memory(registers + PCIE500_REG_BASE,
- PCIE500_REG_SIZE, index);
-
- /* XXX load/save code not tested. */
- vmstate_register(&d->qdev, ppce500_pci_id++, &vmstate_ppce500_pci,
- controller);
-
- return controller->pci_state.bus;
-
-free:
- printf("%s error\n", __func__);
- qemu_free(controller);
- return NULL;
+ sysbus_register_withprop(&e500_pcihost_info);
+ pci_qdev_register(&e500_host_bridge_info);
}
+device_init(e500_pci_register);
--
1.6.0.2
- [Qemu-devel] [PATCH 0/7] PPC: Add FSL (e500) MMU emulation v6, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 1/7] PPC: Make MPC8544DS obey -cpu switch, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 6/7] PPC MPC7544DS: Use new TLB helper function, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 7/7] PPC: Qdev'ify e500 pci,
Alexander Graf <=
- [Qemu-devel] [PATCH 3/7] PPC: Add GS MSR definition, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 2/7] PPC: Make MPC8544DS emulation work w/o KVM, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 4/7] PPC: Add another 64 bits to instruction feature mask, Alexander Graf, 2011/05/09
- [Qemu-devel] [PATCH 5/7] PPC: Implement e500 (FSL) MMU, Alexander Graf, 2011/05/09