@@ -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);
@@ -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);
@@ -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
@@ -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,
@@ -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,
@@ -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);
@@ -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);
@@ -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)
@@ -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;
@@ -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);
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(-)