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 3333ce36bbSAlexander Graf /* debug MACIO */ 3433ce36bbSAlexander Graf // #define DEBUG_MACIO 3533ce36bbSAlexander Graf 3633ce36bbSAlexander Graf #ifdef DEBUG_MACIO 3733ce36bbSAlexander Graf static const int debug_macio = 1; 3833ce36bbSAlexander Graf #else 3933ce36bbSAlexander Graf static const int debug_macio = 0; 4033ce36bbSAlexander Graf #endif 4133ce36bbSAlexander Graf 4233ce36bbSAlexander Graf #define MACIO_DPRINTF(fmt, ...) do { \ 4333ce36bbSAlexander Graf if (debug_macio) { \ 4433ce36bbSAlexander Graf printf(fmt , ## __VA_ARGS__); \ 4533ce36bbSAlexander Graf } \ 4633ce36bbSAlexander Graf } while (0) 4733ce36bbSAlexander Graf 4833ce36bbSAlexander 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*cae32357SAlexander Graf if (!m->dma_active) { 68*cae32357SAlexander Graf MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", 69*cae32357SAlexander Graf s->nsector, io->len, s->status); 70*cae32357SAlexander Graf /* data not ready yet, wait for the channel to get restarted */ 71*cae32357SAlexander Graf io->processing = false; 72*cae32357SAlexander Graf return; 73*cae32357SAlexander Graf } 74*cae32357SAlexander Graf 7533ce36bbSAlexander Graf MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 7633ce36bbSAlexander Graf 77b8842209SGerd Hoffmann if (s->io_buffer_size > 0) { 78b8842209SGerd Hoffmann m->aiocb = NULL; 79b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 80b8842209SGerd Hoffmann 81b8842209SGerd Hoffmann s->packet_transfer_size -= s->io_buffer_size; 82b8842209SGerd Hoffmann 83b8842209SGerd Hoffmann s->io_buffer_index += s->io_buffer_size; 84b8842209SGerd Hoffmann s->lba += s->io_buffer_index >> 11; 85b8842209SGerd Hoffmann s->io_buffer_index &= 0x7ff; 86b8842209SGerd Hoffmann } 87b8842209SGerd Hoffmann 8833ce36bbSAlexander Graf if (s->packet_transfer_size <= 0) { 8933ce36bbSAlexander Graf MACIO_DPRINTF("end of transfer\n"); 90b8842209SGerd Hoffmann ide_atapi_cmd_ok(s); 91*cae32357SAlexander Graf m->dma_active = false; 9233ce36bbSAlexander Graf } 93b8842209SGerd Hoffmann 94b8842209SGerd Hoffmann if (io->len == 0) { 9533ce36bbSAlexander Graf MACIO_DPRINTF("end of DMA\n"); 96a597e79cSChristoph Hellwig goto done; 97b8842209SGerd Hoffmann } 98b8842209SGerd Hoffmann 99b8842209SGerd Hoffmann /* launch next transfer */ 100b8842209SGerd Hoffmann 10133ce36bbSAlexander Graf MACIO_DPRINTF("io->len = %#x\n", io->len); 10233ce36bbSAlexander Graf 103b8842209SGerd Hoffmann s->io_buffer_size = io->len; 104b8842209SGerd Hoffmann 105f487b677SPaolo Bonzini qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 106df32fd1cSPaolo Bonzini &address_space_memory); 107b8842209SGerd Hoffmann qemu_sglist_add(&s->sg, io->addr, io->len); 108b8842209SGerd Hoffmann io->addr += io->len; 109b8842209SGerd Hoffmann io->len = 0; 110b8842209SGerd Hoffmann 11133ce36bbSAlexander Graf MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", 11233ce36bbSAlexander Graf (s->lba << 2) + (s->io_buffer_index >> 9), 11333ce36bbSAlexander Graf s->packet_transfer_size, s->dma_cmd); 11433ce36bbSAlexander Graf 115b8842209SGerd Hoffmann m->aiocb = dma_bdrv_read(s->bs, &s->sg, 116b8842209SGerd Hoffmann (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), 117b8842209SGerd Hoffmann pmac_ide_atapi_transfer_cb, io); 118a597e79cSChristoph Hellwig return; 119a597e79cSChristoph Hellwig 120a597e79cSChristoph Hellwig done: 12133ce36bbSAlexander Graf MACIO_DPRINTF("done DMA\n"); 122a597e79cSChristoph Hellwig bdrv_acct_done(s->bs, &s->acct); 123b8842209SGerd Hoffmann io->dma_end(opaque); 124b8842209SGerd Hoffmann } 125b8842209SGerd Hoffmann 126b8842209SGerd Hoffmann static void pmac_ide_transfer_cb(void *opaque, int ret) 127b8842209SGerd Hoffmann { 128b8842209SGerd Hoffmann DBDMA_io *io = opaque; 129b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 130b8842209SGerd Hoffmann IDEState *s = idebus_active_if(&m->bus); 131b8842209SGerd Hoffmann int n; 132b8842209SGerd Hoffmann int64_t sector_num; 133b8842209SGerd Hoffmann 134b8842209SGerd Hoffmann if (ret < 0) { 13533ce36bbSAlexander Graf MACIO_DPRINTF("DMA error\n"); 136b8842209SGerd Hoffmann m->aiocb = NULL; 137b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 138b8842209SGerd Hoffmann ide_dma_error(s); 139a597e79cSChristoph Hellwig goto done; 140b8842209SGerd Hoffmann } 141b8842209SGerd Hoffmann 142*cae32357SAlexander Graf if (!m->dma_active) { 143*cae32357SAlexander Graf MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", 144*cae32357SAlexander Graf s->nsector, io->len, s->status); 145*cae32357SAlexander Graf /* data not ready yet, wait for the channel to get restarted */ 146*cae32357SAlexander Graf io->processing = false; 147*cae32357SAlexander Graf return; 148*cae32357SAlexander Graf } 149*cae32357SAlexander Graf 150b8842209SGerd Hoffmann sector_num = ide_get_sector(s); 15133ce36bbSAlexander Graf MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 152b8842209SGerd Hoffmann if (s->io_buffer_size > 0) { 153b8842209SGerd Hoffmann m->aiocb = NULL; 154b8842209SGerd Hoffmann qemu_sglist_destroy(&s->sg); 155b8842209SGerd Hoffmann n = (s->io_buffer_size + 0x1ff) >> 9; 156b8842209SGerd Hoffmann sector_num += n; 157b8842209SGerd Hoffmann ide_set_sector(s, sector_num); 158b8842209SGerd Hoffmann s->nsector -= n; 159b8842209SGerd Hoffmann } 160b8842209SGerd Hoffmann 161b8842209SGerd Hoffmann if (s->nsector == 0) { 16233ce36bbSAlexander Graf MACIO_DPRINTF("end of transfer\n"); 163b8842209SGerd Hoffmann s->status = READY_STAT | SEEK_STAT; 1649cdd03a7SGerd Hoffmann ide_set_irq(s->bus); 165*cae32357SAlexander Graf m->dma_active = false; 166b8842209SGerd Hoffmann } 167b8842209SGerd Hoffmann 168b8842209SGerd Hoffmann if (io->len == 0) { 16933ce36bbSAlexander Graf MACIO_DPRINTF("end of DMA\n"); 170a597e79cSChristoph Hellwig goto done; 171b8842209SGerd Hoffmann } 172b8842209SGerd Hoffmann 173b8842209SGerd Hoffmann /* launch next transfer */ 174b8842209SGerd Hoffmann 175b8842209SGerd Hoffmann s->io_buffer_index = 0; 176b8842209SGerd Hoffmann s->io_buffer_size = io->len; 177b8842209SGerd Hoffmann 17833ce36bbSAlexander Graf MACIO_DPRINTF("io->len = %#x\n", io->len); 17933ce36bbSAlexander Graf 180f487b677SPaolo Bonzini qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 181df32fd1cSPaolo Bonzini &address_space_memory); 182b8842209SGerd Hoffmann qemu_sglist_add(&s->sg, io->addr, io->len); 183b8842209SGerd Hoffmann io->addr += io->len; 184b8842209SGerd Hoffmann io->len = 0; 185b8842209SGerd Hoffmann 18633ce36bbSAlexander Graf MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n", 18733ce36bbSAlexander Graf sector_num, n, s->nsector, s->dma_cmd); 18833ce36bbSAlexander Graf 1894e1e0051SChristoph Hellwig switch (s->dma_cmd) { 1904e1e0051SChristoph Hellwig case IDE_DMA_READ: 191b8842209SGerd Hoffmann m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, 192b8842209SGerd Hoffmann pmac_ide_transfer_cb, io); 1934e1e0051SChristoph Hellwig break; 1944e1e0051SChristoph Hellwig case IDE_DMA_WRITE: 195b8842209SGerd Hoffmann m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, 196b8842209SGerd Hoffmann pmac_ide_transfer_cb, io); 1974e1e0051SChristoph Hellwig break; 198d353fb72SChristoph Hellwig case IDE_DMA_TRIM: 199d353fb72SChristoph Hellwig m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, 200b9b5df6fSAurelien Jarno ide_issue_trim, pmac_ide_transfer_cb, io, 20143cf8ae6SDavid Gibson DMA_DIRECTION_TO_DEVICE); 202d353fb72SChristoph Hellwig break; 2034e1e0051SChristoph Hellwig } 204a597e79cSChristoph Hellwig return; 205b9b2008bSPaolo Bonzini 206a597e79cSChristoph Hellwig done: 207a597e79cSChristoph Hellwig if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { 208a597e79cSChristoph Hellwig bdrv_acct_done(s->bs, &s->acct); 209a597e79cSChristoph Hellwig } 210a597e79cSChristoph Hellwig io->dma_end(io); 211b8842209SGerd Hoffmann } 212b8842209SGerd Hoffmann 213b8842209SGerd Hoffmann static void pmac_ide_transfer(DBDMA_io *io) 214b8842209SGerd Hoffmann { 215b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 216b8842209SGerd Hoffmann IDEState *s = idebus_active_if(&m->bus); 217b8842209SGerd Hoffmann 21833ce36bbSAlexander Graf MACIO_DPRINTF("\n"); 21933ce36bbSAlexander Graf 220b8842209SGerd Hoffmann s->io_buffer_size = 0; 221cd8722bbSMarkus Armbruster if (s->drive_kind == IDE_CD) { 222a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 223b8842209SGerd Hoffmann pmac_ide_atapi_transfer_cb(io, 0); 224b8842209SGerd Hoffmann return; 225b8842209SGerd Hoffmann } 226b8842209SGerd Hoffmann 227a597e79cSChristoph Hellwig switch (s->dma_cmd) { 228a597e79cSChristoph Hellwig case IDE_DMA_READ: 229a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 230a597e79cSChristoph Hellwig break; 231a597e79cSChristoph Hellwig case IDE_DMA_WRITE: 232a597e79cSChristoph Hellwig bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); 233a597e79cSChristoph Hellwig break; 234a597e79cSChristoph Hellwig default: 235a597e79cSChristoph Hellwig break; 236a597e79cSChristoph Hellwig } 237a597e79cSChristoph Hellwig 238b8842209SGerd Hoffmann pmac_ide_transfer_cb(io, 0); 239b8842209SGerd Hoffmann } 240b8842209SGerd Hoffmann 241b8842209SGerd Hoffmann static void pmac_ide_flush(DBDMA_io *io) 242b8842209SGerd Hoffmann { 243b8842209SGerd Hoffmann MACIOIDEState *m = io->opaque; 244b8842209SGerd Hoffmann 245922453bcSStefan Hajnoczi if (m->aiocb) { 246922453bcSStefan Hajnoczi bdrv_drain_all(); 247922453bcSStefan Hajnoczi } 248b8842209SGerd Hoffmann } 249b8842209SGerd Hoffmann 250b8842209SGerd Hoffmann /* PowerMac IDE memory IO */ 251b8842209SGerd Hoffmann static void pmac_ide_writeb (void *opaque, 252a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 253b8842209SGerd Hoffmann { 254b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 255b8842209SGerd Hoffmann 256b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 257b8842209SGerd Hoffmann switch (addr) { 258b8842209SGerd Hoffmann case 1 ... 7: 259b8842209SGerd Hoffmann ide_ioport_write(&d->bus, addr, val); 260b8842209SGerd Hoffmann break; 261b8842209SGerd Hoffmann case 8: 262b8842209SGerd Hoffmann case 22: 263b8842209SGerd Hoffmann ide_cmd_write(&d->bus, 0, val); 264b8842209SGerd Hoffmann break; 265b8842209SGerd Hoffmann default: 266b8842209SGerd Hoffmann break; 267b8842209SGerd Hoffmann } 268b8842209SGerd Hoffmann } 269b8842209SGerd Hoffmann 270a8170e5eSAvi Kivity static uint32_t pmac_ide_readb (void *opaque,hwaddr addr) 271b8842209SGerd Hoffmann { 272b8842209SGerd Hoffmann uint8_t retval; 273b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 274b8842209SGerd Hoffmann 275b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 276b8842209SGerd Hoffmann switch (addr) { 277b8842209SGerd Hoffmann case 1 ... 7: 278b8842209SGerd Hoffmann retval = ide_ioport_read(&d->bus, addr); 279b8842209SGerd Hoffmann break; 280b8842209SGerd Hoffmann case 8: 281b8842209SGerd Hoffmann case 22: 282b8842209SGerd Hoffmann retval = ide_status_read(&d->bus, 0); 283b8842209SGerd Hoffmann break; 284b8842209SGerd Hoffmann default: 285b8842209SGerd Hoffmann retval = 0xFF; 286b8842209SGerd Hoffmann break; 287b8842209SGerd Hoffmann } 288b8842209SGerd Hoffmann return retval; 289b8842209SGerd Hoffmann } 290b8842209SGerd Hoffmann 291b8842209SGerd Hoffmann static void pmac_ide_writew (void *opaque, 292a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 293b8842209SGerd Hoffmann { 294b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 295b8842209SGerd Hoffmann 296b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 297b8842209SGerd Hoffmann val = bswap16(val); 298b8842209SGerd Hoffmann if (addr == 0) { 299b8842209SGerd Hoffmann ide_data_writew(&d->bus, 0, val); 300b8842209SGerd Hoffmann } 301b8842209SGerd Hoffmann } 302b8842209SGerd Hoffmann 303a8170e5eSAvi Kivity static uint32_t pmac_ide_readw (void *opaque,hwaddr addr) 304b8842209SGerd Hoffmann { 305b8842209SGerd Hoffmann uint16_t retval; 306b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 307b8842209SGerd Hoffmann 308b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 309b8842209SGerd Hoffmann if (addr == 0) { 310b8842209SGerd Hoffmann retval = ide_data_readw(&d->bus, 0); 311b8842209SGerd Hoffmann } else { 312b8842209SGerd Hoffmann retval = 0xFFFF; 313b8842209SGerd Hoffmann } 314b8842209SGerd Hoffmann retval = bswap16(retval); 315b8842209SGerd Hoffmann return retval; 316b8842209SGerd Hoffmann } 317b8842209SGerd Hoffmann 318b8842209SGerd Hoffmann static void pmac_ide_writel (void *opaque, 319a8170e5eSAvi Kivity hwaddr addr, uint32_t val) 320b8842209SGerd Hoffmann { 321b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 322b8842209SGerd Hoffmann 323b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 324b8842209SGerd Hoffmann val = bswap32(val); 325b8842209SGerd Hoffmann if (addr == 0) { 326b8842209SGerd Hoffmann ide_data_writel(&d->bus, 0, val); 327b8842209SGerd Hoffmann } 328b8842209SGerd Hoffmann } 329b8842209SGerd Hoffmann 330a8170e5eSAvi Kivity static uint32_t pmac_ide_readl (void *opaque,hwaddr addr) 331b8842209SGerd Hoffmann { 332b8842209SGerd Hoffmann uint32_t retval; 333b8842209SGerd Hoffmann MACIOIDEState *d = opaque; 334b8842209SGerd Hoffmann 335b8842209SGerd Hoffmann addr = (addr & 0xFFF) >> 4; 336b8842209SGerd Hoffmann if (addr == 0) { 337b8842209SGerd Hoffmann retval = ide_data_readl(&d->bus, 0); 338b8842209SGerd Hoffmann } else { 339b8842209SGerd Hoffmann retval = 0xFFFFFFFF; 340b8842209SGerd Hoffmann } 341b8842209SGerd Hoffmann retval = bswap32(retval); 342b8842209SGerd Hoffmann return retval; 343b8842209SGerd Hoffmann } 344b8842209SGerd Hoffmann 345a348f108SStefan Weil static const MemoryRegionOps pmac_ide_ops = { 34623c5e4caSAvi Kivity .old_mmio = { 34723c5e4caSAvi Kivity .write = { 348b8842209SGerd Hoffmann pmac_ide_writeb, 349b8842209SGerd Hoffmann pmac_ide_writew, 350b8842209SGerd Hoffmann pmac_ide_writel, 35123c5e4caSAvi Kivity }, 35223c5e4caSAvi Kivity .read = { 353b8842209SGerd Hoffmann pmac_ide_readb, 354b8842209SGerd Hoffmann pmac_ide_readw, 355b8842209SGerd Hoffmann pmac_ide_readl, 35623c5e4caSAvi Kivity }, 35723c5e4caSAvi Kivity }, 35823c5e4caSAvi Kivity .endianness = DEVICE_NATIVE_ENDIAN, 359b8842209SGerd Hoffmann }; 360b8842209SGerd Hoffmann 36144bfa332SJuan Quintela static const VMStateDescription vmstate_pmac = { 36244bfa332SJuan Quintela .name = "ide", 36344bfa332SJuan Quintela .version_id = 3, 36444bfa332SJuan Quintela .minimum_version_id = 0, 36544bfa332SJuan Quintela .minimum_version_id_old = 0, 36644bfa332SJuan Quintela .fields = (VMStateField []) { 36744bfa332SJuan Quintela VMSTATE_IDE_BUS(bus, MACIOIDEState), 36844bfa332SJuan Quintela VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState), 36944bfa332SJuan Quintela VMSTATE_END_OF_LIST() 370b8842209SGerd Hoffmann } 37144bfa332SJuan Quintela }; 372b8842209SGerd Hoffmann 37307a7484eSAndreas Färber static void macio_ide_reset(DeviceState *dev) 374b8842209SGerd Hoffmann { 37507a7484eSAndreas Färber MACIOIDEState *d = MACIO_IDE(dev); 376b8842209SGerd Hoffmann 3774a643563SBlue Swirl ide_bus_reset(&d->bus); 378b8842209SGerd Hoffmann } 379b8842209SGerd Hoffmann 3804aa3510fSAlexander Graf static int ide_nop(IDEDMA *dma) 3814aa3510fSAlexander Graf { 3824aa3510fSAlexander Graf return 0; 3834aa3510fSAlexander Graf } 3844aa3510fSAlexander Graf 3854aa3510fSAlexander Graf static int ide_nop_int(IDEDMA *dma, int x) 3864aa3510fSAlexander Graf { 3874aa3510fSAlexander Graf return 0; 3884aa3510fSAlexander Graf } 3894aa3510fSAlexander Graf 3904aa3510fSAlexander Graf static void ide_nop_restart(void *opaque, int x, RunState y) 3914aa3510fSAlexander Graf { 3924aa3510fSAlexander Graf } 3934aa3510fSAlexander Graf 3944aa3510fSAlexander Graf static void ide_dbdma_start(IDEDMA *dma, IDEState *s, 3954aa3510fSAlexander Graf BlockDriverCompletionFunc *cb) 3964aa3510fSAlexander Graf { 3974aa3510fSAlexander Graf MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); 3984aa3510fSAlexander Graf 3994aa3510fSAlexander Graf MACIO_DPRINTF("\n"); 400*cae32357SAlexander Graf m->dma_active = true; 4014aa3510fSAlexander Graf DBDMA_kick(m->dbdma); 4024aa3510fSAlexander Graf } 4034aa3510fSAlexander Graf 4044aa3510fSAlexander Graf static const IDEDMAOps dbdma_ops = { 4054aa3510fSAlexander Graf .start_dma = ide_dbdma_start, 4064aa3510fSAlexander Graf .start_transfer = ide_nop, 4074aa3510fSAlexander Graf .prepare_buf = ide_nop_int, 4084aa3510fSAlexander Graf .rw_buf = ide_nop_int, 4094aa3510fSAlexander Graf .set_unit = ide_nop_int, 4104aa3510fSAlexander Graf .add_status = ide_nop_int, 4114aa3510fSAlexander Graf .set_inactive = ide_nop, 4124aa3510fSAlexander Graf .restart_cb = ide_nop_restart, 4134aa3510fSAlexander Graf .reset = ide_nop, 4144aa3510fSAlexander Graf }; 4154aa3510fSAlexander Graf 41607a7484eSAndreas Färber static void macio_ide_realizefn(DeviceState *dev, Error **errp) 417b8842209SGerd Hoffmann { 41807a7484eSAndreas Färber MACIOIDEState *s = MACIO_IDE(dev); 419b8842209SGerd Hoffmann 42007a7484eSAndreas Färber ide_init2(&s->bus, s->irq); 4214aa3510fSAlexander Graf 4224aa3510fSAlexander Graf /* Register DMA callbacks */ 4234aa3510fSAlexander Graf s->dma.ops = &dbdma_ops; 4244aa3510fSAlexander Graf s->bus.dma = &s->dma; 425b8842209SGerd Hoffmann } 42607a7484eSAndreas Färber 42707a7484eSAndreas Färber static void macio_ide_initfn(Object *obj) 42807a7484eSAndreas Färber { 42907a7484eSAndreas Färber SysBusDevice *d = SYS_BUS_DEVICE(obj); 43007a7484eSAndreas Färber MACIOIDEState *s = MACIO_IDE(obj); 43107a7484eSAndreas Färber 4320ee20e66SKevin Wolf ide_bus_new(&s->bus, DEVICE(obj), 0, 2); 4331437c94bSPaolo Bonzini memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000); 43407a7484eSAndreas Färber sysbus_init_mmio(d, &s->mem); 43507a7484eSAndreas Färber sysbus_init_irq(d, &s->irq); 43607a7484eSAndreas Färber sysbus_init_irq(d, &s->dma_irq); 43707a7484eSAndreas Färber } 43807a7484eSAndreas Färber 43907a7484eSAndreas Färber static void macio_ide_class_init(ObjectClass *oc, void *data) 44007a7484eSAndreas Färber { 44107a7484eSAndreas Färber DeviceClass *dc = DEVICE_CLASS(oc); 44207a7484eSAndreas Färber 44307a7484eSAndreas Färber dc->realize = macio_ide_realizefn; 44407a7484eSAndreas Färber dc->reset = macio_ide_reset; 44507a7484eSAndreas Färber dc->vmsd = &vmstate_pmac; 44607a7484eSAndreas Färber } 44707a7484eSAndreas Färber 44807a7484eSAndreas Färber static const TypeInfo macio_ide_type_info = { 44907a7484eSAndreas Färber .name = TYPE_MACIO_IDE, 45007a7484eSAndreas Färber .parent = TYPE_SYS_BUS_DEVICE, 45107a7484eSAndreas Färber .instance_size = sizeof(MACIOIDEState), 45207a7484eSAndreas Färber .instance_init = macio_ide_initfn, 45307a7484eSAndreas Färber .class_init = macio_ide_class_init, 45407a7484eSAndreas Färber }; 45507a7484eSAndreas Färber 45607a7484eSAndreas Färber static void macio_ide_register_types(void) 45707a7484eSAndreas Färber { 45807a7484eSAndreas Färber type_register_static(&macio_ide_type_info); 45907a7484eSAndreas Färber } 46007a7484eSAndreas Färber 46114eefd0eSAlexander Graf /* hd_table must contain 2 block drivers */ 46207a7484eSAndreas Färber void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) 46307a7484eSAndreas Färber { 46407a7484eSAndreas Färber int i; 46507a7484eSAndreas Färber 46607a7484eSAndreas Färber for (i = 0; i < 2; i++) { 46707a7484eSAndreas Färber if (hd_table[i]) { 46807a7484eSAndreas Färber ide_create_drive(&s->bus, i, hd_table[i]); 46907a7484eSAndreas Färber } 47007a7484eSAndreas Färber } 47107a7484eSAndreas Färber } 47207a7484eSAndreas Färber 47307a7484eSAndreas Färber void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) 47407a7484eSAndreas Färber { 4754aa3510fSAlexander Graf s->dbdma = dbdma; 47607a7484eSAndreas Färber DBDMA_register_channel(dbdma, channel, s->dma_irq, 47707a7484eSAndreas Färber pmac_ide_transfer, pmac_ide_flush, s); 47807a7484eSAndreas Färber } 47907a7484eSAndreas Färber 48007a7484eSAndreas Färber type_init(macio_ide_register_types) 481