13cbee15bSj_mayer /* 23cbee15bSj_mayer * PowerMac MacIO device emulation 33cbee15bSj_mayer * 43cbee15bSj_mayer * Copyright (c) 2005-2007 Fabrice Bellard 53cbee15bSj_mayer * Copyright (c) 2007 Jocelyn Mayer 63cbee15bSj_mayer * 73cbee15bSj_mayer * Permission is hereby granted, free of charge, to any person obtaining a copy 83cbee15bSj_mayer * of this software and associated documentation files (the "Software"), to deal 93cbee15bSj_mayer * in the Software without restriction, including without limitation the rights 103cbee15bSj_mayer * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 113cbee15bSj_mayer * copies of the Software, and to permit persons to whom the Software is 123cbee15bSj_mayer * furnished to do so, subject to the following conditions: 133cbee15bSj_mayer * 143cbee15bSj_mayer * The above copyright notice and this permission notice shall be included in 153cbee15bSj_mayer * all copies or substantial portions of the Software. 163cbee15bSj_mayer * 173cbee15bSj_mayer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 183cbee15bSj_mayer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 193cbee15bSj_mayer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 203cbee15bSj_mayer * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 213cbee15bSj_mayer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 223cbee15bSj_mayer * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 233cbee15bSj_mayer * THE SOFTWARE. 243cbee15bSj_mayer */ 2583c9f4caSPaolo Bonzini #include "hw/hw.h" 2683c9f4caSPaolo Bonzini #include "hw/ppc/mac.h" 2783c9f4caSPaolo Bonzini #include "hw/pci/pci.h" 280d09e41aSPaolo Bonzini #include "hw/ppc/mac_dbdma.h" 290d09e41aSPaolo Bonzini #include "hw/char/escc.h" 303cbee15bSj_mayer 31fcf1bbabSAndreas Färber #define TYPE_MACIO "macio" 32fcf1bbabSAndreas Färber #define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO) 33fcf1bbabSAndreas Färber 34d8c51b05SAnthony Liguori typedef struct MacIOState 35d8c51b05SAnthony Liguori { 36fcf1bbabSAndreas Färber /*< private >*/ 37d8c51b05SAnthony Liguori PCIDevice parent; 38fcf1bbabSAndreas Färber /*< public >*/ 39fcf1bbabSAndreas Färber 4023c5e4caSAvi Kivity MemoryRegion bar; 4145fa67fbSAndreas Färber CUDAState cuda; 4207a7484eSAndreas Färber void *dbdma; 4323c5e4caSAvi Kivity MemoryRegion *pic_mem; 4423c5e4caSAvi Kivity MemoryRegion *escc_mem; 45d8c51b05SAnthony Liguori } MacIOState; 463cbee15bSj_mayer 4795ed3b7cSAndreas Färber #define OLDWORLD_MACIO(obj) \ 4895ed3b7cSAndreas Färber OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO) 4995ed3b7cSAndreas Färber 5095ed3b7cSAndreas Färber typedef struct OldWorldMacIOState { 5195ed3b7cSAndreas Färber /*< private >*/ 5295ed3b7cSAndreas Färber MacIOState parent_obj; 5395ed3b7cSAndreas Färber /*< public >*/ 5495ed3b7cSAndreas Färber 5514eefd0eSAlexander Graf qemu_irq irqs[5]; 5607a7484eSAndreas Färber 5795ed3b7cSAndreas Färber MacIONVRAMState nvram; 5814eefd0eSAlexander Graf MACIOIDEState ide[2]; 5995ed3b7cSAndreas Färber } OldWorldMacIOState; 6095ed3b7cSAndreas Färber 6107a7484eSAndreas Färber #define NEWWORLD_MACIO(obj) \ 6207a7484eSAndreas Färber OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO) 6307a7484eSAndreas Färber 6407a7484eSAndreas Färber typedef struct NewWorldMacIOState { 6507a7484eSAndreas Färber /*< private >*/ 6607a7484eSAndreas Färber MacIOState parent_obj; 6707a7484eSAndreas Färber /*< public >*/ 6845fa67fbSAndreas Färber qemu_irq irqs[5]; 6907a7484eSAndreas Färber MACIOIDEState ide[2]; 7007a7484eSAndreas Färber } NewWorldMacIOState; 7107a7484eSAndreas Färber 720d54a502SAlexander Graf /* 730d54a502SAlexander Graf * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", 740d54a502SAlexander Graf * while the other one is the normal, current ESCC interface. 750d54a502SAlexander Graf * 760d54a502SAlexander Graf * The magic below creates memory aliases to spawn the escc-legacy device 770d54a502SAlexander Graf * purely by rerouting the respective registers to our escc region. This 780d54a502SAlexander Graf * works because the only difference between the two memory regions is the 790d54a502SAlexander Graf * register layout, not their semantics. 800d54a502SAlexander Graf * 810d54a502SAlexander Graf * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf 820d54a502SAlexander Graf */ 830d54a502SAlexander Graf static void macio_escc_legacy_setup(MacIOState *macio_state) 840d54a502SAlexander Graf { 850d54a502SAlexander Graf MemoryRegion *escc_legacy = g_new(MemoryRegion, 1); 860d54a502SAlexander Graf MemoryRegion *bar = &macio_state->bar; 870d54a502SAlexander Graf int i; 880d54a502SAlexander Graf static const int maps[] = { 890d54a502SAlexander Graf 0x00, 0x00, 900d54a502SAlexander Graf 0x02, 0x20, 910d54a502SAlexander Graf 0x04, 0x10, 920d54a502SAlexander Graf 0x06, 0x30, 930d54a502SAlexander Graf 0x08, 0x40, 940d54a502SAlexander Graf 0x0A, 0x50, 950d54a502SAlexander Graf 0x60, 0x60, 960d54a502SAlexander Graf 0x70, 0x70, 970d54a502SAlexander Graf 0x80, 0x70, 980d54a502SAlexander Graf 0x90, 0x80, 990d54a502SAlexander Graf 0xA0, 0x90, 1000d54a502SAlexander Graf 0xB0, 0xA0, 1010d54a502SAlexander Graf 0xC0, 0xB0, 1020d54a502SAlexander Graf 0xD0, 0xC0, 1030d54a502SAlexander Graf 0xE0, 0xD0, 1040d54a502SAlexander Graf 0xF0, 0xE0, 1050d54a502SAlexander Graf }; 1060d54a502SAlexander Graf 1072c9b15caSPaolo Bonzini memory_region_init(escc_legacy, NULL, "escc-legacy", 256); 1080d54a502SAlexander Graf for (i = 0; i < ARRAY_SIZE(maps); i += 2) { 1090d54a502SAlexander Graf MemoryRegion *port = g_new(MemoryRegion, 1); 1102c9b15caSPaolo Bonzini memory_region_init_alias(port, NULL, "escc-legacy-port", 1112c9b15caSPaolo Bonzini macio_state->escc_mem, maps[i+1], 0x2); 1120d54a502SAlexander Graf memory_region_add_subregion(escc_legacy, maps[i], port); 1130d54a502SAlexander Graf } 1140d54a502SAlexander Graf 1150d54a502SAlexander Graf memory_region_add_subregion(bar, 0x12000, escc_legacy); 1160d54a502SAlexander Graf } 1170d54a502SAlexander Graf 118d8c51b05SAnthony Liguori static void macio_bar_setup(MacIOState *macio_state) 1193cbee15bSj_mayer { 12023c5e4caSAvi Kivity MemoryRegion *bar = &macio_state->bar; 1213cbee15bSj_mayer 12223c5e4caSAvi Kivity if (macio_state->escc_mem) { 12323c5e4caSAvi Kivity memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); 1240d54a502SAlexander Graf macio_escc_legacy_setup(macio_state); 1257fa9ae1aSblueswir1 } 1263cbee15bSj_mayer } 1273cbee15bSj_mayer 128d037834aSAndreas Färber static int macio_common_initfn(PCIDevice *d) 129d8c51b05SAnthony Liguori { 1307b925079SAndreas Färber MacIOState *s = MACIO(d); 13145fa67fbSAndreas Färber SysBusDevice *sysbus_dev; 13245fa67fbSAndreas Färber int ret; 1337b925079SAndreas Färber 134d8c51b05SAnthony Liguori d->config[0x3d] = 0x01; // interrupt on pin 1 1357b925079SAndreas Färber 13645fa67fbSAndreas Färber ret = qdev_init(DEVICE(&s->cuda)); 13745fa67fbSAndreas Färber if (ret < 0) { 13845fa67fbSAndreas Färber return ret; 13945fa67fbSAndreas Färber } 14045fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 14145fa67fbSAndreas Färber memory_region_add_subregion(&s->bar, 0x16000, 14245fa67fbSAndreas Färber sysbus_mmio_get_region(sysbus_dev, 0)); 14345fa67fbSAndreas Färber 1447b925079SAndreas Färber macio_bar_setup(s); 1457b925079SAndreas Färber pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); 1467b925079SAndreas Färber 147d8c51b05SAnthony Liguori return 0; 148d8c51b05SAnthony Liguori } 149d8c51b05SAnthony Liguori 15014eefd0eSAlexander Graf static int macio_initfn_ide(MacIOState *s, MACIOIDEState *ide, qemu_irq irq0, 15114eefd0eSAlexander Graf qemu_irq irq1, int dmaid) 15214eefd0eSAlexander Graf { 15314eefd0eSAlexander Graf SysBusDevice *sysbus_dev; 15414eefd0eSAlexander Graf 15514eefd0eSAlexander Graf sysbus_dev = SYS_BUS_DEVICE(ide); 15614eefd0eSAlexander Graf sysbus_connect_irq(sysbus_dev, 0, irq0); 15714eefd0eSAlexander Graf sysbus_connect_irq(sysbus_dev, 1, irq1); 15814eefd0eSAlexander Graf macio_ide_register_dma(ide, s->dbdma, dmaid); 15914eefd0eSAlexander Graf return qdev_init(DEVICE(ide)); 16014eefd0eSAlexander Graf } 16114eefd0eSAlexander Graf 162d037834aSAndreas Färber static int macio_oldworld_initfn(PCIDevice *d) 163d037834aSAndreas Färber { 164d037834aSAndreas Färber MacIOState *s = MACIO(d); 16595ed3b7cSAndreas Färber OldWorldMacIOState *os = OLDWORLD_MACIO(d); 16695ed3b7cSAndreas Färber SysBusDevice *sysbus_dev; 16714eefd0eSAlexander Graf int i; 16814eefd0eSAlexander Graf int cur_irq = 0; 169d037834aSAndreas Färber int ret = macio_common_initfn(d); 170d037834aSAndreas Färber if (ret < 0) { 171d037834aSAndreas Färber return ret; 172d037834aSAndreas Färber } 173d037834aSAndreas Färber 17445fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 17514eefd0eSAlexander Graf sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); 17645fa67fbSAndreas Färber 17795ed3b7cSAndreas Färber ret = qdev_init(DEVICE(&os->nvram)); 17895ed3b7cSAndreas Färber if (ret < 0) { 17995ed3b7cSAndreas Färber return ret; 18095ed3b7cSAndreas Färber } 18195ed3b7cSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&os->nvram); 18295ed3b7cSAndreas Färber memory_region_add_subregion(&s->bar, 0x60000, 18395ed3b7cSAndreas Färber sysbus_mmio_get_region(sysbus_dev, 0)); 18495ed3b7cSAndreas Färber pmac_format_nvram_partition(&os->nvram, os->nvram.size); 18595ed3b7cSAndreas Färber 186d037834aSAndreas Färber if (s->pic_mem) { 187d037834aSAndreas Färber /* Heathrow PIC */ 188d037834aSAndreas Färber memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem); 189d037834aSAndreas Färber } 190d037834aSAndreas Färber 19114eefd0eSAlexander Graf /* IDE buses */ 19214eefd0eSAlexander Graf for (i = 0; i < ARRAY_SIZE(os->ide); i++) { 19314eefd0eSAlexander Graf qemu_irq irq0 = os->irqs[cur_irq++]; 19414eefd0eSAlexander Graf qemu_irq irq1 = os->irqs[cur_irq++]; 19514eefd0eSAlexander Graf 19614eefd0eSAlexander Graf ret = macio_initfn_ide(s, &os->ide[i], irq0, irq1, 0x16 + (i * 4)); 19707a7484eSAndreas Färber if (ret < 0) { 19807a7484eSAndreas Färber return ret; 19907a7484eSAndreas Färber } 20014eefd0eSAlexander Graf } 20107a7484eSAndreas Färber 202d037834aSAndreas Färber return 0; 203d037834aSAndreas Färber } 204d037834aSAndreas Färber 20514eefd0eSAlexander Graf static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index) 20614eefd0eSAlexander Graf { 20714eefd0eSAlexander Graf gchar *name; 20814eefd0eSAlexander Graf 20914eefd0eSAlexander Graf object_initialize(ide, TYPE_MACIO_IDE); 21014eefd0eSAlexander Graf qdev_set_parent_bus(DEVICE(ide), sysbus_get_default()); 21114eefd0eSAlexander Graf memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), 21214eefd0eSAlexander Graf &ide->mem); 21314eefd0eSAlexander Graf name = g_strdup_printf("ide[%i]", index); 21414eefd0eSAlexander Graf object_property_add_child(OBJECT(s), name, OBJECT(ide), NULL); 21514eefd0eSAlexander Graf g_free(name); 21614eefd0eSAlexander Graf } 21714eefd0eSAlexander Graf 21895ed3b7cSAndreas Färber static void macio_oldworld_init(Object *obj) 21995ed3b7cSAndreas Färber { 22007a7484eSAndreas Färber MacIOState *s = MACIO(obj); 22195ed3b7cSAndreas Färber OldWorldMacIOState *os = OLDWORLD_MACIO(obj); 22295ed3b7cSAndreas Färber DeviceState *dev; 22314eefd0eSAlexander Graf int i; 22495ed3b7cSAndreas Färber 22507a7484eSAndreas Färber qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs)); 22607a7484eSAndreas Färber 22795ed3b7cSAndreas Färber object_initialize(&os->nvram, TYPE_MACIO_NVRAM); 22895ed3b7cSAndreas Färber dev = DEVICE(&os->nvram); 22995ed3b7cSAndreas Färber qdev_prop_set_uint32(dev, "size", 0x2000); 23095ed3b7cSAndreas Färber qdev_prop_set_uint32(dev, "it_shift", 4); 23107a7484eSAndreas Färber 23214eefd0eSAlexander Graf for (i = 0; i < 2; i++) { 23314eefd0eSAlexander Graf macio_init_ide(s, &os->ide[i], i); 23414eefd0eSAlexander Graf } 23595ed3b7cSAndreas Färber } 23695ed3b7cSAndreas Färber 237*a0f9fdfdSAlexander Graf static void timer_write(void *opaque, hwaddr addr, uint64_t value, 238*a0f9fdfdSAlexander Graf unsigned size) 239*a0f9fdfdSAlexander Graf { 240*a0f9fdfdSAlexander Graf } 241*a0f9fdfdSAlexander Graf 242*a0f9fdfdSAlexander Graf static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) 243*a0f9fdfdSAlexander Graf { 244*a0f9fdfdSAlexander Graf uint32_t value = 0; 245*a0f9fdfdSAlexander Graf 246*a0f9fdfdSAlexander Graf switch (addr) { 247*a0f9fdfdSAlexander Graf case 0x38: 248*a0f9fdfdSAlexander Graf value = qemu_get_clock_ns(vm_clock); 249*a0f9fdfdSAlexander Graf break; 250*a0f9fdfdSAlexander Graf case 0x3c: 251*a0f9fdfdSAlexander Graf value = qemu_get_clock_ns(vm_clock) >> 32; 252*a0f9fdfdSAlexander Graf break; 253*a0f9fdfdSAlexander Graf } 254*a0f9fdfdSAlexander Graf 255*a0f9fdfdSAlexander Graf return value; 256*a0f9fdfdSAlexander Graf } 257*a0f9fdfdSAlexander Graf 258*a0f9fdfdSAlexander Graf static const MemoryRegionOps timer_ops = { 259*a0f9fdfdSAlexander Graf .read = timer_read, 260*a0f9fdfdSAlexander Graf .write = timer_write, 261*a0f9fdfdSAlexander Graf .endianness = DEVICE_NATIVE_ENDIAN, 262*a0f9fdfdSAlexander Graf }; 263*a0f9fdfdSAlexander Graf 264d037834aSAndreas Färber static int macio_newworld_initfn(PCIDevice *d) 265d037834aSAndreas Färber { 266d037834aSAndreas Färber MacIOState *s = MACIO(d); 26707a7484eSAndreas Färber NewWorldMacIOState *ns = NEWWORLD_MACIO(d); 26807a7484eSAndreas Färber SysBusDevice *sysbus_dev; 269*a0f9fdfdSAlexander Graf MemoryRegion *timer_memory = g_new(MemoryRegion, 1); 27014eefd0eSAlexander Graf int i; 27114eefd0eSAlexander Graf int cur_irq = 0; 272d037834aSAndreas Färber int ret = macio_common_initfn(d); 273d037834aSAndreas Färber if (ret < 0) { 274d037834aSAndreas Färber return ret; 275d037834aSAndreas Färber } 276d037834aSAndreas Färber 27745fa67fbSAndreas Färber sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 27814eefd0eSAlexander Graf sysbus_connect_irq(sysbus_dev, 0, ns->irqs[cur_irq++]); 27945fa67fbSAndreas Färber 280d037834aSAndreas Färber if (s->pic_mem) { 281d037834aSAndreas Färber /* OpenPIC */ 282d037834aSAndreas Färber memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem); 283d037834aSAndreas Färber } 284d037834aSAndreas Färber 28514eefd0eSAlexander Graf /* IDE buses */ 28614eefd0eSAlexander Graf for (i = 0; i < ARRAY_SIZE(ns->ide); i++) { 28714eefd0eSAlexander Graf qemu_irq irq0 = ns->irqs[cur_irq++]; 28814eefd0eSAlexander Graf qemu_irq irq1 = ns->irqs[cur_irq++]; 28914eefd0eSAlexander Graf 29014eefd0eSAlexander Graf ret = macio_initfn_ide(s, &ns->ide[i], irq0, irq1, 0x16 + (i * 4)); 29107a7484eSAndreas Färber if (ret < 0) { 29207a7484eSAndreas Färber return ret; 29307a7484eSAndreas Färber } 29407a7484eSAndreas Färber } 29507a7484eSAndreas Färber 296*a0f9fdfdSAlexander Graf /* Timer */ 297*a0f9fdfdSAlexander Graf memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer", 298*a0f9fdfdSAlexander Graf 0x1000); 299*a0f9fdfdSAlexander Graf memory_region_add_subregion(&s->bar, 0x15000, timer_memory); 300*a0f9fdfdSAlexander Graf 301d037834aSAndreas Färber return 0; 302d037834aSAndreas Färber } 303d037834aSAndreas Färber 30407a7484eSAndreas Färber static void macio_newworld_init(Object *obj) 30507a7484eSAndreas Färber { 30607a7484eSAndreas Färber MacIOState *s = MACIO(obj); 30707a7484eSAndreas Färber NewWorldMacIOState *ns = NEWWORLD_MACIO(obj); 30807a7484eSAndreas Färber int i; 30907a7484eSAndreas Färber 31007a7484eSAndreas Färber qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs)); 31107a7484eSAndreas Färber 31207a7484eSAndreas Färber for (i = 0; i < 2; i++) { 31314eefd0eSAlexander Graf macio_init_ide(s, &ns->ide[i], i); 31407a7484eSAndreas Färber } 31507a7484eSAndreas Färber } 31607a7484eSAndreas Färber 317fcf1bbabSAndreas Färber static void macio_instance_init(Object *obj) 318fcf1bbabSAndreas Färber { 319fcf1bbabSAndreas Färber MacIOState *s = MACIO(obj); 32007a7484eSAndreas Färber MemoryRegion *dbdma_mem; 321fcf1bbabSAndreas Färber 3222c9b15caSPaolo Bonzini memory_region_init(&s->bar, NULL, "macio", 0x80000); 32307a7484eSAndreas Färber 32445fa67fbSAndreas Färber object_initialize(&s->cuda, TYPE_CUDA); 32545fa67fbSAndreas Färber qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); 32645fa67fbSAndreas Färber object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL); 32745fa67fbSAndreas Färber 32807a7484eSAndreas Färber s->dbdma = DBDMA_init(&dbdma_mem); 32907a7484eSAndreas Färber memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem); 330fcf1bbabSAndreas Färber } 331fcf1bbabSAndreas Färber 332d037834aSAndreas Färber static void macio_oldworld_class_init(ObjectClass *oc, void *data) 333d037834aSAndreas Färber { 334d037834aSAndreas Färber PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); 335d037834aSAndreas Färber 336d037834aSAndreas Färber pdc->init = macio_oldworld_initfn; 337d037834aSAndreas Färber pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201; 338d037834aSAndreas Färber } 339d037834aSAndreas Färber 340d037834aSAndreas Färber static void macio_newworld_class_init(ObjectClass *oc, void *data) 341d037834aSAndreas Färber { 342d037834aSAndreas Färber PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); 343d037834aSAndreas Färber 344d037834aSAndreas Färber pdc->init = macio_newworld_initfn; 345d037834aSAndreas Färber pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL; 346d037834aSAndreas Färber } 347d037834aSAndreas Färber 34840021f08SAnthony Liguori static void macio_class_init(ObjectClass *klass, void *data) 34940021f08SAnthony Liguori { 35040021f08SAnthony Liguori PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 35140021f08SAnthony Liguori 35240021f08SAnthony Liguori k->vendor_id = PCI_VENDOR_ID_APPLE; 35340021f08SAnthony Liguori k->class_id = PCI_CLASS_OTHERS << 8; 35440021f08SAnthony Liguori } 35540021f08SAnthony Liguori 356d037834aSAndreas Färber static const TypeInfo macio_oldworld_type_info = { 357d037834aSAndreas Färber .name = TYPE_OLDWORLD_MACIO, 358d037834aSAndreas Färber .parent = TYPE_MACIO, 35995ed3b7cSAndreas Färber .instance_size = sizeof(OldWorldMacIOState), 36095ed3b7cSAndreas Färber .instance_init = macio_oldworld_init, 361d037834aSAndreas Färber .class_init = macio_oldworld_class_init, 362d037834aSAndreas Färber }; 363d037834aSAndreas Färber 364d037834aSAndreas Färber static const TypeInfo macio_newworld_type_info = { 365d037834aSAndreas Färber .name = TYPE_NEWWORLD_MACIO, 366d037834aSAndreas Färber .parent = TYPE_MACIO, 36707a7484eSAndreas Färber .instance_size = sizeof(NewWorldMacIOState), 36807a7484eSAndreas Färber .instance_init = macio_newworld_init, 369d037834aSAndreas Färber .class_init = macio_newworld_class_init, 370d037834aSAndreas Färber }; 371d037834aSAndreas Färber 372fcf1bbabSAndreas Färber static const TypeInfo macio_type_info = { 373fcf1bbabSAndreas Färber .name = TYPE_MACIO, 37439bffca2SAnthony Liguori .parent = TYPE_PCI_DEVICE, 37539bffca2SAnthony Liguori .instance_size = sizeof(MacIOState), 376fcf1bbabSAndreas Färber .instance_init = macio_instance_init, 377d037834aSAndreas Färber .abstract = true, 37840021f08SAnthony Liguori .class_init = macio_class_init, 379d8c51b05SAnthony Liguori }; 380d8c51b05SAnthony Liguori 38183f7d43aSAndreas Färber static void macio_register_types(void) 382d8c51b05SAnthony Liguori { 383fcf1bbabSAndreas Färber type_register_static(&macio_type_info); 384d037834aSAndreas Färber type_register_static(&macio_oldworld_type_info); 385d037834aSAndreas Färber type_register_static(&macio_newworld_type_info); 386d8c51b05SAnthony Liguori } 387d8c51b05SAnthony Liguori 38883f7d43aSAndreas Färber type_init(macio_register_types) 389d8c51b05SAnthony Liguori 390d037834aSAndreas Färber void macio_init(PCIDevice *d, 39107a7484eSAndreas Färber MemoryRegion *pic_mem, 39223c5e4caSAvi Kivity MemoryRegion *escc_mem) 3933cbee15bSj_mayer { 394d037834aSAndreas Färber MacIOState *macio_state = MACIO(d); 3953cbee15bSj_mayer 39623c5e4caSAvi Kivity macio_state->pic_mem = pic_mem; 39723c5e4caSAvi Kivity macio_state->escc_mem = escc_mem; 3983cbee15bSj_mayer /* Note: this code is strongly inspirated from the corresponding code 3993cbee15bSj_mayer in PearPC */ 400deb54399Saliguori 4017b925079SAndreas Färber qdev_init_nofail(DEVICE(d)); 4023cbee15bSj_mayer } 403