Patchwork [09/10] convert IDE as piix3 proper QOM child

login
register
mail settings
Submitter Wanpeng Li
Date Nov. 8, 2012, 5:36 a.m.
Message ID <1352352999-2561-10-git-send-email-liwanp@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/197780/
State New
Headers show

Comments

Wanpeng Li - Nov. 8, 2012, 5:36 a.m.
convert IDE as piix3 proper QOM child.

IDE creation for the PIIX3 is done by calling object_init() with
qdev_init() being called for each child device in the PIIX3 ::init
function.

Signed-off-by: Wanpeng Li <liwanp@linux.vnet.ibm.com>

---
 hw/i440fx.c       |    6 ++++++
 hw/ide.h          |    6 ++++--
 hw/ide/internal.h |    9 +++++++++
 hw/ide/isa.c      |   14 +-------------
 hw/ide/piix.c     |   24 ++----------------------
 hw/pc.c           |   28 +++++-----------------------
 hw/pc.h           |    4 ++++
 hw/piix3.c        |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/piix3.h        |    7 +++++++
 sysemu.h          |    2 --
 10 files changed, 85 insertions(+), 62 deletions(-)

Patch

diff --git a/hw/i440fx.c b/hw/i440fx.c
index 5196201..e994722 100644
--- a/hw/i440fx.c
+++ b/hw/i440fx.c
@@ -193,6 +193,12 @@  static int i440fx_realize(SysBusDevice *dev)
     h->bus = pci_bus_new(DEVICE(s), NULL, &s->pci_address_space,
                          s->address_space_io, 0);
 
+    if (pci_is_enabled) {
+        qdev_set_parent_bus(DEVICE(&s->piix3.ide.pci), BUS(h->bus));
+    } else {
+        qdev_set_parent_bus(DEVICE(&s->piix3.ide.isa), BUS(h->bus));
+    }
+
     memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops, s,
                           "pci-conf-idx", 4);
     sysbus_add_io(dev, 0xcf8, &h->conf_mem);
diff --git a/hw/ide.h b/hw/ide.h
index add742c..7060124 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -7,6 +7,10 @@ 
 
 #define MAX_IDE_DEVS	2
 
+#define TYPE_PIIX3_IDE_XEN "piix3-ide-xen"
+#define TYPE_PIIX3_IDE "piix3-ide"
+#define TYPE_ISA_IDE "isa-ide"
+
 /* ide-isa.c */
 ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
                         DriveInfo *hd0, DriveInfo *hd1);
@@ -14,8 +18,6 @@  ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
 /* ide-pci.c */
 void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
                          int secondary_ide_enabled);
-PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
-PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index bf7d313..3114f8c 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -483,6 +483,15 @@  struct IDEDevice {
     uint64_t wwn;
 };
 
+typedef struct ISAIDEState {
+    ISADevice dev;
+    IDEBus    bus;
+    uint32_t  iobase;
+    uint32_t  iobase2;
+    uint32_t  isairq;
+    qemu_irq  irq;
+} ISAIDEState;
+
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
 #define BM_STATUS_INT    0x04
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 8ab2718..ca206ca 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -30,18 +30,6 @@ 
 
 #include <hw/ide/internal.h>
 
-/***********************************************************/
-/* ISA IDE definitions */
-
-typedef struct ISAIDEState {
-    ISADevice dev;
-    IDEBus    bus;
-    uint32_t  iobase;
-    uint32_t  iobase2;
-    uint32_t  isairq;
-    qemu_irq  irq;
-} ISAIDEState;
-
 static void isa_ide_reset(DeviceState *d)
 {
     ISAIDEState *s = container_of(d, ISAIDEState, dev.qdev);
@@ -112,7 +100,7 @@  static void isa_ide_class_initfn(ObjectClass *klass, void *data)
 }
 
 static TypeInfo isa_ide_info = {
-    .name          = "isa-ide",
+    .name          = TYPE_ISA_IDE,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(ISAIDEState),
     .class_init    = isa_ide_class_initfn,
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 9431bad..3e53302 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -192,15 +192,6 @@  static int pci_piix3_xen_ide_unplug(DeviceState *dev)
     return 0;
 }
 
-PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
-{
-    PCIDevice *dev;
-
-    dev = pci_create_simple(bus, devfn, "piix3-ide-xen");
-    pci_ide_create_devs(dev, hd_table);
-    return dev;
-}
-
 static void pci_piix_ide_exitfn(PCIDevice *dev)
 {
     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
@@ -216,17 +207,6 @@  static void pci_piix_ide_exitfn(PCIDevice *dev)
 }
 
 /* hd_table must contain 4 block drivers */
-/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
-PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
-{
-    PCIDevice *dev;
-
-    dev = pci_create_simple(bus, devfn, "piix3-ide");
-    pci_ide_create_devs(dev, hd_table);
-    return dev;
-}
-
-/* hd_table must contain 4 block drivers */
 /* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
 PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
 {
@@ -252,7 +232,7 @@  static void piix3_ide_class_init(ObjectClass *klass, void *data)
 }
 
 static TypeInfo piix3_ide_info = {
-    .name          = "piix3-ide",
+    .name          = TYPE_PIIX3_IDE,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIIDEState),
     .class_init    = piix3_ide_class_init,
@@ -272,7 +252,7 @@  static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
 }
 
 static TypeInfo piix3_ide_xen_info = {
-    .name          = "piix3-ide-xen",
+    .name          = TYPE_PIIX3_IDE_XEN,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIIDEState),
     .class_init    = piix3_ide_xen_class_init,
diff --git a/hw/pc.c b/hw/pc.c
index 9798c24..74cec55 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -77,7 +77,7 @@ 
 
 #define E820_NR_ENTRIES		16
 
-#define MAX_IDE_BUS 2
+BusState *idebus[MAX_IDE_BUS];
 
 struct e820_entry {
     uint64_t address;
@@ -97,6 +97,8 @@  static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 static struct e820_table e820_table;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
 
+int pci_is_enabled;
+
 static void gsi_handler(void *opaque, int n, int level)
 {
     GSIState *s = opaque;
@@ -1090,13 +1092,13 @@  static void pc_init1(MemoryRegion *system_memory,
     qemu_irq *i8259;
     qemu_irq *smi_irq;
     GSIState *gsi_state;
-    DriveInfo * hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
     ISADevice *floppy;
 
     void *fw_cfg = NULL;
 
+    pci_is_enabled = pci_enabled;
+
     pc_cpus_init(cpu_model);
 
     if (kvmclock_enabled) {
@@ -1175,26 +1177,6 @@  static void pc_init1(MemoryRegion *system_memory,
         }
     }
 
-    ide_drive_get(hd, MAX_IDE_BUS);
-    if (pci_enabled) {
-        PCIDevice *dev;
-        if (xen_enabled()) {
-            dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
-        } else {
-            dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
-        }
-        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
-        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
-    } else {
-        for (i = 0; i < MAX_IDE_BUS; i++) {
-            ISADevice *dev;
-            dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
-                               ide_irq[i],
-                               hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
-            idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
-        }
-    }
-
     /* FIXME */
     rtc_state = ISA_DEVICE(object_resolve_path("rtc", NULL));
     qemu_register_boot_set(pc_boot_set, rtc_state);
diff --git a/hw/pc.h b/hw/pc.h
index 5b7bc26..620349f 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -138,6 +138,10 @@  void pc_system_firmware_init(MemoryRegion *rom_memory);
 #define E820_NVS        4
 #define E820_UNUSABLE   5
 
+extern BusState *idebus[MAX_IDE_BUS];
+
+extern int pci_is_enabled;
+
 int e820_add_entry(uint64_t, uint64_t, uint32_t);
 
 void handle_a20_line_change(void *opaque, int irq, int level);
diff --git a/hw/piix3.c b/hw/piix3.c
index 2922fd4..7ca0f83 100644
--- a/hw/piix3.c
+++ b/hw/piix3.c
@@ -33,6 +33,10 @@ 
 #include "pc.h"
 #include "pcspk.h"
 
+static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
+static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
+static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
+
 void piix3_set_irq(void *opaque, int pirq, int level)
 {
     PIIX3State *piix3 = opaque;
@@ -197,6 +201,8 @@  static int piix3_realize(PCIDevice *dev)
     int pit_isa_irq = 0;
     qemu_irq pit_alt_irq = NULL;
     qemu_irq *a20_line;
+    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    int i;
 
     /* Initialize ISA Bus */
     s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev));
@@ -282,6 +288,31 @@  static int piix3_realize(PCIDevice *dev)
         qdev_init_nofail(DEVICE(&s->vmmouse));
     }
 
+    /* Realize the IDE */
+    ide_drive_get(hd, MAX_IDE_BUS);
+    if (pci_is_enabled) {
+        s->ide.pci.dev.devfn = s->dev.devfn + 1;
+        qdev_init_nofail(DEVICE(&s->ide.pci));
+        pci_ide_create_devs(&s->ide.pci.dev, hd);
+        idebus[0] = qdev_get_child_bus(DEVICE(&s->ide.pci), "ide.0");
+        idebus[1] = qdev_get_child_bus(DEVICE(&s->ide.pci), "ide.1");
+    } else {
+        for (i = 0; i < MAX_IDE_BUS; i++) {
+            qdev_prop_set_uint32(DEVICE(&s->ide.isa), "iobase", ide_iobase[i]);
+            qdev_prop_set_uint32(DEVICE(&s->ide.isa), "iobase2",
+                                                         ide_iobase2[i]);
+            qdev_prop_set_uint32(DEVICE(&s->ide.isa), "irq", ide_irq[i]);
+            qdev_init_nofail(DEVICE(&s->ide.isa));
+            if (hd[MAX_IDE_DEVS * i]) {
+                ide_create_drive(&s->ide.isa.bus, 0, hd[MAX_IDE_DEVS * i]);
+            }
+            if (hd[MAX_IDE_DEVS * i + 1]) {
+                ide_create_drive(&s->ide.isa.bus, 1, hd[MAX_IDE_DEVS * i + 1]);
+            }
+            idebus[i] = qdev_get_child_bus(DEVICE(&s->ide.isa), "ide.0");
+        }
+    }
+
     return 0;
 }
 
@@ -328,6 +359,22 @@  static void piix3_initfn(Object *obj)
 
     object_initialize(&s->vmmouse, TYPE_VMMOUSE);
     object_property_add_child(obj, "vmmouse", OBJECT(&s->vmmouse), NULL);
+
+    if (pci_is_enabled) {
+        if (xen_enabled()) {
+            object_initialize(&s->ide.pci, TYPE_PIIX3_IDE_XEN);
+            object_property_add_child(obj, "piix3-ide-xen",
+                                          OBJECT(&s->ide.pci), NULL);
+        } else {
+            object_initialize(&s->ide.pci, TYPE_PIIX3_IDE);
+            object_property_add_child(obj, "piix3-ide",
+                                          OBJECT(&s->ide.pci), NULL);
+        }
+    } else {
+        object_initialize(&s->ide.isa, TYPE_ISA_IDE);
+        object_property_add_child(obj, "isa-ide",
+                                          OBJECT(&s->ide.isa), NULL);
+    }
 }
 
 static void piix3_class_init(ObjectClass *klass, void *data)
diff --git a/hw/piix3.h b/hw/piix3.h
index 29ae820..8916e4a 100644
--- a/hw/piix3.h
+++ b/hw/piix3.h
@@ -37,6 +37,7 @@ 
 #include "pcspk.h"
 #include "ps2.h"
 #include "console.h"
+#include "ide/pci.h"
 
 #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
 #define PIIX_NUM_PIRQS          4ULL    /* PIRQ[A-D] */
@@ -61,6 +62,8 @@  typedef struct KVMPITState {
 #define TYPE_VMMOUSE "vmmouse"
 #define VMMOUSE_QUEUE_SIZE 1024
 
+#define MAX_IDE_BUS 2
+
 typedef struct _VMMouseState {
     ISADevice dev;
     uint32_t queue[VMMOUSE_QUEUE_SIZE];
@@ -141,6 +144,10 @@  typedef struct PIIX3State {
     PCSpkState pcspk;
     Port92State port92;
     ISAKBDState i8042;
+    union {
+        ISAIDEState isa;
+        PCIIDEState pci;
+    } ide;
 
     qemu_irq *pic;
 
diff --git a/sysemu.h b/sysemu.h
index f5ac664..9bcb04b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -175,8 +175,6 @@  void usb_info(Monitor *mon);
 
 void rtc_change_mon_event(struct tm *tm);
 
-void register_devices(void);
-
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
                           const char *suffix);
 char *get_boot_devices_list(uint32_t *size);