1b8842209SGerd Hoffmann /* 2b8842209SGerd Hoffmann * QEMU IDE Emulation: MacIO support. 3b8842209SGerd Hoffmann * 4b8842209SGerd Hoffmann * Copyright (c) 2003 Fabrice Bellard 5b8842209SGerd Hoffmann * Copyright (c) 2006 Openedhand Ltd. 6b8842209SGerd Hoffmann * 7b8842209SGerd Hoffmann * Permission is hereby granted, free of charge, to any person obtaining a copy 8b8842209SGerd Hoffmann * of this software and associated documentation files (the "Software"), to deal 9b8842209SGerd Hoffmann * in the Software without restriction, including without limitation the rights 10b8842209SGerd Hoffmann * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11b8842209SGerd Hoffmann * copies of the Software, and to permit persons to whom the Software is 12b8842209SGerd Hoffmann * furnished to do so, subject to the following conditions: 13b8842209SGerd Hoffmann * 14b8842209SGerd Hoffmann * The above copyright notice and this permission notice shall be included in 15b8842209SGerd Hoffmann * all copies or substantial portions of the Software. 16b8842209SGerd Hoffmann * 17b8842209SGerd Hoffmann * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18b8842209SGerd Hoffmann * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19b8842209SGerd Hoffmann * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20b8842209SGerd Hoffmann * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21b8842209SGerd Hoffmann * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22b8842209SGerd Hoffmann * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23b8842209SGerd Hoffmann * THE SOFTWARE. 24b8842209SGerd Hoffmann */ 25baec1910SAndreas Färber #include "hw/hw.h" 26baec1910SAndreas Färber #include "hw/ppc/mac.h" 270d09e41aSPaolo Bonzini #include "hw/ppc/mac_dbdma.h" 28737e150eSPaolo Bonzini #include "block/block.h" 299c17d615SPaolo Bonzini #include "sysemu/dma.h" 3059f2a787SGerd Hoffmann 3159f2a787SGerd Hoffmann #include <hw/ide/internal.h> 32b8842209SGerd Hoffmann 33*33ce36bbSAlexander Graf /* debug MACIO */ 34*33ce36bbSAlexander Graf // #define DEBUG_MACIO 35*33ce36bbSAlexander Graf 36*33ce36bbSAlexander Graf #ifdef DEBUG_MACIO 37*33ce36bbSAlexander Graf static const int debug_macio = 1; 38*33ce36bbSAlexander Graf #else 39*33ce36bbSAlexander Graf static const int debug_macio = 0; 40*33ce36bbSAlexander Graf #endif 41*33ce36bbSAlexander Graf 42*33ce36bbSAlexander Graf #define MACIO_DPRINTF(fmt, ...) do { \ 43*33ce36bbSAlexander Graf if (debug_macio) { \ 44*33ce36bbSAlexander Graf printf(fmt , ## __VA_ARGS__); \ 45*33ce36bbSAlexander Graf } \ 46*33ce36bbSAlexander Graf } while (0) 47*33ce36bbSAlexander Graf 48*33ce36bbSAlexander Graf 49b8842209SGerd Hoffmann /***********************************************************/ 50b8842209SGerd Hoffmann /* MacIO based PowerPC IDE */ 51b8842209SGerd Hoffmann 5202c7c992SBlue Swirl #define MACIO_PAGE_SIZE 4096 5302c7c992SBlue Swirl 54b8842209SGerd Hoffmann static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) 55b8842209SGerd Hoffmann { 56b8842209SGerd Hoffmann DBDMA_io *io = opaque; 57b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 58b8842209SGerd Hoffmann IDEState *s = idebus_active_if(&m->bus); 59b8842209SGerd Hoffmann 60b8842209SGerd Hoffmann if (ret < 0) { 61b8842209SGerd Hoffmann m->aiocb = NULL; 62b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 63b8842209SGerd Hoffmann ide_atapi_io_error(s, ret); 64a597e79cSChristoph Hellwig goto done; 65b8842209SGerd Hoffmann } 66b8842209SGerd Hoffmann 67*33ce36bbSAlexander Graf MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 68*33ce36bbSAlexander Graf 69b8842209SGerd Hoffmann if (s->io_buffer_size > 0) { 70b8842209SGerd Hoffmann m->aiocb = NULL; 71b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 72b8842209SGerd Hoffmann 73b8842209SGerd Hoffmann s->packet_transfer_size -= s->io_buffer_size; 74b8842209SGerd Hoffmann 75b8842209SGerd Hoffmann s->io_buffer_index += s->io_buffer_size; 76b8842209SGerd Hoffmann s->lba += s->io_buffer_index >> 11; 77b8842209SGerd Hoffmann s->io_buffer_index &= 0x7ff; 78b8842209SGerd Hoffmann } 79b8842209SGerd Hoffmann 80*33ce36bbSAlexander Graf if (s->packet_transfer_size <= 0) { 81*33ce36bbSAlexander Graf MACIO_DPRINTF("end of transfer\n"); 82b8842209SGerd Hoffmann ide_atapi_cmd_ok(s); 83*33ce36bbSAlexander Graf } 84b8842209SGerd Hoffmann 85b8842209SGerd Hoffmann if (io->len == 0) { 86*33ce36bbSAlexander Graf MACIO_DPRINTF("end of DMA\n"); 87a597e79cSChristoph Hellwig goto done; 88b8842209SGerd Hoffmann } 89b8842209SGerd Hoffmann 90b8842209SGerd Hoffmann /* launch next transfer */ 91b8842209SGerd Hoffmann 92*33ce36bbSAlexander Graf MACIO_DPRINTF("io->len = %#x\n", io->len); 93*33ce36bbSAlexander Graf 94b8842209SGerd Hoffmann s->io_buffer_size = io->len; 95b8842209SGerd Hoffmann 96f487b677SPaolo Bonzini qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 97df32fd1cSPaolo Bonzini &address_space_memory); 98b8842209SGerd Hoffmann qemu_sglist_add(&s->sg, io->addr, io->len); 99b8842209SGerd Hoffmann io->addr += io->len; 100b8842209SGerd Hoffmann io->len = 0; 101b8842209SGerd Hoffmann 102*33ce36bbSAlexander Graf MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", 103*33ce36bbSAlexander Graf (s->lba << 2) + (s->io_buffer_index >> 9), 104*33ce36bbSAlexander Graf s->packet_transfer_size, s->dma_cmd); 105*33ce36bbSAlexander Graf 106b8842209SGerd Hoffmann m->aiocb = dma_bdrv_read(s->bs, &s->sg, 107b8842209SGerd Hoffmann (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), 108b8842209SGerd Hoffmann pmac_ide_atapi_transfer_cb, io); 109a597e79cSChristoph Hellwig return; 110a597e79cSChristoph Hellwig 111a597e79cSChristoph Hellwig done: 112*33ce36bbSAlexander Graf MACIO_DPRINTF("done DMA\n"); 113a597e79cSChristoph Hellwig bdrv_acct_done(s->bs, &s->acct); 114b8842209SGerd Hoffmann io->dma_end(opaque); 115b8842209SGerd Hoffmann } 116b8842209SGerd Hoffmann 117b8842209SGerd Hoffmann static void pmac_ide_transfer_cb(void *opaque, int ret) 118b8842209SGerd Hoffmann { 119b8842209SGerd Hoffmann DBDMA_io *io = opaque; 120b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 121b8842209SGerd Hoffmann IDEState *s = idebus_active_if(&m->bus); 122b8842209SGerd Hoffmann int n; 123b8842209SGerd Hoffmann int64_t sector_num; 124b8842209SGerd Hoffmann 125b8842209SGerd Hoffmann if (ret < 0) { 126*33ce36bbSAlexander Graf MACIO_DPRINTF("DMA error\n"); 127b8842209SGerd Hoffmann m->aiocb = NULL; 128b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 129b8842209SGerd Hoffmann ide_dma_error(s); 130a597e79cSChristoph Hellwig goto done; 131b8842209SGerd Hoffmann } 132b8842209SGerd Hoffmann 133b8842209SGerd Hoffmann sector_num = ide_get_sector(s); 134*33ce36bbSAlexander Graf MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 135b8842209SGerd Hoffmann if (s->io_buffer_size > 0) { 136b8842209SGerd Hoffmann m->aiocb = NULL; 137b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 138b8842209SGerd Hoffmann n = (s->io_buffer_size + 0x1ff) >> 9; 139b8842209SGerd Hoffmann sector_num += n; 140b8842209SGerd Hoffmann ide_set_sector(s, sector_num); 141b8842209SGerd Hoffmann s->nsector -= n; 142b8842209SGerd Hoffmann } 143b8842209SGerd Hoffmann 144b8842209SGerd Hoffmann if (s->nsector == 0) { 145*33ce36bbSAlexander Graf MACIO_DPRINTF("end of transfer\n"); 146b8842209SGerd Hoffmann s->status = READY_STAT | SEEK_STAT; 1479cdd03a7SGerd Hoffmann ide_set_irq(s->bus); 148b8842209SGerd Hoffmann } 149b8842209SGerd Hoffmann 150b8842209SGerd Hoffmann if (io->len == 0) { 151*33ce36bbSAlexander Graf MACIO_DPRINTF("end of DMA\n"); 152a597e79cSChristoph Hellwig goto done; 153b8842209SGerd Hoffmann } 154b8842209SGerd Hoffmann 155b8842209SGerd Hoffmann /* launch next transfer */ 156b8842209SGerd Hoffmann 157b8842209SGerd Hoffmann s->io_buffer_index = 0; 158b8842209SGerd Hoffmann s->io_buffer_size = io->len; 159b8842209SGerd Hoffmann 160*33ce36bbSAlexander Graf MACIO_DPRINTF("io->len = %#x\n", io->len); 161*33ce36bbSAlexander Graf 162f487b677SPaolo Bonzini qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 163df32fd1cSPaolo Bonzini &address_space_memory); 164b8842209SGerd Hoffmann qemu_sglist_add(&s->sg, io->addr, io->len); 165b8842209SGerd Hoffmann io->addr += io->len; 166b8842209SGerd Hoffmann io->len = 0; 167b8842209SGerd Hoffmann 168*33ce36bbSAlexander Graf MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n", 169*33ce36bbSAlexander Graf sector_num, n, s->nsector, s->dma_cmd); 170*33ce36bbSAlexander Graf 1714e1e0051SChristoph Hellwig switch (s->dma_cmd) { 1724e1e0051SChristoph Hellwig case IDE_DMA_READ: 173b8842209SGerd Hoffmann m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, 174b8842209SGerd Hoffmann pmac_ide_transfer_cb, io); 1754e1e0051SChristoph Hellwig break; 1764e1e0051SChristoph Hellwig case IDE_DMA_WRITE: 177b8842209SGerd Hoffmann m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, 178b8842209SGerd Hoffmann pmac_ide_transfer_cb, io); 1794e1e0051SChristoph Hellwig break; 180d353fb72SChristoph Hellwig case IDE_DMA_TRIM: 181d353fb72SChristoph Hellwig m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, 182b9b5df6fSAurelien Jarno ide_issue_trim, pmac_ide_transfer_cb, io, 18343cf8ae6SDavid Gibson DMA_DIRECTION_TO_DEVICE); 184d353fb72SChristoph Hellwig break; 1854e1e0051SChristoph Hellwig } 186a597e79cSChristoph Hellwig return; 187b9b2008bSPaolo Bonzini 188a597e79cSChristoph Hellwig done: 189a597e79cSChristoph Hellwig if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { 190a597e79cSChristoph Hellwig bdrv_acct_done(s->bs, &s->acct); 191a597e79cSChristoph Hellwig } 192a597e79cSChristoph Hellwig io->dma_end(io); 193b8842209SGerd Hoffmann } 194b8842209SGerd Hoffmann 195b8842209SGerd Hoffmann static void pmac_ide_transfer(DBDMA_io *io) 196b8842209SGerd Hoffmann { 197b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 198b8842209SGerd Hoffmann IDEState *s = idebus_active_if(&m->bus); 199b8842209SGerd Hoffmann 200*33ce36bbSAlexander Graf MACIO_DPRINTF("\n"); 201*33ce36bbSAlexander Graf 202b8842209SGerd Hoffmann s->io_buffer_size = 0; 203cd8722bbSMarkus Armbruster if (s->drive_kind == IDE_CD) { 204a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 205b8842209SGerd Hoffmann pmac_ide_atapi_transfer_cb(io, 0); 206b8842209SGerd Hoffmann return; 207b8842209SGerd Hoffmann } 208b8842209SGerd Hoffmann 209a597e79cSChristoph Hellwig switch (s->dma_cmd) { 210a597e79cSChristoph Hellwig case IDE_DMA_READ: 211a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 212a597e79cSChristoph Hellwig break; 213a597e79cSChristoph Hellwig case IDE_DMA_WRITE: 214a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); 215a597e79cSChristoph Hellwig break; 216a597e79cSChristoph Hellwig default: 217a597e79cSChristoph Hellwig break; 218a597e79cSChristoph Hellwig } 219a597e79cSChristoph Hellwig 220b8842209SGerd Hoffmann pmac_ide_transfer_cb(io, 0); 221b8842209SGerd Hoffmann } 222b8842209SGerd Hoffmann 223b8842209SGerd Hoffmann static void pmac_ide_flush(DBDMA_io *io) 224b8842209SGerd Hoffmann { 225b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 226b8842209SGerd Hoffmann 227922453bcSStefan Hajnoczi if (m->aiocb) { 228922453bcSStefan Hajnoczi bdrv_drain_all(); 229922453bcSStefan Hajnoczi } 230b8842209SGerd Hoffmann } 231b8842209SGerd Hoffmann 232b8842209SGerd Hoffmann /* PowerMac IDE memory IO */ 233b8842209SGerd Hoffmann static void pmac_ide_writeb (void *opaque, 234a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 235b8842209SGerd Hoffmann { 236b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 237b8842209SGerd Hoffmann 238b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 239b8842209SGerd Hoffmann switch (addr) { 240b8842209SGerd Hoffmann case 1 ... 7: 241b8842209SGerd Hoffmann ide_ioport_write(&d->bus, addr, val); 242b8842209SGerd Hoffmann break; 243b8842209SGerd Hoffmann case 8: 244b8842209SGerd Hoffmann case 22: 245b8842209SGerd Hoffmann ide_cmd_write(&d->bus, 0, val); 246b8842209SGerd Hoffmann break; 247b8842209SGerd Hoffmann default: 248b8842209SGerd Hoffmann break; 249b8842209SGerd Hoffmann } 250b8842209SGerd Hoffmann } 251b8842209SGerd Hoffmann 252a8170e5eSAvi Kivity static uint32_t pmac_ide_readb (void *opaque,hwaddr addr) 253b8842209SGerd Hoffmann { 254b8842209SGerd Hoffmann uint8_t retval; 255b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 256b8842209SGerd Hoffmann 257b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 258b8842209SGerd Hoffmann switch (addr) { 259b8842209SGerd Hoffmann case 1 ... 7: 260b8842209SGerd Hoffmann retval = ide_ioport_read(&d->bus, addr); 261b8842209SGerd Hoffmann break; 262b8842209SGerd Hoffmann case 8: 263b8842209SGerd Hoffmann case 22: 264b8842209SGerd Hoffmann retval = ide_status_read(&d->bus, 0); 265b8842209SGerd Hoffmann break; 266b8842209SGerd Hoffmann default: 267b8842209SGerd Hoffmann retval = 0xFF; 268b8842209SGerd Hoffmann break; 269b8842209SGerd Hoffmann } 270b8842209SGerd Hoffmann return retval; 271b8842209SGerd Hoffmann } 272b8842209SGerd Hoffmann 273b8842209SGerd Hoffmann static void pmac_ide_writew (void *opaque, 274a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 275b8842209SGerd Hoffmann { 276b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 277b8842209SGerd Hoffmann 278b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 279b8842209SGerd Hoffmann val = bswap16(val); 280b8842209SGerd Hoffmann if (addr == 0) { 281b8842209SGerd Hoffmann ide_data_writew(&d->bus, 0, val); 282b8842209SGerd Hoffmann } 283b8842209SGerd Hoffmann } 284b8842209SGerd Hoffmann 285a8170e5eSAvi Kivity static uint32_t pmac_ide_readw (void *opaque,hwaddr addr) 286b8842209SGerd Hoffmann { 287b8842209SGerd Hoffmann uint16_t retval; 288b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 289b8842209SGerd Hoffmann 290b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 291b8842209SGerd Hoffmann if (addr == 0) { 292b8842209SGerd Hoffmann retval = ide_data_readw(&d->bus, 0); 293b8842209SGerd Hoffmann } else { 294b8842209SGerd Hoffmann retval = 0xFFFF; 295b8842209SGerd Hoffmann } 296b8842209SGerd Hoffmann retval = bswap16(retval); 297b8842209SGerd Hoffmann return retval; 298b8842209SGerd Hoffmann } 299b8842209SGerd Hoffmann 300b8842209SGerd Hoffmann static void pmac_ide_writel (void *opaque, 301a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 302b8842209SGerd Hoffmann { 303b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 304b8842209SGerd Hoffmann 305b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 306b8842209SGerd Hoffmann val = bswap32(val); 307b8842209SGerd Hoffmann if (addr == 0) { 308b8842209SGerd Hoffmann ide_data_writel(&d->bus, 0, val); 309b8842209SGerd Hoffmann } 310b8842209SGerd Hoffmann } 311b8842209SGerd Hoffmann 312a8170e5eSAvi Kivity static uint32_t pmac_ide_readl (void *opaque,hwaddr addr) 313b8842209SGerd Hoffmann { 314b8842209SGerd Hoffmann uint32_t retval; 315b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 316b8842209SGerd Hoffmann 317b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 318b8842209SGerd Hoffmann if (addr == 0) { 319b8842209SGerd Hoffmann retval = ide_data_readl(&d->bus, 0); 320b8842209SGerd Hoffmann } else { 321b8842209SGerd Hoffmann retval = 0xFFFFFFFF; 322b8842209SGerd Hoffmann } 323b8842209SGerd Hoffmann retval = bswap32(retval); 324b8842209SGerd Hoffmann return retval; 325b8842209SGerd Hoffmann } 326b8842209SGerd Hoffmann 327a348f108SStefan Weil static const MemoryRegionOps pmac_ide_ops = { 32823c5e4caSAvi Kivity .old_mmio = { 32923c5e4caSAvi Kivity .write = { 330b8842209SGerd Hoffmann pmac_ide_writeb, 331b8842209SGerd Hoffmann pmac_ide_writew, 332b8842209SGerd Hoffmann pmac_ide_writel, 33323c5e4caSAvi Kivity }, 33423c5e4caSAvi Kivity .read = { 335b8842209SGerd Hoffmann pmac_ide_readb, 336b8842209SGerd Hoffmann pmac_ide_readw, 337b8842209SGerd Hoffmann pmac_ide_readl, 33823c5e4caSAvi Kivity }, 33923c5e4caSAvi Kivity }, 34023c5e4caSAvi Kivity .endianness = DEVICE_NATIVE_ENDIAN, 341b8842209SGerd Hoffmann }; 342b8842209SGerd Hoffmann 34344bfa332SJuan Quintela static const VMStateDescription vmstate_pmac = { 34444bfa332SJuan Quintela .name = "ide", 34544bfa332SJuan Quintela .version_id = 3, 34644bfa332SJuan Quintela .minimum_version_id = 0, 34744bfa332SJuan Quintela .minimum_version_id_old = 0, 34844bfa332SJuan Quintela .fields = (VMStateField []) { 34944bfa332SJuan Quintela VMSTATE_IDE_BUS(bus, MACIOIDEState), 35044bfa332SJuan Quintela VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState), 35144bfa332SJuan Quintela VMSTATE_END_OF_LIST() 352b8842209SGerd Hoffmann } 35344bfa332SJuan Quintela }; 354b8842209SGerd Hoffmann 35507a7484eSAndreas Färber static void macio_ide_reset(DeviceState *dev) 356b8842209SGerd Hoffmann { 35707a7484eSAndreas Färber MACIOIDEState *d = MACIO_IDE(dev); 358b8842209SGerd Hoffmann 3594a643563SBlue Swirl ide_bus_reset(&d->bus); 360b8842209SGerd Hoffmann } 361b8842209SGerd Hoffmann 36207a7484eSAndreas Färber static void macio_ide_realizefn(DeviceState *dev, Error **errp) 363b8842209SGerd Hoffmann { 36407a7484eSAndreas Färber MACIOIDEState *s = MACIO_IDE(dev); 365b8842209SGerd Hoffmann 36607a7484eSAndreas Färber ide_init2(&s->bus, s->irq); 367b8842209SGerd Hoffmann } 36807a7484eSAndreas Färber 36907a7484eSAndreas Färber static void macio_ide_initfn(Object *obj) 37007a7484eSAndreas Färber { 37107a7484eSAndreas Färber SysBusDevice *d = SYS_BUS_DEVICE(obj); 37207a7484eSAndreas Färber MACIOIDEState *s = MACIO_IDE(obj); 37307a7484eSAndreas Färber 3740ee20e66SKevin Wolf ide_bus_new(&s->bus, DEVICE(obj), 0, 2); 3751437c94bSPaolo Bonzini memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000); 37607a7484eSAndreas Färber sysbus_init_mmio(d, &s->mem); 37707a7484eSAndreas Färber sysbus_init_irq(d, &s->irq); 37807a7484eSAndreas Färber sysbus_init_irq(d, &s->dma_irq); 37907a7484eSAndreas Färber } 38007a7484eSAndreas Färber 38107a7484eSAndreas Färber static void macio_ide_class_init(ObjectClass *oc, void *data) 38207a7484eSAndreas Färber { 38307a7484eSAndreas Färber DeviceClass *dc = DEVICE_CLASS(oc); 38407a7484eSAndreas Färber 38507a7484eSAndreas Färber dc->realize = macio_ide_realizefn; 38607a7484eSAndreas Färber dc->reset = macio_ide_reset; 38707a7484eSAndreas Färber dc->vmsd = &vmstate_pmac; 38807a7484eSAndreas Färber } 38907a7484eSAndreas Färber 39007a7484eSAndreas Färber static const TypeInfo macio_ide_type_info = { 39107a7484eSAndreas Färber .name = TYPE_MACIO_IDE, 39207a7484eSAndreas Färber .parent = TYPE_SYS_BUS_DEVICE, 39307a7484eSAndreas Färber .instance_size = sizeof(MACIOIDEState), 39407a7484eSAndreas Färber .instance_init = macio_ide_initfn, 39507a7484eSAndreas Färber .class_init = macio_ide_class_init, 39607a7484eSAndreas Färber }; 39707a7484eSAndreas Färber 39807a7484eSAndreas Färber static void macio_ide_register_types(void) 39907a7484eSAndreas Färber { 40007a7484eSAndreas Färber type_register_static(&macio_ide_type_info); 40107a7484eSAndreas Färber } 40207a7484eSAndreas Färber 40314eefd0eSAlexander Graf /* hd_table must contain 2 block drivers */ 40407a7484eSAndreas Färber void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) 40507a7484eSAndreas Färber { 40607a7484eSAndreas Färber int i; 40707a7484eSAndreas Färber 40807a7484eSAndreas Färber for (i = 0; i < 2; i++) { 40907a7484eSAndreas Färber if (hd_table[i]) { 41007a7484eSAndreas Färber ide_create_drive(&s->bus, i, hd_table[i]); 41107a7484eSAndreas Färber } 41207a7484eSAndreas Färber } 41307a7484eSAndreas Färber } 41407a7484eSAndreas Färber 41507a7484eSAndreas Färber void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) 41607a7484eSAndreas Färber { 41707a7484eSAndreas Färber DBDMA_register_channel(dbdma, channel, s->dma_irq, 41807a7484eSAndreas Färber pmac_ide_transfer, pmac_ide_flush, s); 41907a7484eSAndreas Färber } 42007a7484eSAndreas Färber 42107a7484eSAndreas Färber type_init(macio_ide_register_types) 422