xref: /qemu/hw/ide/macio.c (revision 33ce36bb33cc00ac3070d49e17b4afed62b412a8)
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