diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ide.h | 4 | ||||
-rw-r--r-- | hw/ide/macio.c | 78 | ||||
-rw-r--r-- | hw/macio.c | 102 | ||||
-rw-r--r-- | hw/ppc/mac.h | 25 | ||||
-rw-r--r-- | hw/ppc/mac_newworld.c | 28 | ||||
-rw-r--r-- | hw/ppc/mac_oldworld.c | 36 |
6 files changed, 195 insertions, 78 deletions
@@ -19,10 +19,6 @@ 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); -/* ide-macio.c */ -MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, - void *dbdma, int channel, qemu_irq dma_irq); - /* ide-mmio.c */ void mmio_ide_init (hwaddr membase, hwaddr membase2, MemoryRegion *address_space, diff --git a/hw/ide/macio.c b/hw/ide/macio.c index e0f04dc..375c46f 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -33,12 +33,6 @@ /***********************************************************/ /* MacIO based PowerPC IDE */ -typedef struct MACIOIDEState { - MemoryRegion mem; - IDEBus bus; - BlockDriverAIOCB *aiocb; -} MACIOIDEState; - #define MACIO_PAGE_SIZE 4096 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) @@ -321,30 +315,70 @@ static const VMStateDescription vmstate_pmac = { } }; -static void pmac_ide_reset(void *opaque) +static void macio_ide_reset(DeviceState *dev) { - MACIOIDEState *d = opaque; + MACIOIDEState *d = MACIO_IDE(dev); ide_bus_reset(&d->bus); } -/* hd_table must contain 4 block drivers */ -/* PowerMac uses memory mapped registers, not I/O. Return the memory - I/O index to access the ide. */ -MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, - void *dbdma, int channel, qemu_irq dma_irq) +static void macio_ide_realizefn(DeviceState *dev, Error **errp) { - MACIOIDEState *d; + MACIOIDEState *s = MACIO_IDE(dev); + + ide_init2(&s->bus, s->irq); +} + +static void macio_ide_initfn(Object *obj) +{ + SysBusDevice *d = SYS_BUS_DEVICE(obj); + MACIOIDEState *s = MACIO_IDE(obj); + + ide_bus_new(&s->bus, DEVICE(obj), 0); + memory_region_init_io(&s->mem, &pmac_ide_ops, s, "pmac-ide", 0x1000); + sysbus_init_mmio(d, &s->mem); + sysbus_init_irq(d, &s->irq); + sysbus_init_irq(d, &s->dma_irq); +} + +static void macio_ide_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = macio_ide_realizefn; + dc->reset = macio_ide_reset; + dc->vmsd = &vmstate_pmac; +} - d = g_malloc0(sizeof(MACIOIDEState)); - ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq); +static const TypeInfo macio_ide_type_info = { + .name = TYPE_MACIO_IDE, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MACIOIDEState), + .instance_init = macio_ide_initfn, + .class_init = macio_ide_class_init, +}; - if (dbdma) - DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d); +static void macio_ide_register_types(void) +{ + type_register_static(&macio_ide_type_info); +} - memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000); - vmstate_register(NULL, 0, &vmstate_pmac, d); - qemu_register_reset(pmac_ide_reset, d); +/* hd_table must contain 4 block drivers */ +void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) +{ + int i; - return &d->mem; + for (i = 0; i < 2; i++) { + if (hd_table[i]) { + ide_create_drive(&s->bus, i, hd_table[i]); + } + } } + +void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) +{ + DBDMA_register_channel(dbdma, channel, s->dma_irq, + pmac_ide_transfer, pmac_ide_flush, s); +} + +type_init(macio_ide_register_types) @@ -25,6 +25,7 @@ #include "hw.h" #include "ppc/mac.h" #include "pci/pci.h" +#include "mac_dbdma.h" #include "escc.h" #define TYPE_MACIO "macio" @@ -37,12 +38,10 @@ typedef struct MacIOState /*< public >*/ MemoryRegion bar; + void *dbdma; MemoryRegion *pic_mem; - MemoryRegion *dbdma_mem; MemoryRegion *cuda_mem; MemoryRegion *escc_mem; - int nb_ide; - MemoryRegion *ide_mem[4]; } MacIOState; #define OLDWORLD_MACIO(obj) \ @@ -53,29 +52,33 @@ typedef struct OldWorldMacIOState { MacIOState parent_obj; /*< public >*/ + qemu_irq irqs[2]; + MacIONVRAMState nvram; + MACIOIDEState ide; } OldWorldMacIOState; +#define NEWWORLD_MACIO(obj) \ + OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO) + +typedef struct NewWorldMacIOState { + /*< private >*/ + MacIOState parent_obj; + /*< public >*/ + qemu_irq irqs[4]; + MACIOIDEState ide[2]; +} NewWorldMacIOState; + static void macio_bar_setup(MacIOState *macio_state) { - int i; MemoryRegion *bar = &macio_state->bar; - if (macio_state->dbdma_mem) { - memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem); - } if (macio_state->escc_mem) { memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); } if (macio_state->cuda_mem) { memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem); } - for (i = 0; i < macio_state->nb_ide; i++) { - if (macio_state->ide_mem[i]) { - memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000), - macio_state->ide_mem[i]); - } - } } static int macio_common_initfn(PCIDevice *d) @@ -114,23 +117,42 @@ static int macio_oldworld_initfn(PCIDevice *d) memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem); } + sysbus_dev = SYS_BUS_DEVICE(&os->ide); + sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]); + sysbus_connect_irq(sysbus_dev, 1, os->irqs[1]); + macio_ide_register_dma(&os->ide, s->dbdma, 0x16); + ret = qdev_init(DEVICE(&os->ide)); + if (ret < 0) { + return ret; + } + return 0; } static void macio_oldworld_init(Object *obj) { + MacIOState *s = MACIO(obj); OldWorldMacIOState *os = OLDWORLD_MACIO(obj); DeviceState *dev; + qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs)); + object_initialize(&os->nvram, TYPE_MACIO_NVRAM); dev = DEVICE(&os->nvram); qdev_prop_set_uint32(dev, "size", 0x2000); qdev_prop_set_uint32(dev, "it_shift", 4); + + object_initialize(&os->ide, TYPE_MACIO_IDE); + qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default()); + memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem); + object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL); } static int macio_newworld_initfn(PCIDevice *d) { MacIOState *s = MACIO(d); + NewWorldMacIOState *ns = NEWWORLD_MACIO(d); + SysBusDevice *sysbus_dev; int ret = macio_common_initfn(d); if (ret < 0) { return ret; @@ -141,14 +163,56 @@ static int macio_newworld_initfn(PCIDevice *d) memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem); } + sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]); + sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]); + sysbus_connect_irq(sysbus_dev, 1, ns->irqs[1]); + macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16); + ret = qdev_init(DEVICE(&ns->ide[0])); + if (ret < 0) { + return ret; + } + + sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]); + sysbus_connect_irq(sysbus_dev, 0, ns->irqs[2]); + sysbus_connect_irq(sysbus_dev, 1, ns->irqs[3]); + macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a); + ret = qdev_init(DEVICE(&ns->ide[1])); + if (ret < 0) { + return ret; + } + return 0; } +static void macio_newworld_init(Object *obj) +{ + MacIOState *s = MACIO(obj); + NewWorldMacIOState *ns = NEWWORLD_MACIO(obj); + int i; + gchar *name; + + qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs)); + + for (i = 0; i < 2; i++) { + object_initialize(&ns->ide[i], TYPE_MACIO_IDE); + qdev_set_parent_bus(DEVICE(&ns->ide[i]), sysbus_get_default()); + memory_region_add_subregion(&s->bar, 0x1f000 + ((i + 1) * 0x1000), + &ns->ide[i].mem); + name = g_strdup_printf("ide[%i]", i); + object_property_add_child(obj, name, OBJECT(&ns->ide[i]), NULL); + g_free(name); + } +} + static void macio_instance_init(Object *obj) { MacIOState *s = MACIO(obj); + MemoryRegion *dbdma_mem; memory_region_init(&s->bar, "macio", 0x80000); + + s->dbdma = DBDMA_init(&dbdma_mem); + memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem); } static void macio_oldworld_class_init(ObjectClass *oc, void *data) @@ -186,6 +250,8 @@ static const TypeInfo macio_oldworld_type_info = { static const TypeInfo macio_newworld_type_info = { .name = TYPE_NEWWORLD_MACIO, .parent = TYPE_MACIO, + .instance_size = sizeof(NewWorldMacIOState), + .instance_init = macio_newworld_init, .class_init = macio_newworld_class_init, }; @@ -208,23 +274,15 @@ static void macio_register_types(void) type_init(macio_register_types) void macio_init(PCIDevice *d, - MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *pic_mem, MemoryRegion *cuda_mem, - int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem) { MacIOState *macio_state = MACIO(d); - int i; macio_state->pic_mem = pic_mem; - macio_state->dbdma_mem = dbdma_mem; macio_state->cuda_mem = cuda_mem; macio_state->escc_mem = escc_mem; - if (nb_ide > 4) - nb_ide = 4; - macio_state->nb_ide = nb_ide; - for (i = 0; i < nb_ide; i++) - macio_state->ide_mem[i] = ide_mem[i]; /* Note: this code is strongly inspirated from the corresponding code in PearPC */ diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 581e95c..3e390d3 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -27,6 +27,7 @@ #include "exec/memory.h" #include "hw/sysbus.h" +#include "hw/ide/internal.h" /* SMP is not enabled, for now */ #define MAX_CPUS 1 @@ -48,10 +49,30 @@ void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq); /* MacIO */ #define TYPE_OLDWORLD_MACIO "macio-oldworld" #define TYPE_NEWWORLD_MACIO "macio-newworld" + +#define TYPE_MACIO_IDE "macio-ide" +#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) + +typedef struct MACIOIDEState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + qemu_irq irq; + qemu_irq dma_irq; + + MemoryRegion mem; + IDEBus bus; + BlockDriverAIOCB *aiocb; +} MACIOIDEState; + +void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); +void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel); + void macio_init(PCIDevice *dev, - MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *pic_mem, MemoryRegion *cuda_mem, - int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem); + MemoryRegion *escc_mem); /* Heathrow PIC */ qemu_irq *heathrow_pic_init(MemoryRegion **pmem, diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index a4b38fb..4fd86b0 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -148,15 +148,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) long kernel_size, initrd_size; PCIBus *pci_bus; PCIDevice *macio; + MACIOIDEState *macio_ide; MacIONVRAMState *nvr; int bios_size; - MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem; + MemoryRegion *pic_mem, *cuda_mem, *escc_mem; MemoryRegion *escc_bar = g_new(MemoryRegion, 1); - MemoryRegion *ide_mem[3]; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; - void *dbdma; int machine_arch; SysBusDevice *s; DeviceState *dev; @@ -363,12 +362,6 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); - dbdma = DBDMA_init(&dbdma_mem); - - /* We only emulate 2 out of 3 IDE controllers for now */ - ide_mem[0] = NULL; - ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); - ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]); cuda_init(&cuda_mem, pic[0x19]); @@ -376,8 +369,21 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) adb_mouse_init(&adb_bus); macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO); - macio_init(macio, pic_mem, - dbdma_mem, cuda_mem, 3, ide_mem, escc_bar); + dev = DEVICE(macio); + qdev_connect_gpio_out(dev, 0, pic[0x0d]); /* IDE */ + qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */ + qdev_connect_gpio_out(dev, 2, pic[0x0e]); /* IDE */ + qdev_connect_gpio_out(dev, 3, pic[0x02]); /* IDE DMA */ + macio_init(macio, pic_mem, cuda_mem, escc_bar); + + /* We only emulate 2 out of 3 IDE controllers for now */ + macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), + "ide[0]")); + macio_ide_init_drives(macio_ide, hd); + + macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), + "ide[1]")); + macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); if (usb_enabled(machine_arch == ARCH_MAC99_U3)) { pci_create_simple(pci_bus, -1, "pci-ohci"); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 29b3277..6039ea6 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -27,7 +27,6 @@ #include "hw/ppc.h" #include "mac.h" #include "hw/adb.h" -#include "hw/mac_dbdma.h" #include "hw/nvram.h" #include "sysemu/sysemu.h" #include "net/net.h" @@ -91,13 +90,14 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) int32_t kernel_size, initrd_size; PCIBus *pci_bus; PCIDevice *macio; + MACIOIDEState *macio_ide; + DeviceState *dev; int bios_size; - MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem; - MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2]; + MemoryRegion *pic_mem, *cuda_mem; + MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1); uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; - void *dbdma; linux_boot = (kernel_filename != NULL); @@ -263,17 +263,6 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) ide_drive_get(hd, MAX_IDE_BUS); - /* First IDE channel is a MAC IDE on the MacIO bus */ - dbdma = DBDMA_init(&dbdma_mem); - ide_mem[0] = NULL; - ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); - - /* Second IDE channel is a CMD646 on the PCI bus */ - hd[0] = hd[MAX_IDE_DEVS]; - hd[1] = hd[MAX_IDE_DEVS + 1]; - hd[3] = hd[2] = NULL; - pci_cmd646_ide_init(pci_bus, hd, 0); - /* cuda also initialize ADB */ cuda_init(&cuda_mem, pic[0x12]); @@ -281,8 +270,21 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) adb_mouse_init(&adb_bus); macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); - macio_init(macio, pic_mem, - dbdma_mem, cuda_mem, 2, ide_mem, escc_bar); + dev = DEVICE(macio); + qdev_connect_gpio_out(dev, 0, pic[0x0D]); /* IDE */ + qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */ + macio_init(macio, pic_mem, cuda_mem, escc_bar); + + /* First IDE channel is a MAC IDE on the MacIO bus */ + macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), + "ide")); + macio_ide_init_drives(macio_ide, hd); + + /* Second IDE channel is a CMD646 on the PCI bus */ + hd[0] = hd[MAX_IDE_DEVS]; + hd[1] = hd[MAX_IDE_DEVS + 1]; + hd[3] = hd[2] = NULL; + pci_cmd646_ide_init(pci_bus, hd, 0); if (usb_enabled(false)) { pci_create_simple(pci_bus, -1, "pci-ohci"); |