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 */ 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" 30 31 #include <hw/ide/internal.h> 32 33 /* debug MACIO */ 34 // #define DEBUG_MACIO 35 36 #ifdef DEBUG_MACIO 37 static const int debug_macio = 1; 38 #else 39 static 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 49 /***********************************************************/ 50 /* MacIO based PowerPC IDE */ 51 52 #define MACIO_PAGE_SIZE 4096 53 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) 57 { 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; 64 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 } 98 } 99 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); 104 } 105 106 nsector = ((io->len + 0x1ff) >> 9); 107 remainder = (nsector << 9) - io->len; 108 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); 125 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); 131 132 io->remainder_len = remainder; 133 } 134 135 s->io_buffer_size -= io->len; 136 s->io_buffer_index += io->len; 137 138 io->len = 0; 139 140 MACIO_DPRINTF("--- Block read transfer - sector_num: %"PRIx64" " 141 "nsector: %x\n", 142 sector_num, nsector); 143 144 m->aiocb = blk_aio_readv(blk, sector_num, &io->iov, nsector, cb, io); 145 } 146 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) 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 242 static 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; 269 return; 270 } 271 272 if (s->io_buffer_size <= 0) { 273 ide_atapi_cmd_ok(s); 274 m->dma_active = false; 275 goto done; 276 } 277 278 if (io->len == 0) { 279 MACIO_DPRINTF("End of DMA transfer\n"); 280 goto done; 281 } 282 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; 290 } 291 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; 296 297 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder); 298 MACIO_DPRINTF("sector: %"PRIx64" %zx\n", sector_num, io->iov.size / 512); 299 300 pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_atapi_transfer_cb, io); 301 return; 302 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); 307 308 return; 309 } 310 311 static 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); 316 int64_t sector_num; 317 int nsector, remainder; 318 319 MACIO_DPRINTF("pmac_ide_transfer_cb\n"); 320 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; 327 } 328 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 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; 343 } 344 345 if (io->len == 0) { 346 MACIO_DPRINTF("End of DMA transfer\n"); 347 goto done; 348 } 349 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; 354 355 s->nsector -= nsector; 356 357 MACIO_DPRINTF("nsector: %d remainder: %x\n", nsector, remainder); 358 MACIO_DPRINTF("sector: %"PRIx64" %x\n", sector_num, nsector); 359 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; 370 } 371 372 return; 373 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); 377 } 378 io->dma_end(opaque); 379 } 380 381 static void pmac_ide_transfer(DBDMA_io *io) 382 { 383 MACIOIDEState *m = io->opaque; 384 IDEState *s = idebus_active_if(&m->bus); 385 386 MACIO_DPRINTF("\n"); 387 388 if (s->drive_kind == IDE_CD) { 389 block_acct_start(blk_get_stats(s->blk), &s->acct, io->len, 390 BLOCK_ACCT_READ); 391 392 pmac_ide_atapi_transfer_cb(io, 0); 393 return; 394 } 395 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; 407 } 408 409 pmac_ide_transfer_cb(io, 0); 410 } 411 412 static void pmac_ide_flush(DBDMA_io *io) 413 { 414 MACIOIDEState *m = io->opaque; 415 416 if (m->aiocb) { 417 blk_drain_all(); 418 } 419 } 420 421 /* PowerMac IDE memory IO */ 422 static void pmac_ide_writeb (void *opaque, 423 hwaddr addr, uint32_t val) 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 441 static uint32_t pmac_ide_readb (void *opaque,hwaddr addr) 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 462 static void pmac_ide_writew (void *opaque, 463 hwaddr addr, uint32_t val) 464 { 465 MACIOIDEState *d = opaque; 466 467 addr = (addr & 0xFFF) >> 4; 468 val = bswap16(val); 469 if (addr == 0) { 470 ide_data_writew(&d->bus, 0, val); 471 } 472 } 473 474 static uint32_t pmac_ide_readw (void *opaque,hwaddr addr) 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 } 485 retval = bswap16(retval); 486 return retval; 487 } 488 489 static void pmac_ide_writel (void *opaque, 490 hwaddr addr, uint32_t val) 491 { 492 MACIOIDEState *d = opaque; 493 494 addr = (addr & 0xFFF) >> 4; 495 val = bswap32(val); 496 if (addr == 0) { 497 ide_data_writel(&d->bus, 0, val); 498 } 499 } 500 501 static uint32_t pmac_ide_readl (void *opaque,hwaddr addr) 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 } 512 retval = bswap32(retval); 513 return retval; 514 } 515 516 static const MemoryRegionOps pmac_ide_ops = { 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, 530 }; 531 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() 540 } 541 }; 542 543 static void macio_ide_reset(DeviceState *dev) 544 { 545 MACIOIDEState *d = MACIO_IDE(dev); 546 547 ide_bus_reset(&d->bus); 548 } 549 550 static int ide_nop_int(IDEDMA *dma, int x) 551 { 552 return 0; 553 } 554 555 static int32_t ide_nop_int32(IDEDMA *dma, int x) 556 { 557 return 0; 558 } 559 560 static void ide_dbdma_start(IDEDMA *dma, IDEState *s, 561 BlockCompletionFunc *cb) 562 { 563 MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); 564 DBDMAState *dbdma = m->dbdma; 565 DBDMA_io *io; 566 int i; 567 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; 573 } 574 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"); 580 581 for (i = 0; i < DBDMA_CHANNELS; i++) { 582 io = &dbdma->channels[i].io; 583 584 if (io->opaque == m) { 585 io->remainder_len = 0; 586 } 587 } 588 589 MACIO_DPRINTF("\n"); 590 m->dma_active = true; 591 DBDMA_kick(m->dbdma); 592 } 593 594 static const IDEDMAOps dbdma_ops = { 595 .start_dma = ide_dbdma_start, 596 .prepare_buf = ide_nop_int32, 597 .rw_buf = ide_nop_int, 598 }; 599 600 static void macio_ide_realizefn(DeviceState *dev, Error **errp) 601 { 602 MACIOIDEState *s = MACIO_IDE(dev); 603 604 ide_init2(&s->bus, s->irq); 605 606 /* Register DMA callbacks */ 607 s->dma.ops = &dbdma_ops; 608 s->bus.dma = &s->dma; 609 } 610 611 static void macio_ide_initfn(Object *obj) 612 { 613 SysBusDevice *d = SYS_BUS_DEVICE(obj); 614 MACIOIDEState *s = MACIO_IDE(obj); 615 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); 621 } 622 623 static 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 } 631 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, 638 }; 639 640 static void macio_ide_register_types(void) 641 { 642 type_register_static(&macio_ide_type_info); 643 } 644 645 /* hd_table must contain 2 block drivers */ 646 void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) 647 { 648 int i; 649 650 for (i = 0; i < 2; i++) { 651 if (hd_table[i]) { 652 ide_create_drive(&s->bus, i, hd_table[i]); 653 } 654 } 655 } 656 657 void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) 658 { 659 s->dbdma = dbdma; 660 DBDMA_register_channel(dbdma, channel, s->dma_irq, 661 pmac_ide_transfer, pmac_ide_flush, s); 662 } 663 664 type_init(macio_ide_register_types) 665