virtio: make features 64bit wide
[qemu/ar7.git] / hw / ide / macio.c
blob585a27bd6c7fd87b7cc9a9ca34cfc50d999f6230
1 /*
2 * QEMU IDE Emulation: MacIO support.
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2006 Openedhand Ltd.
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
25 #include "hw/hw.h"
26 #include "hw/ppc/mac.h"
27 #include "hw/ppc/mac_dbdma.h"
28 #include "sysemu/block-backend.h"
29 #include "sysemu/dma.h"
31 #include <hw/ide/internal.h>
33 /* debug MACIO */
34 // #define DEBUG_MACIO
36 #ifdef DEBUG_MACIO
37 static const int debug_macio = 1;
38 #else
39 static const int debug_macio = 0;
40 #endif
42 #define MACIO_DPRINTF(fmt, ...) do { \
43 if (debug_macio) { \
44 printf(fmt , ## __VA_ARGS__); \
45 } \
46 } while (0)
49 /***********************************************************/
50 /* MacIO based PowerPC IDE */
52 #define MACIO_PAGE_SIZE 4096
54 static void pmac_dma_read(BlockBackend *blk,
55 int64_t sector_num, int nb_sectors,
56 void (*cb)(void *opaque, int ret), void *opaque)
58 DBDMA_io *io = opaque;
59 MACIOIDEState *m = io->opaque;
60 IDEState *s = idebus_active_if(&m->bus);
61 dma_addr_t dma_addr, dma_len;
62 void *mem;
63 int nsector, remainder;
65 qemu_iovec_destroy(&io->iov);
66 qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
68 if (io->remainder_len > 0) {
69 /* Return remainder of request */
70 int transfer = MIN(io->remainder_len, io->len);
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);
77 cpu_physical_memory_write(io->addr,
78 &io->remainder + (0x200 - transfer),
79 transfer);
81 io->remainder_len -= transfer;
82 io->len -= transfer;
83 io->addr += transfer;
85 s->io_buffer_index += transfer;
86 s->io_buffer_size -= transfer;
88 if (io->remainder_len != 0) {
89 /* Still waiting for remainder */
90 return;
93 if (io->len == 0) {
94 MACIO_DPRINTF("--- finished all read processing; go and finish\n");
95 cb(opaque, 0);
96 return;
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);
106 nsector = ((io->len + 0x1ff) >> 9);
107 remainder = (nsector << 9) - io->len;
109 MACIO_DPRINTF("--- DMA read transfer - addr: %" HWADDR_PRIx " len: %x\n",
110 io->addr, io->len);
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);
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);
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);
132 io->remainder_len = remainder;
135 s->io_buffer_size -= io->len;
136 s->io_buffer_index += io->len;
138 io->len = 0;
140 MACIO_DPRINTF("--- Block read transfer - sector_num: %"PRIx64" "
141 "nsector: %x\n",
142 sector_num, nsector);
144 m->aiocb = blk_aio_readv(blk, sector_num, &io->iov, nsector, cb, io);
147 static void pmac_dma_write(BlockBackend *blk,
148 int64_t sector_num, int nb_sectors,
149 void (*cb)(void *opaque, int ret), void *opaque)
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;
159 qemu_iovec_destroy(&io->iov);
160 qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
162 if (io->remainder_len > 0) {
163 /* Return remainder of request */
164 int transfer = MIN(io->remainder_len, io->len);
166 MACIO_DPRINTF("--- processing write remainder %x\n", transfer);
167 cpu_physical_memory_read(io->addr,
168 &io->remainder + (0x200 - transfer),
169 transfer);
171 io->remainder_len -= transfer;
172 io->len -= transfer;
173 io->addr += transfer;
175 s->io_buffer_index += transfer;
176 s->io_buffer_size -= transfer;
178 if (io->remainder_len != 0) {
179 /* Still waiting for remainder */
180 return;
183 MACIO_DPRINTF("--> prepending bounce buffer with size 0x200\n");
185 /* Sector transfer complete - prepend to request */
186 qemu_iovec_add(&io->iov, &io->remainder, 0x200);
187 extra = 1;
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);
196 nsector = (io->len >> 9);
197 remainder = io->len - (nsector << 9);
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);
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);
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));
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);
225 io->remainder_len = 0x200 - remainder;
227 MACIO_DPRINTF("xxx remainder_len: %x\n", io->remainder_len);
230 s->io_buffer_size -= ((nsector + extra) << 9);
231 s->io_buffer_index += ((nsector + extra) << 9);
233 io->len = 0;
235 MACIO_DPRINTF("--- Block write transfer - sector_num: %"PRIx64" "
236 "nsector: %x\n", sector_num, nsector + extra);
238 m->aiocb = blk_aio_writev(blk, sector_num, &io->iov, nsector + extra, cb,
239 io);
242 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
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;
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);
258 if (ret < 0) {
259 MACIO_DPRINTF("THERE WAS AN ERROR! %d\n", ret);
260 ide_atapi_io_error(s, ret);
261 goto done;
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;
269 return;
272 if (s->io_buffer_size <= 0) {
273 ide_atapi_cmd_ok(s);
274 m->dma_active = false;
275 goto done;
278 if (io->len == 0) {
279 MACIO_DPRINTF("End of DMA transfer\n");
280 goto done;
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;
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;
297 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder);
298 MACIO_DPRINTF("sector: %"PRIx64" %zx\n", sector_num, io->iov.size / 512);
300 pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_atapi_transfer_cb, io);
301 return;
303 done:
304 MACIO_DPRINTF("done DMA\n\n");
305 block_acct_done(blk_get_stats(s->blk), &s->acct);
306 io->dma_end(opaque);
308 return;
311 static void pmac_ide_transfer_cb(void *opaque, int ret)
313 DBDMA_io *io = opaque;
314 MACIOIDEState *m = io->opaque;
315 IDEState *s = idebus_active_if(&m->bus);
316 int64_t sector_num;
317 int nsector, remainder;
319 MACIO_DPRINTF("pmac_ide_transfer_cb\n");
321 if (ret < 0) {
322 MACIO_DPRINTF("DMA error\n");
323 m->aiocb = NULL;
324 ide_dma_error(s);
325 io->remainder_len = 0;
326 goto done;
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;
337 if (s->io_buffer_size <= 0) {
338 MACIO_DPRINTF("end of transfer\n");
339 s->status = READY_STAT | SEEK_STAT;
340 ide_set_irq(s->bus);
341 m->dma_active = false;
342 goto done;
345 if (io->len == 0) {
346 MACIO_DPRINTF("End of DMA transfer\n");
347 goto done;
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;
355 s->nsector -= nsector;
357 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder);
358 MACIO_DPRINTF("sector: %"PRIx64" %x\n", sector_num, nsector);
360 switch (s->dma_cmd) {
361 case IDE_DMA_READ:
362 pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
363 break;
364 case IDE_DMA_WRITE:
365 pmac_dma_write(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
366 break;
367 case IDE_DMA_TRIM:
368 MACIO_DPRINTF("TRIM command issued!");
369 break;
372 return;
374 done:
375 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
376 block_acct_done(blk_get_stats(s->blk), &s->acct);
378 io->dma_end(opaque);
381 static void pmac_ide_transfer(DBDMA_io *io)
383 MACIOIDEState *m = io->opaque;
384 IDEState *s = idebus_active_if(&m->bus);
386 MACIO_DPRINTF("\n");
388 if (s->drive_kind == IDE_CD) {
389 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
390 BLOCK_ACCT_READ);
392 pmac_ide_atapi_transfer_cb(io, 0);
393 return;
396 switch (s->dma_cmd) {
397 case IDE_DMA_READ:
398 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
399 BLOCK_ACCT_READ);
400 break;
401 case IDE_DMA_WRITE:
402 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
403 BLOCK_ACCT_WRITE);
404 break;
405 default:
406 break;
409 pmac_ide_transfer_cb(io, 0);
412 static void pmac_ide_flush(DBDMA_io *io)
414 MACIOIDEState *m = io->opaque;
416 if (m->aiocb) {
417 blk_drain_all();
421 /* PowerMac IDE memory IO */
422 static void pmac_ide_writeb (void *opaque,
423 hwaddr addr, uint32_t val)
425 MACIOIDEState *d = opaque;
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;
441 static uint32_t pmac_ide_readb (void *opaque,hwaddr addr)
443 uint8_t retval;
444 MACIOIDEState *d = opaque;
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;
459 return retval;
462 static void pmac_ide_writew (void *opaque,
463 hwaddr addr, uint32_t val)
465 MACIOIDEState *d = opaque;
467 addr = (addr & 0xFFF) >> 4;
468 val = bswap16(val);
469 if (addr == 0) {
470 ide_data_writew(&d->bus, 0, val);
474 static uint32_t pmac_ide_readw (void *opaque,hwaddr addr)
476 uint16_t retval;
477 MACIOIDEState *d = opaque;
479 addr = (addr & 0xFFF) >> 4;
480 if (addr == 0) {
481 retval = ide_data_readw(&d->bus, 0);
482 } else {
483 retval = 0xFFFF;
485 retval = bswap16(retval);
486 return retval;
489 static void pmac_ide_writel (void *opaque,
490 hwaddr addr, uint32_t val)
492 MACIOIDEState *d = opaque;
494 addr = (addr & 0xFFF) >> 4;
495 val = bswap32(val);
496 if (addr == 0) {
497 ide_data_writel(&d->bus, 0, val);
501 static uint32_t pmac_ide_readl (void *opaque,hwaddr addr)
503 uint32_t retval;
504 MACIOIDEState *d = opaque;
506 addr = (addr & 0xFFF) >> 4;
507 if (addr == 0) {
508 retval = ide_data_readl(&d->bus, 0);
509 } else {
510 retval = 0xFFFFFFFF;
512 retval = bswap32(retval);
513 return retval;
516 static const MemoryRegionOps pmac_ide_ops = {
517 .old_mmio = {
518 .write = {
519 pmac_ide_writeb,
520 pmac_ide_writew,
521 pmac_ide_writel,
523 .read = {
524 pmac_ide_readb,
525 pmac_ide_readw,
526 pmac_ide_readl,
529 .endianness = DEVICE_NATIVE_ENDIAN,
532 static const VMStateDescription vmstate_pmac = {
533 .name = "ide",
534 .version_id = 3,
535 .minimum_version_id = 0,
536 .fields = (VMStateField[]) {
537 VMSTATE_IDE_BUS(bus, MACIOIDEState),
538 VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState),
539 VMSTATE_END_OF_LIST()
543 static void macio_ide_reset(DeviceState *dev)
545 MACIOIDEState *d = MACIO_IDE(dev);
547 ide_bus_reset(&d->bus);
550 static int ide_nop_int(IDEDMA *dma, int x)
552 return 0;
555 static int32_t ide_nop_int32(IDEDMA *dma, int x)
557 return 0;
560 static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
561 BlockCompletionFunc *cb)
563 MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);
564 DBDMAState *dbdma = m->dbdma;
565 DBDMA_io *io;
566 int i;
568 s->io_buffer_index = 0;
569 if (s->drive_kind == IDE_CD) {
570 s->io_buffer_size = s->packet_transfer_size;
571 } else {
572 s->io_buffer_size = s->nsector * 0x200;
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");
581 for (i = 0; i < DBDMA_CHANNELS; i++) {
582 io = &dbdma->channels[i].io;
584 if (io->opaque == m) {
585 io->remainder_len = 0;
589 MACIO_DPRINTF("\n");
590 m->dma_active = true;
591 DBDMA_kick(m->dbdma);
594 static const IDEDMAOps dbdma_ops = {
595 .start_dma = ide_dbdma_start,
596 .prepare_buf = ide_nop_int32,
597 .rw_buf = ide_nop_int,
600 static void macio_ide_realizefn(DeviceState *dev, Error **errp)
602 MACIOIDEState *s = MACIO_IDE(dev);
604 ide_init2(&s->bus, s->irq);
606 /* Register DMA callbacks */
607 s->dma.ops = &dbdma_ops;
608 s->bus.dma = &s->dma;
611 static void macio_ide_initfn(Object *obj)
613 SysBusDevice *d = SYS_BUS_DEVICE(obj);
614 MACIOIDEState *s = MACIO_IDE(obj);
616 ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
617 memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
618 sysbus_init_mmio(d, &s->mem);
619 sysbus_init_irq(d, &s->irq);
620 sysbus_init_irq(d, &s->dma_irq);
623 static void macio_ide_class_init(ObjectClass *oc, void *data)
625 DeviceClass *dc = DEVICE_CLASS(oc);
627 dc->realize = macio_ide_realizefn;
628 dc->reset = macio_ide_reset;
629 dc->vmsd = &vmstate_pmac;
632 static 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,
640 static void macio_ide_register_types(void)
642 type_register_static(&macio_ide_type_info);
645 /* hd_table must contain 2 block drivers */
646 void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
648 int i;
650 for (i = 0; i < 2; i++) {
651 if (hd_table[i]) {
652 ide_create_drive(&s->bus, i, hd_table[i]);
657 void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
659 s->dbdma = dbdma;
660 DBDMA_register_channel(dbdma, channel, s->dma_irq,
661 pmac_ide_transfer, pmac_ide_flush, s);
664 type_init(macio_ide_register_types)