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 "block/block.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_ide_atapi_transfer_cb(void *opaque, int ret) 55 { 56 DBDMA_io *io = opaque; 57 MACIOIDEState *m = io->opaque; 58 IDEState *s = idebus_active_if(&m->bus); 59 int unaligned; 60 61 if (ret < 0) { 62 m->aiocb = NULL; 63 qemu_sglist_destroy(&s->sg); 64 ide_atapi_io_error(s, ret); 65 io->remainder_len = 0; 66 goto done; 67 } 68 69 if (!m->dma_active) { 70 MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", 71 s->nsector, io->len, s->status); 72 /* data not ready yet, wait for the channel to get restarted */ 73 io->processing = false; 74 return; 75 } 76 77 MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 78 79 if (s->io_buffer_size > 0) { 80 m->aiocb = NULL; 81 qemu_sglist_destroy(&s->sg); 82 83 s->packet_transfer_size -= s->io_buffer_size; 84 85 s->io_buffer_index += s->io_buffer_size; 86 s->lba += s->io_buffer_index >> 11; 87 s->io_buffer_index &= 0x7ff; 88 } 89 90 s->io_buffer_size = MIN(io->len, s->packet_transfer_size); 91 92 MACIO_DPRINTF("remainder: %d io->len: %d size: %d\n", io->remainder_len, 93 io->len, s->packet_transfer_size); 94 if (io->remainder_len && io->len) { 95 /* guest wants the rest of its previous transfer */ 96 int remainder_len = MIN(io->remainder_len, io->len); 97 98 MACIO_DPRINTF("copying remainder %d bytes\n", remainder_len); 99 100 cpu_physical_memory_write(io->addr, io->remainder + 0x200 - 101 remainder_len, remainder_len); 102 103 io->addr += remainder_len; 104 io->len -= remainder_len; 105 s->io_buffer_size = remainder_len; 106 io->remainder_len -= remainder_len; 107 /* treat remainder as individual transfer, start again */ 108 qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 109 &address_space_memory); 110 pmac_ide_atapi_transfer_cb(opaque, 0); 111 return; 112 } 113 114 if (!s->packet_transfer_size) { 115 MACIO_DPRINTF("end of transfer\n"); 116 ide_atapi_cmd_ok(s); 117 m->dma_active = false; 118 } 119 120 if (io->len == 0) { 121 MACIO_DPRINTF("end of DMA\n"); 122 goto done; 123 } 124 125 /* launch next transfer */ 126 127 /* handle unaligned accesses first, get them over with and only do the 128 remaining bulk transfer using our async DMA helpers */ 129 unaligned = io->len & 0x1ff; 130 if (unaligned) { 131 int sector_num = (s->lba << 2) + (s->io_buffer_index >> 9); 132 int nsector = io->len >> 9; 133 134 MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n", 135 unaligned, io->addr + io->len - unaligned); 136 137 bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); 138 cpu_physical_memory_write(io->addr + io->len - unaligned, 139 io->remainder, unaligned); 140 141 io->len -= unaligned; 142 } 143 144 MACIO_DPRINTF("io->len = %#x\n", io->len); 145 146 qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 147 &address_space_memory); 148 qemu_sglist_add(&s->sg, io->addr, io->len); 149 io->addr += s->io_buffer_size; 150 io->remainder_len = MIN(s->packet_transfer_size - s->io_buffer_size, 151 (0x200 - unaligned) & 0x1ff); 152 MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len); 153 154 /* We would read no data from the block layer, thus not get a callback. 155 Just fake completion manually. */ 156 if (!io->len) { 157 pmac_ide_atapi_transfer_cb(opaque, 0); 158 return; 159 } 160 161 io->len = 0; 162 163 MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", 164 (s->lba << 2) + (s->io_buffer_index >> 9), 165 s->packet_transfer_size, s->dma_cmd); 166 167 m->aiocb = dma_bdrv_read(s->bs, &s->sg, 168 (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), 169 pmac_ide_atapi_transfer_cb, io); 170 return; 171 172 done: 173 MACIO_DPRINTF("done DMA\n"); 174 bdrv_acct_done(s->bs, &s->acct); 175 io->dma_end(opaque); 176 } 177 178 static void pmac_ide_transfer_cb(void *opaque, int ret) 179 { 180 DBDMA_io *io = opaque; 181 MACIOIDEState *m = io->opaque; 182 IDEState *s = idebus_active_if(&m->bus); 183 int n = 0; 184 int64_t sector_num; 185 int unaligned; 186 187 if (ret < 0) { 188 MACIO_DPRINTF("DMA error\n"); 189 m->aiocb = NULL; 190 qemu_sglist_destroy(&s->sg); 191 ide_dma_error(s); 192 io->remainder_len = 0; 193 goto done; 194 } 195 196 if (!m->dma_active) { 197 MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", 198 s->nsector, io->len, s->status); 199 /* data not ready yet, wait for the channel to get restarted */ 200 io->processing = false; 201 return; 202 } 203 204 sector_num = ide_get_sector(s); 205 MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); 206 if (s->io_buffer_size > 0) { 207 m->aiocb = NULL; 208 qemu_sglist_destroy(&s->sg); 209 n = (s->io_buffer_size + 0x1ff) >> 9; 210 sector_num += n; 211 ide_set_sector(s, sector_num); 212 s->nsector -= n; 213 } 214 215 MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d " 216 "sector_num: %" PRId64 "\n", 217 io->remainder_len, io->len, s->nsector, sector_num); 218 if (io->remainder_len && io->len) { 219 /* guest wants the rest of its previous transfer */ 220 int remainder_len = MIN(io->remainder_len, io->len); 221 uint8_t *p = &io->remainder[0x200 - remainder_len]; 222 223 MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\n", 224 remainder_len, io->addr); 225 226 switch (s->dma_cmd) { 227 case IDE_DMA_READ: 228 cpu_physical_memory_write(io->addr, p, remainder_len); 229 break; 230 case IDE_DMA_WRITE: 231 cpu_physical_memory_read(io->addr, p, remainder_len); 232 bdrv_write(s->bs, sector_num - 1, io->remainder, 1); 233 break; 234 case IDE_DMA_TRIM: 235 break; 236 } 237 io->addr += remainder_len; 238 io->len -= remainder_len; 239 io->remainder_len -= remainder_len; 240 } 241 242 if (s->nsector == 0 && !io->remainder_len) { 243 MACIO_DPRINTF("end of transfer\n"); 244 s->status = READY_STAT | SEEK_STAT; 245 ide_set_irq(s->bus); 246 m->dma_active = false; 247 } 248 249 if (io->len == 0) { 250 MACIO_DPRINTF("end of DMA\n"); 251 goto done; 252 } 253 254 /* launch next transfer */ 255 256 s->io_buffer_index = 0; 257 s->io_buffer_size = MIN(io->len, s->nsector * 512); 258 259 /* handle unaligned accesses first, get them over with and only do the 260 remaining bulk transfer using our async DMA helpers */ 261 unaligned = io->len & 0x1ff; 262 if (unaligned) { 263 int nsector = io->len >> 9; 264 265 MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n", 266 unaligned, io->addr + io->len - unaligned); 267 268 switch (s->dma_cmd) { 269 case IDE_DMA_READ: 270 bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); 271 cpu_physical_memory_write(io->addr + io->len - unaligned, 272 io->remainder, unaligned); 273 break; 274 case IDE_DMA_WRITE: 275 /* cache the contents in our io struct */ 276 cpu_physical_memory_read(io->addr + io->len - unaligned, 277 io->remainder, unaligned); 278 break; 279 case IDE_DMA_TRIM: 280 break; 281 } 282 283 io->len -= unaligned; 284 } 285 286 MACIO_DPRINTF("io->len = %#x\n", io->len); 287 288 qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 289 &address_space_memory); 290 qemu_sglist_add(&s->sg, io->addr, io->len); 291 io->addr += io->len + unaligned; 292 io->remainder_len = (0x200 - unaligned) & 0x1ff; 293 MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len); 294 295 /* We would read no data from the block layer, thus not get a callback. 296 Just fake completion manually. */ 297 if (!io->len) { 298 pmac_ide_transfer_cb(opaque, 0); 299 return; 300 } 301 302 io->len = 0; 303 304 MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n", 305 sector_num, n, s->nsector, s->dma_cmd); 306 307 switch (s->dma_cmd) { 308 case IDE_DMA_READ: 309 m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, 310 pmac_ide_transfer_cb, io); 311 break; 312 case IDE_DMA_WRITE: 313 m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, 314 pmac_ide_transfer_cb, io); 315 break; 316 case IDE_DMA_TRIM: 317 m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, 318 ide_issue_trim, pmac_ide_transfer_cb, io, 319 DMA_DIRECTION_TO_DEVICE); 320 break; 321 } 322 return; 323 324 done: 325 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { 326 bdrv_acct_done(s->bs, &s->acct); 327 } 328 io->dma_end(io); 329 } 330 331 static void pmac_ide_transfer(DBDMA_io *io) 332 { 333 MACIOIDEState *m = io->opaque; 334 IDEState *s = idebus_active_if(&m->bus); 335 336 MACIO_DPRINTF("\n"); 337 338 s->io_buffer_size = 0; 339 if (s->drive_kind == IDE_CD) { 340 341 /* Handle non-block ATAPI DMA transfers */ 342 if (s->lba == -1) { 343 s->io_buffer_size = MIN(io->len, s->packet_transfer_size); 344 bdrv_acct_start(s->bs, &s->acct, s->io_buffer_size, 345 BDRV_ACCT_READ); 346 MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n", 347 s->io_buffer_size); 348 349 /* Copy ATAPI buffer directly to RAM and finish */ 350 cpu_physical_memory_write(io->addr, s->io_buffer, 351 s->io_buffer_size); 352 ide_atapi_cmd_ok(s); 353 m->dma_active = false; 354 355 MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n"); 356 bdrv_acct_done(s->bs, &s->acct); 357 io->dma_end(io); 358 return; 359 } 360 361 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 362 pmac_ide_atapi_transfer_cb(io, 0); 363 return; 364 } 365 366 switch (s->dma_cmd) { 367 case IDE_DMA_READ: 368 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 369 break; 370 case IDE_DMA_WRITE: 371 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); 372 break; 373 default: 374 break; 375 } 376 377 pmac_ide_transfer_cb(io, 0); 378 } 379 380 static void pmac_ide_flush(DBDMA_io *io) 381 { 382 MACIOIDEState *m = io->opaque; 383 384 if (m->aiocb) { 385 bdrv_drain_all(); 386 } 387 } 388 389 /* PowerMac IDE memory IO */ 390 static void pmac_ide_writeb (void *opaque, 391 hwaddr addr, uint32_t val) 392 { 393 MACIOIDEState *d = opaque; 394 395 addr = (addr & 0xFFF) >> 4; 396 switch (addr) { 397 case 1 ... 7: 398 ide_ioport_write(&d->bus, addr, val); 399 break; 400 case 8: 401 case 22: 402 ide_cmd_write(&d->bus, 0, val); 403 break; 404 default: 405 break; 406 } 407 } 408 409 static uint32_t pmac_ide_readb (void *opaque,hwaddr addr) 410 { 411 uint8_t retval; 412 MACIOIDEState *d = opaque; 413 414 addr = (addr & 0xFFF) >> 4; 415 switch (addr) { 416 case 1 ... 7: 417 retval = ide_ioport_read(&d->bus, addr); 418 break; 419 case 8: 420 case 22: 421 retval = ide_status_read(&d->bus, 0); 422 break; 423 default: 424 retval = 0xFF; 425 break; 426 } 427 return retval; 428 } 429 430 static void pmac_ide_writew (void *opaque, 431 hwaddr addr, uint32_t val) 432 { 433 MACIOIDEState *d = opaque; 434 435 addr = (addr & 0xFFF) >> 4; 436 val = bswap16(val); 437 if (addr == 0) { 438 ide_data_writew(&d->bus, 0, val); 439 } 440 } 441 442 static uint32_t pmac_ide_readw (void *opaque,hwaddr addr) 443 { 444 uint16_t retval; 445 MACIOIDEState *d = opaque; 446 447 addr = (addr & 0xFFF) >> 4; 448 if (addr == 0) { 449 retval = ide_data_readw(&d->bus, 0); 450 } else { 451 retval = 0xFFFF; 452 } 453 retval = bswap16(retval); 454 return retval; 455 } 456 457 static void pmac_ide_writel (void *opaque, 458 hwaddr addr, uint32_t val) 459 { 460 MACIOIDEState *d = opaque; 461 462 addr = (addr & 0xFFF) >> 4; 463 val = bswap32(val); 464 if (addr == 0) { 465 ide_data_writel(&d->bus, 0, val); 466 } 467 } 468 469 static uint32_t pmac_ide_readl (void *opaque,hwaddr addr) 470 { 471 uint32_t retval; 472 MACIOIDEState *d = opaque; 473 474 addr = (addr & 0xFFF) >> 4; 475 if (addr == 0) { 476 retval = ide_data_readl(&d->bus, 0); 477 } else { 478 retval = 0xFFFFFFFF; 479 } 480 retval = bswap32(retval); 481 return retval; 482 } 483 484 static const MemoryRegionOps pmac_ide_ops = { 485 .old_mmio = { 486 .write = { 487 pmac_ide_writeb, 488 pmac_ide_writew, 489 pmac_ide_writel, 490 }, 491 .read = { 492 pmac_ide_readb, 493 pmac_ide_readw, 494 pmac_ide_readl, 495 }, 496 }, 497 .endianness = DEVICE_NATIVE_ENDIAN, 498 }; 499 500 static const VMStateDescription vmstate_pmac = { 501 .name = "ide", 502 .version_id = 3, 503 .minimum_version_id = 0, 504 .fields = (VMStateField[]) { 505 VMSTATE_IDE_BUS(bus, MACIOIDEState), 506 VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState), 507 VMSTATE_END_OF_LIST() 508 } 509 }; 510 511 static void macio_ide_reset(DeviceState *dev) 512 { 513 MACIOIDEState *d = MACIO_IDE(dev); 514 515 ide_bus_reset(&d->bus); 516 } 517 518 static int ide_nop(IDEDMA *dma) 519 { 520 return 0; 521 } 522 523 static int ide_nop_int(IDEDMA *dma, int x) 524 { 525 return 0; 526 } 527 528 static void ide_nop_restart(void *opaque, int x, RunState y) 529 { 530 } 531 532 static void ide_dbdma_start(IDEDMA *dma, IDEState *s, 533 BlockDriverCompletionFunc *cb) 534 { 535 MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); 536 537 MACIO_DPRINTF("\n"); 538 m->dma_active = true; 539 DBDMA_kick(m->dbdma); 540 } 541 542 static const IDEDMAOps dbdma_ops = { 543 .start_dma = ide_dbdma_start, 544 .start_transfer = ide_nop, 545 .prepare_buf = ide_nop_int, 546 .rw_buf = ide_nop_int, 547 .set_unit = ide_nop_int, 548 .add_status = ide_nop_int, 549 .set_inactive = ide_nop, 550 .restart_cb = ide_nop_restart, 551 .reset = ide_nop, 552 }; 553 554 static void macio_ide_realizefn(DeviceState *dev, Error **errp) 555 { 556 MACIOIDEState *s = MACIO_IDE(dev); 557 558 ide_init2(&s->bus, s->irq); 559 560 /* Register DMA callbacks */ 561 s->dma.ops = &dbdma_ops; 562 s->bus.dma = &s->dma; 563 } 564 565 static void macio_ide_initfn(Object *obj) 566 { 567 SysBusDevice *d = SYS_BUS_DEVICE(obj); 568 MACIOIDEState *s = MACIO_IDE(obj); 569 570 ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2); 571 memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000); 572 sysbus_init_mmio(d, &s->mem); 573 sysbus_init_irq(d, &s->irq); 574 sysbus_init_irq(d, &s->dma_irq); 575 } 576 577 static void macio_ide_class_init(ObjectClass *oc, void *data) 578 { 579 DeviceClass *dc = DEVICE_CLASS(oc); 580 581 dc->realize = macio_ide_realizefn; 582 dc->reset = macio_ide_reset; 583 dc->vmsd = &vmstate_pmac; 584 } 585 586 static const TypeInfo macio_ide_type_info = { 587 .name = TYPE_MACIO_IDE, 588 .parent = TYPE_SYS_BUS_DEVICE, 589 .instance_size = sizeof(MACIOIDEState), 590 .instance_init = macio_ide_initfn, 591 .class_init = macio_ide_class_init, 592 }; 593 594 static void macio_ide_register_types(void) 595 { 596 type_register_static(&macio_ide_type_info); 597 } 598 599 /* hd_table must contain 2 block drivers */ 600 void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) 601 { 602 int i; 603 604 for (i = 0; i < 2; i++) { 605 if (hd_table[i]) { 606 ide_create_drive(&s->bus, i, hd_table[i]); 607 } 608 } 609 } 610 611 void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) 612 { 613 s->dbdma = dbdma; 614 DBDMA_register_channel(dbdma, channel, s->dma_irq, 615 pmac_ide_transfer, pmac_ide_flush, s); 616 } 617 618 type_init(macio_ide_register_types) 619