]> Git Repo - qemu.git/blame - hw/ide/macio.c
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
[qemu.git] / hw / ide / macio.c
CommitLineData
b8842209
GH
1/*
2 * QEMU IDE Emulation: MacIO support.
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2006 Openedhand Ltd.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
baec1910
AF
25#include "hw/hw.h"
26#include "hw/ppc/mac.h"
0d09e41a 27#include "hw/ppc/mac_dbdma.h"
4be74634 28#include "sysemu/block-backend.h"
9c17d615 29#include "sysemu/dma.h"
59f2a787
GH
30
31#include <hw/ide/internal.h>
b8842209 32
33ce36bb
AG
33/* debug MACIO */
34// #define DEBUG_MACIO
35
36#ifdef DEBUG_MACIO
37static const int debug_macio = 1;
38#else
39static const int debug_macio = 0;
40#endif
41
42#define MACIO_DPRINTF(fmt, ...) do { \
43 if (debug_macio) { \
44 printf(fmt , ## __VA_ARGS__); \
45 } \
46 } while (0)
47
48
b8842209
GH
49/***********************************************************/
50/* MacIO based PowerPC IDE */
51
02c7c992
BS
52#define MACIO_PAGE_SIZE 4096
53
4827ac1e
MCA
54static void pmac_dma_read(BlockBackend *blk,
55 int64_t sector_num, int nb_sectors,
56 void (*cb)(void *opaque, int ret), void *opaque)
b8842209
GH
57{
58 DBDMA_io *io = opaque;
59 MACIOIDEState *m = io->opaque;
60 IDEState *s = idebus_active_if(&m->bus);
4827ac1e
MCA
61 dma_addr_t dma_addr, dma_len;
62 void *mem;
63 int nsector, remainder;
b8842209 64
4827ac1e
MCA
65 qemu_iovec_destroy(&io->iov);
66 qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
67
68 if (io->remainder_len > 0) {
69 /* Return remainder of request */
70 int transfer = MIN(io->remainder_len, io->len);
71
72 MACIO_DPRINTF("--- DMA read pop - bounce addr: %p addr: %"
73 HWADDR_PRIx " remainder_len: %x\n",
74 &io->remainder + (0x200 - transfer), io->addr,
75 io->remainder_len);
76
77 cpu_physical_memory_write(io->addr,
78 &io->remainder + (0x200 - transfer),
79 transfer);
80
81 io->remainder_len -= transfer;
82 io->len -= transfer;
83 io->addr += transfer;
84
85 s->io_buffer_index += transfer;
86 s->io_buffer_size -= transfer;
87
88 if (io->remainder_len != 0) {
89 /* Still waiting for remainder */
90 return;
91 }
92
93 if (io->len == 0) {
94 MACIO_DPRINTF("--- finished all read processing; go and finish\n");
95 cb(opaque, 0);
96 return;
97 }
b8842209
GH
98 }
99
4827ac1e
MCA
100 if (s->drive_kind == IDE_CD) {
101 sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
102 } else {
103 sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
cae32357
AG
104 }
105
4827ac1e
MCA
106 nsector = ((io->len + 0x1ff) >> 9);
107 remainder = (nsector << 9) - io->len;
33ce36bb 108
4827ac1e
MCA
109 MACIO_DPRINTF("--- DMA read transfer - addr: %" HWADDR_PRIx " len: %x\n",
110 io->addr, io->len);
111
112 dma_addr = io->addr;
113 dma_len = io->len;
114 mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
115 DMA_DIRECTION_FROM_DEVICE);
116
117 if (!remainder) {
118 MACIO_DPRINTF("--- DMA read aligned - addr: %" HWADDR_PRIx
119 " len: %x\n", io->addr, io->len);
120 qemu_iovec_add(&io->iov, mem, io->len);
121 } else {
122 MACIO_DPRINTF("--- DMA read unaligned - addr: %" HWADDR_PRIx
123 " len: %x\n", io->addr, io->len);
124 qemu_iovec_add(&io->iov, mem, io->len);
b8842209 125
4827ac1e
MCA
126 MACIO_DPRINTF("--- DMA read push - bounce addr: %p "
127 "remainder_len: %x\n",
128 &io->remainder + 0x200 - remainder, remainder);
129 qemu_iovec_add(&io->iov, &io->remainder + 0x200 - remainder,
130 remainder);
b8842209 131
4827ac1e 132 io->remainder_len = remainder;
b8842209
GH
133 }
134
4827ac1e
MCA
135 s->io_buffer_size -= io->len;
136 s->io_buffer_index += io->len;
80fc95d8 137
4827ac1e 138 io->len = 0;
80fc95d8 139
4827ac1e
MCA
140 MACIO_DPRINTF("--- Block read transfer - sector_num: %"PRIx64" "
141 "nsector: %x\n",
142 sector_num, nsector);
80fc95d8 143
4827ac1e
MCA
144 m->aiocb = blk_aio_readv(blk, sector_num, &io->iov, nsector, cb, io);
145}
80fc95d8 146
bd4214fc
MCA
147static void pmac_dma_write(BlockBackend *blk,
148 int64_t sector_num, int nb_sectors,
149 void (*cb)(void *opaque, int ret), void *opaque)
150{
151 DBDMA_io *io = opaque;
152 MACIOIDEState *m = io->opaque;
153 IDEState *s = idebus_active_if(&m->bus);
154 dma_addr_t dma_addr, dma_len;
155 void *mem;
156 int nsector, remainder;
157 int extra = 0;
158
159 qemu_iovec_destroy(&io->iov);
160 qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
161
162 if (io->remainder_len > 0) {
163 /* Return remainder of request */
164 int transfer = MIN(io->remainder_len, io->len);
165
166 MACIO_DPRINTF("--- processing write remainder %x\n", transfer);
167 cpu_physical_memory_read(io->addr,
168 &io->remainder + (0x200 - transfer),
169 transfer);
170
171 io->remainder_len -= transfer;
172 io->len -= transfer;
173 io->addr += transfer;
174
175 s->io_buffer_index += transfer;
176 s->io_buffer_size -= transfer;
177
178 if (io->remainder_len != 0) {
179 /* Still waiting for remainder */
180 return;
181 }
182
183 MACIO_DPRINTF("--> prepending bounce buffer with size 0x200\n");
184
185 /* Sector transfer complete - prepend to request */
186 qemu_iovec_add(&io->iov, &io->remainder, 0x200);
187 extra = 1;
188 }
189
190 if (s->drive_kind == IDE_CD) {
191 sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
192 } else {
193 sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
194 }
195
196 nsector = (io->len >> 9);
197 remainder = io->len - (nsector << 9);
198
199 MACIO_DPRINTF("--- DMA write transfer - addr: %" HWADDR_PRIx " len: %x\n",
200 io->addr, io->len);
201 MACIO_DPRINTF("xxx remainder: %x\n", remainder);
202 MACIO_DPRINTF("xxx sector_num: %"PRIx64" nsector: %x\n",
203 sector_num, nsector);
204
205 dma_addr = io->addr;
206 dma_len = io->len;
207 mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
208 DMA_DIRECTION_TO_DEVICE);
209
210 if (!remainder) {
211 MACIO_DPRINTF("--- DMA write aligned - addr: %" HWADDR_PRIx
212 " len: %x\n", io->addr, io->len);
213 qemu_iovec_add(&io->iov, mem, io->len);
214 } else {
215 /* Write up to last complete sector */
216 MACIO_DPRINTF("--- DMA write unaligned - addr: %" HWADDR_PRIx
217 " len: %x\n", io->addr, (nsector << 9));
218 qemu_iovec_add(&io->iov, mem, (nsector << 9));
219
220 MACIO_DPRINTF("--- DMA write read - bounce addr: %p "
221 "remainder_len: %x\n", &io->remainder, remainder);
222 cpu_physical_memory_read(io->addr + (nsector << 9), &io->remainder,
223 remainder);
224
225 io->remainder_len = 0x200 - remainder;
226
227 MACIO_DPRINTF("xxx remainder_len: %x\n", io->remainder_len);
228 }
229
230 s->io_buffer_size -= ((nsector + extra) << 9);
231 s->io_buffer_index += ((nsector + extra) << 9);
232
233 io->len = 0;
234
235 MACIO_DPRINTF("--- Block write transfer - sector_num: %"PRIx64" "
236 "nsector: %x\n", sector_num, nsector + extra);
237
238 m->aiocb = blk_aio_writev(blk, sector_num, &io->iov, nsector + extra, cb,
239 io);
240}
241
4827ac1e
MCA
242static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
243{
244 DBDMA_io *io = opaque;
245 MACIOIDEState *m = io->opaque;
246 IDEState *s = idebus_active_if(&m->bus);
247 int64_t sector_num;
248 int nsector, remainder;
249
250 MACIO_DPRINTF("\ns is %p\n", s);
251 MACIO_DPRINTF("io_buffer_index: %x\n", s->io_buffer_index);
252 MACIO_DPRINTF("io_buffer_size: %x packet_transfer_size: %x\n",
253 s->io_buffer_size, s->packet_transfer_size);
254 MACIO_DPRINTF("lba: %x\n", s->lba);
255 MACIO_DPRINTF("io_addr: %" HWADDR_PRIx " io_len: %x\n", io->addr,
256 io->len);
257
258 if (ret < 0) {
259 MACIO_DPRINTF("THERE WAS AN ERROR! %d\n", ret);
260 ide_atapi_io_error(s, ret);
261 goto done;
262 }
263
264 if (!m->dma_active) {
265 MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
266 s->nsector, io->len, s->status);
267 /* data not ready yet, wait for the channel to get restarted */
268 io->processing = false;
80fc95d8
AG
269 return;
270 }
271
4827ac1e 272 if (s->io_buffer_size <= 0) {
b8842209 273 ide_atapi_cmd_ok(s);
cae32357 274 m->dma_active = false;
4827ac1e 275 goto done;
33ce36bb 276 }
b8842209
GH
277
278 if (io->len == 0) {
4827ac1e 279 MACIO_DPRINTF("End of DMA transfer\n");
a597e79c 280 goto done;
b8842209
GH
281 }
282
4827ac1e
MCA
283 if (s->lba == -1) {
284 /* Non-block ATAPI transfer - just copy to RAM */
285 s->io_buffer_size = MIN(s->io_buffer_size, io->len);
286 cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size);
287 ide_atapi_cmd_ok(s);
288 m->dma_active = false;
289 goto done;
80fc95d8
AG
290 }
291
4827ac1e
MCA
292 /* Calculate number of sectors */
293 sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
294 nsector = (io->len + 0x1ff) >> 9;
295 remainder = io->len & 0x1ff;
b8842209 296
4827ac1e
MCA
297 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder);
298 MACIO_DPRINTF("sector: %"PRIx64" %zx\n", sector_num, io->iov.size / 512);
33ce36bb 299
4827ac1e 300 pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_atapi_transfer_cb, io);
a597e79c
CH
301 return;
302
303done:
4827ac1e 304 MACIO_DPRINTF("done DMA\n\n");
4be74634 305 block_acct_done(blk_get_stats(s->blk), &s->acct);
a597e79c 306 io->dma_end(opaque);
4827ac1e
MCA
307
308 return;
b8842209
GH
309}
310
311static void pmac_ide_transfer_cb(void *opaque, int ret)
312{
313 DBDMA_io *io = opaque;
314 MACIOIDEState *m = io->opaque;
315 IDEState *s = idebus_active_if(&m->bus);
b8842209 316 int64_t sector_num;
bd4214fc
MCA
317 int nsector, remainder;
318
319 MACIO_DPRINTF("pmac_ide_transfer_cb\n");
b8842209
GH
320
321 if (ret < 0) {
33ce36bb 322 MACIO_DPRINTF("DMA error\n");
b8842209 323 m->aiocb = NULL;
8aef291f 324 ide_dma_error(s);
80fc95d8 325 io->remainder_len = 0;
a597e79c 326 goto done;
b8842209
GH
327 }
328
cae32357
AG
329 if (!m->dma_active) {
330 MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
331 s->nsector, io->len, s->status);
332 /* data not ready yet, wait for the channel to get restarted */
333 io->processing = false;
334 return;
335 }
336
bd4214fc 337 if (s->io_buffer_size <= 0) {
33ce36bb 338 MACIO_DPRINTF("end of transfer\n");
b8842209 339 s->status = READY_STAT | SEEK_STAT;
9cdd03a7 340 ide_set_irq(s->bus);
cae32357 341 m->dma_active = false;
bd4214fc 342 goto done;
b8842209
GH
343 }
344
b8842209 345 if (io->len == 0) {
bd4214fc 346 MACIO_DPRINTF("End of DMA transfer\n");
a597e79c 347 goto done;
b8842209
GH
348 }
349
bd4214fc
MCA
350 /* Calculate number of sectors */
351 sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
352 nsector = (io->len + 0x1ff) >> 9;
353 remainder = io->len & 0x1ff;
80fc95d8 354
bd4214fc 355 s->nsector -= nsector;
b8842209 356
bd4214fc
MCA
357 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder);
358 MACIO_DPRINTF("sector: %"PRIx64" %x\n", sector_num, nsector);
33ce36bb 359
4e1e0051
CH
360 switch (s->dma_cmd) {
361 case IDE_DMA_READ:
bd4214fc 362 pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
4e1e0051
CH
363 break;
364 case IDE_DMA_WRITE:
bd4214fc 365 pmac_dma_write(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
4e1e0051 366 break;
d353fb72 367 case IDE_DMA_TRIM:
bd4214fc 368 MACIO_DPRINTF("TRIM command issued!");
d353fb72 369 break;
4e1e0051 370 }
3e300fa6 371
a597e79c 372 return;
b9b2008b 373
a597e79c
CH
374done:
375 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
4be74634 376 block_acct_done(blk_get_stats(s->blk), &s->acct);
a597e79c 377 }
bd4214fc 378 io->dma_end(opaque);
b8842209
GH
379}
380
381static void pmac_ide_transfer(DBDMA_io *io)
382{
383 MACIOIDEState *m = io->opaque;
384 IDEState *s = idebus_active_if(&m->bus);
385
33ce36bb
AG
386 MACIO_DPRINTF("\n");
387
cd8722bb 388 if (s->drive_kind == IDE_CD) {
4be74634 389 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
5366d0c8 390 BLOCK_ACCT_READ);
4827ac1e 391
b8842209
GH
392 pmac_ide_atapi_transfer_cb(io, 0);
393 return;
394 }
395
a597e79c
CH
396 switch (s->dma_cmd) {
397 case IDE_DMA_READ:
4be74634 398 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
5366d0c8 399 BLOCK_ACCT_READ);
a597e79c
CH
400 break;
401 case IDE_DMA_WRITE:
4be74634 402 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
5366d0c8 403 BLOCK_ACCT_WRITE);
a597e79c
CH
404 break;
405 default:
406 break;
407 }
408
b8842209
GH
409 pmac_ide_transfer_cb(io, 0);
410}
411
412static void pmac_ide_flush(DBDMA_io *io)
413{
414 MACIOIDEState *m = io->opaque;
415
922453bc 416 if (m->aiocb) {
4be74634 417 blk_drain_all();
922453bc 418 }
b8842209
GH
419}
420
421/* PowerMac IDE memory IO */
422static void pmac_ide_writeb (void *opaque,
a8170e5e 423 hwaddr addr, uint32_t val)
b8842209
GH
424{
425 MACIOIDEState *d = opaque;
426
427 addr = (addr & 0xFFF) >> 4;
428 switch (addr) {
429 case 1 ... 7:
430 ide_ioport_write(&d->bus, addr, val);
431 break;
432 case 8:
433 case 22:
434 ide_cmd_write(&d->bus, 0, val);
435 break;
436 default:
437 break;
438 }
439}
440
a8170e5e 441static uint32_t pmac_ide_readb (void *opaque,hwaddr addr)
b8842209
GH
442{
443 uint8_t retval;
444 MACIOIDEState *d = opaque;
445
446 addr = (addr & 0xFFF) >> 4;
447 switch (addr) {
448 case 1 ... 7:
449 retval = ide_ioport_read(&d->bus, addr);
450 break;
451 case 8:
452 case 22:
453 retval = ide_status_read(&d->bus, 0);
454 break;
455 default:
456 retval = 0xFF;
457 break;
458 }
459 return retval;
460}
461
462static void pmac_ide_writew (void *opaque,
a8170e5e 463 hwaddr addr, uint32_t val)
b8842209
GH
464{
465 MACIOIDEState *d = opaque;
466
467 addr = (addr & 0xFFF) >> 4;
b8842209 468 val = bswap16(val);
b8842209
GH
469 if (addr == 0) {
470 ide_data_writew(&d->bus, 0, val);
471 }
472}
473
a8170e5e 474static uint32_t pmac_ide_readw (void *opaque,hwaddr addr)
b8842209
GH
475{
476 uint16_t retval;
477 MACIOIDEState *d = opaque;
478
479 addr = (addr & 0xFFF) >> 4;
480 if (addr == 0) {
481 retval = ide_data_readw(&d->bus, 0);
482 } else {
483 retval = 0xFFFF;
484 }
b8842209 485 retval = bswap16(retval);
b8842209
GH
486 return retval;
487}
488
489static void pmac_ide_writel (void *opaque,
a8170e5e 490 hwaddr addr, uint32_t val)
b8842209
GH
491{
492 MACIOIDEState *d = opaque;
493
494 addr = (addr & 0xFFF) >> 4;
b8842209 495 val = bswap32(val);
b8842209
GH
496 if (addr == 0) {
497 ide_data_writel(&d->bus, 0, val);
498 }
499}
500
a8170e5e 501static uint32_t pmac_ide_readl (void *opaque,hwaddr addr)
b8842209
GH
502{
503 uint32_t retval;
504 MACIOIDEState *d = opaque;
505
506 addr = (addr & 0xFFF) >> 4;
507 if (addr == 0) {
508 retval = ide_data_readl(&d->bus, 0);
509 } else {
510 retval = 0xFFFFFFFF;
511 }
b8842209 512 retval = bswap32(retval);
b8842209
GH
513 return retval;
514}
515
a348f108 516static const MemoryRegionOps pmac_ide_ops = {
23c5e4ca
AK
517 .old_mmio = {
518 .write = {
519 pmac_ide_writeb,
520 pmac_ide_writew,
521 pmac_ide_writel,
522 },
523 .read = {
524 pmac_ide_readb,
525 pmac_ide_readw,
526 pmac_ide_readl,
527 },
528 },
529 .endianness = DEVICE_NATIVE_ENDIAN,
b8842209
GH
530};
531
44bfa332
JQ
532static const VMStateDescription vmstate_pmac = {
533 .name = "ide",
534 .version_id = 3,
535 .minimum_version_id = 0,
35d08458 536 .fields = (VMStateField[]) {
44bfa332
JQ
537 VMSTATE_IDE_BUS(bus, MACIOIDEState),
538 VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState),
539 VMSTATE_END_OF_LIST()
b8842209 540 }
44bfa332 541};
b8842209 542
07a7484e 543static void macio_ide_reset(DeviceState *dev)
b8842209 544{
07a7484e 545 MACIOIDEState *d = MACIO_IDE(dev);
b8842209 546
4a643563 547 ide_bus_reset(&d->bus);
b8842209
GH
548}
549
4aa3510f
AG
550static int ide_nop_int(IDEDMA *dma, int x)
551{
552 return 0;
553}
554
3251bdcf
JS
555static int32_t ide_nop_int32(IDEDMA *dma, int x)
556{
557 return 0;
558}
559
4aa3510f 560static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
097310b5 561 BlockCompletionFunc *cb)
4aa3510f
AG
562{
563 MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);
4827ac1e
MCA
564 DBDMAState *dbdma = m->dbdma;
565 DBDMA_io *io;
566 int i;
567
bd4214fc 568 s->io_buffer_index = 0;
4827ac1e 569 if (s->drive_kind == IDE_CD) {
4827ac1e 570 s->io_buffer_size = s->packet_transfer_size;
bd4214fc
MCA
571 } else {
572 s->io_buffer_size = s->nsector * 0x200;
573 }
4827ac1e 574
bd4214fc
MCA
575 MACIO_DPRINTF("\n\n------------ IDE transfer\n");
576 MACIO_DPRINTF("buffer_size: %x buffer_index: %x\n",
577 s->io_buffer_size, s->io_buffer_index);
578 MACIO_DPRINTF("lba: %x size: %x\n", s->lba, s->io_buffer_size);
579 MACIO_DPRINTF("-------------------------\n");
4827ac1e 580
bd4214fc
MCA
581 for (i = 0; i < DBDMA_CHANNELS; i++) {
582 io = &dbdma->channels[i].io;
4827ac1e 583
bd4214fc
MCA
584 if (io->opaque == m) {
585 io->remainder_len = 0;
4827ac1e
MCA
586 }
587 }
4aa3510f
AG
588
589 MACIO_DPRINTF("\n");
cae32357 590 m->dma_active = true;
4aa3510f
AG
591 DBDMA_kick(m->dbdma);
592}
593
594static const IDEDMAOps dbdma_ops = {
595 .start_dma = ide_dbdma_start,
3251bdcf 596 .prepare_buf = ide_nop_int32,
4aa3510f 597 .rw_buf = ide_nop_int,
4aa3510f
AG
598};
599
07a7484e 600static void macio_ide_realizefn(DeviceState *dev, Error **errp)
b8842209 601{
07a7484e
AF
602 MACIOIDEState *s = MACIO_IDE(dev);
603
604 ide_init2(&s->bus, s->irq);
4aa3510f
AG
605
606 /* Register DMA callbacks */
607 s->dma.ops = &dbdma_ops;
608 s->bus.dma = &s->dma;
07a7484e
AF
609}
610
611static void macio_ide_initfn(Object *obj)
612{
613 SysBusDevice *d = SYS_BUS_DEVICE(obj);
614 MACIOIDEState *s = MACIO_IDE(obj);
615
c6baf942 616 ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
1437c94b 617 memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
07a7484e
AF
618 sysbus_init_mmio(d, &s->mem);
619 sysbus_init_irq(d, &s->irq);
620 sysbus_init_irq(d, &s->dma_irq);
621}
622
623static void macio_ide_class_init(ObjectClass *oc, void *data)
624{
625 DeviceClass *dc = DEVICE_CLASS(oc);
626
627 dc->realize = macio_ide_realizefn;
628 dc->reset = macio_ide_reset;
629 dc->vmsd = &vmstate_pmac;
630}
b8842209 631
07a7484e
AF
632static const TypeInfo macio_ide_type_info = {
633 .name = TYPE_MACIO_IDE,
634 .parent = TYPE_SYS_BUS_DEVICE,
635 .instance_size = sizeof(MACIOIDEState),
636 .instance_init = macio_ide_initfn,
637 .class_init = macio_ide_class_init,
638};
b8842209 639
07a7484e
AF
640static void macio_ide_register_types(void)
641{
642 type_register_static(&macio_ide_type_info);
643}
b8842209 644
14eefd0e 645/* hd_table must contain 2 block drivers */
07a7484e
AF
646void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
647{
648 int i;
b8842209 649
07a7484e
AF
650 for (i = 0; i < 2; i++) {
651 if (hd_table[i]) {
652 ide_create_drive(&s->bus, i, hd_table[i]);
653 }
654 }
b8842209 655}
07a7484e
AF
656
657void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
658{
4aa3510f 659 s->dbdma = dbdma;
07a7484e
AF
660 DBDMA_register_channel(dbdma, channel, s->dma_irq,
661 pmac_ide_transfer, pmac_ide_flush, s);
662}
663
664type_init(macio_ide_register_types)
This page took 0.671268 seconds and 4 git commands to generate.