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 %#lx\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 sector_num: %ld\n", 216 io->remainder_len, io->len, s->nsector, sector_num); 217 if (io->remainder_len && io->len) { 218 /* guest wants the rest of its previous transfer */ 219 int remainder_len = MIN(io->remainder_len, io->len); 220 uint8_t *p = &io->remainder[0x200 - remainder_len]; 221 222 MACIO_DPRINTF("copying remainder %d bytes at %#lx\n", 223 remainder_len, io->addr); 224 225 switch (s->dma_cmd) { 226 case IDE_DMA_READ: 227 cpu_physical_memory_write(io->addr, p, remainder_len); 228 break; 229 case IDE_DMA_WRITE: 230 cpu_physical_memory_read(io->addr, p, remainder_len); 231 bdrv_write(s->bs, sector_num - 1, io->remainder, 1); 232 break; 233 case IDE_DMA_TRIM: 234 break; 235 } 236 io->addr += remainder_len; 237 io->len -= remainder_len; 238 io->remainder_len -= remainder_len; 239 } 240 241 if (s->nsector == 0 && !io->remainder_len) { 242 MACIO_DPRINTF("end of transfer\n"); 243 s->status = READY_STAT | SEEK_STAT; 244 ide_set_irq(s->bus); 245 m->dma_active = false; 246 } 247 248 if (io->len == 0) { 249 MACIO_DPRINTF("end of DMA\n"); 250 goto done; 251 } 252 253 /* launch next transfer */ 254 255 s->io_buffer_index = 0; 256 s->io_buffer_size = MIN(io->len, s->nsector * 512); 257 258 /* handle unaligned accesses first, get them over with and only do the 259 remaining bulk transfer using our async DMA helpers */ 260 unaligned = io->len & 0x1ff; 261 if (unaligned) { 262 int nsector = io->len >> 9; 263 264 MACIO_DPRINTF("precopying unaligned %d bytes to %#lx\n", 265 unaligned, io->addr + io->len - unaligned); 266 267 switch (s->dma_cmd) { 268 case IDE_DMA_READ: 269 bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); 270 cpu_physical_memory_write(io->addr + io->len - unaligned, 271 io->remainder, unaligned); 272 break; 273 case IDE_DMA_WRITE: 274 /* cache the contents in our io struct */ 275 cpu_physical_memory_read(io->addr + io->len - unaligned, 276 io->remainder, unaligned); 277 break; 278 case IDE_DMA_TRIM: 279 break; 280 } 281 282 io->len -= unaligned; 283 } 284 285 MACIO_DPRINTF("io->len = %#x\n", io->len); 286 287 qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, 288 &address_space_memory); 289 qemu_sglist_add(&s->sg, io->addr, io->len); 290 io->addr += io->len + unaligned; 291 io->remainder_len = (0x200 - unaligned) & 0x1ff; 292 MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len); 293 294 /* We would read no data from the block layer, thus not get a callback. 295 Just fake completion manually. */ 296 if (!io->len) { 297 pmac_ide_transfer_cb(opaque, 0); 298 return; 299 } 300 301 io->len = 0; 302 303 MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n", 304 sector_num, n, s->nsector, s->dma_cmd); 305 306 switch (s->dma_cmd) { 307 case IDE_DMA_READ: 308 m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, 309 pmac_ide_transfer_cb, io); 310 break; 311 case IDE_DMA_WRITE: 312 m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, 313 pmac_ide_transfer_cb, io); 314 break; 315 case IDE_DMA_TRIM: 316 m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, 317 ide_issue_trim, pmac_ide_transfer_cb, io, 318 DMA_DIRECTION_TO_DEVICE); 319 break; 320 } 321 return; 322 323 done: 324 if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { 325 bdrv_acct_done(s->bs, &s->acct); 326 } 327 io->dma_end(io); 328 } 329 330 static void pmac_ide_transfer(DBDMA_io *io) 331 { 332 MACIOIDEState *m = io->opaque; 333 IDEState *s = idebus_active_if(&m->bus); 334 335 MACIO_DPRINTF("\n"); 336 337 s->io_buffer_size = 0; 338 if (s->drive_kind == IDE_CD) { 339 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 340 pmac_ide_atapi_transfer_cb(io, 0); 341 return; 342 } 343 344 switch (s->dma_cmd) { 345 case IDE_DMA_READ: 346 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); 347 break; 348 case IDE_DMA_WRITE: 349 bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); 350 break; 351 default: 352 break; 353 } 354 355 pmac_ide_transfer_cb(io, 0); 356 } 357 358 static void pmac_ide_flush(DBDMA_io *io) 359 { 360 MACIOIDEState *m = io->opaque; 361 362 if (m->aiocb) { 363 bdrv_drain_all(); 364 } 365 } 366 367 /* PowerMac IDE memory IO */ 368 static void pmac_ide_writeb (void *opaque, 369 hwaddr addr, uint32_t val) 370 { 371 MACIOIDEState *d = opaque; 372 373 addr = (addr & 0xFFF) >> 4; 374 switch (addr) { 375 case 1 ... 7: 376 ide_ioport_write(&d->bus, addr, val); 377 break; 378 case 8: 379 case 22: 380 ide_cmd_write(&d->bus, 0, val); 381 break; 382 default: 383 break; 384 } 385 } 386 387 static uint32_t pmac_ide_readb (void *opaque,hwaddr addr) 388 { 389 uint8_t retval; 390 MACIOIDEState *d = opaque; 391 392 addr = (addr & 0xFFF) >> 4; 393 switch (addr) { 394 case 1 ... 7: 395 retval = ide_ioport_read(&d->bus, addr); 396 break; 397 case 8: 398 case 22: 399 retval = ide_status_read(&d->bus, 0); 400 break; 401 default: 402 retval = 0xFF; 403 break; 404 } 405 return retval; 406 } 407 408 static void pmac_ide_writew (void *opaque, 409 hwaddr addr, uint32_t val) 410 { 411 MACIOIDEState *d = opaque; 412 413 addr = (addr & 0xFFF) >> 4; 414 val = bswap16(val); 415 if (addr == 0) { 416 ide_data_writew(&d->bus, 0, val); 417 } 418 } 419 420 static uint32_t pmac_ide_readw (void *opaque,hwaddr addr) 421 { 422 uint16_t retval; 423 MACIOIDEState *d = opaque; 424 425 addr = (addr & 0xFFF) >> 4; 426 if (addr == 0) { 427 retval = ide_data_readw(&d->bus, 0); 428 } else { 429 retval = 0xFFFF; 430 } 431 retval = bswap16(retval); 432 return retval; 433 } 434 435 static void pmac_ide_writel (void *opaque, 436 hwaddr addr, uint32_t val) 437 { 438 MACIOIDEState *d = opaque; 439 440 addr = (addr & 0xFFF) >> 4; 441 val = bswap32(val); 442 if (addr == 0) { 443 ide_data_writel(&d->bus, 0, val); 444 } 445 } 446 447 static uint32_t pmac_ide_readl (void *opaque,hwaddr addr) 448 { 449 uint32_t retval; 450 MACIOIDEState *d = opaque; 451 452 addr = (addr & 0xFFF) >> 4; 453 if (addr == 0) { 454 retval = ide_data_readl(&d->bus, 0); 455 } else { 456 retval = 0xFFFFFFFF; 457 } 458 retval = bswap32(retval); 459 return retval; 460 } 461 462 static const MemoryRegionOps pmac_ide_ops = { 463 .old_mmio = { 464 .write = { 465 pmac_ide_writeb, 466 pmac_ide_writew, 467 pmac_ide_writel, 468 }, 469 .read = { 470 pmac_ide_readb, 471 pmac_ide_readw, 472 pmac_ide_readl, 473 }, 474 }, 475 .endianness = DEVICE_NATIVE_ENDIAN, 476 }; 477 478 static const VMStateDescription vmstate_pmac = { 479 .name = "ide", 480 .version_id = 3, 481 .minimum_version_id = 0, 482 .minimum_version_id_old = 0, 483 .fields = (VMStateField []) { 484 VMSTATE_IDE_BUS(bus, MACIOIDEState), 485 VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState), 486 VMSTATE_END_OF_LIST() 487 } 488 }; 489 490 static void macio_ide_reset(DeviceState *dev) 491 { 492 MACIOIDEState *d = MACIO_IDE(dev); 493 494 ide_bus_reset(&d->bus); 495 } 496 497 static int ide_nop(IDEDMA *dma) 498 { 499 return 0; 500 } 501 502 static int ide_nop_int(IDEDMA *dma, int x) 503 { 504 return 0; 505 } 506 507 static void ide_nop_restart(void *opaque, int x, RunState y) 508 { 509 } 510 511 static void ide_dbdma_start(IDEDMA *dma, IDEState *s, 512 BlockDriverCompletionFunc *cb) 513 { 514 MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); 515 516 MACIO_DPRINTF("\n"); 517 m->dma_active = true; 518 DBDMA_kick(m->dbdma); 519 } 520 521 static const IDEDMAOps dbdma_ops = { 522 .start_dma = ide_dbdma_start, 523 .start_transfer = ide_nop, 524 .prepare_buf = ide_nop_int, 525 .rw_buf = ide_nop_int, 526 .set_unit = ide_nop_int, 527 .add_status = ide_nop_int, 528 .set_inactive = ide_nop, 529 .restart_cb = ide_nop_restart, 530 .reset = ide_nop, 531 }; 532 533 static void macio_ide_realizefn(DeviceState *dev, Error **errp) 534 { 535 MACIOIDEState *s = MACIO_IDE(dev); 536 537 ide_init2(&s->bus, s->irq); 538 539 /* Register DMA callbacks */ 540 s->dma.ops = &dbdma_ops; 541 s->bus.dma = &s->dma; 542 } 543 544 static void macio_ide_initfn(Object *obj) 545 { 546 SysBusDevice *d = SYS_BUS_DEVICE(obj); 547 MACIOIDEState *s = MACIO_IDE(obj); 548 549 ide_bus_new(&s->bus, DEVICE(obj), 0, 2); 550 memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000); 551 sysbus_init_mmio(d, &s->mem); 552 sysbus_init_irq(d, &s->irq); 553 sysbus_init_irq(d, &s->dma_irq); 554 } 555 556 static void macio_ide_class_init(ObjectClass *oc, void *data) 557 { 558 DeviceClass *dc = DEVICE_CLASS(oc); 559 560 dc->realize = macio_ide_realizefn; 561 dc->reset = macio_ide_reset; 562 dc->vmsd = &vmstate_pmac; 563 } 564 565 static const TypeInfo macio_ide_type_info = { 566 .name = TYPE_MACIO_IDE, 567 .parent = TYPE_SYS_BUS_DEVICE, 568 .instance_size = sizeof(MACIOIDEState), 569 .instance_init = macio_ide_initfn, 570 .class_init = macio_ide_class_init, 571 }; 572 573 static void macio_ide_register_types(void) 574 { 575 type_register_static(&macio_ide_type_info); 576 } 577 578 /* hd_table must contain 2 block drivers */ 579 void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) 580 { 581 int i; 582 583 for (i = 0; i < 2; i++) { 584 if (hd_table[i]) { 585 ide_create_drive(&s->bus, i, hd_table[i]); 586 } 587 } 588 } 589 590 void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) 591 { 592 s->dbdma = dbdma; 593 DBDMA_register_channel(dbdma, channel, s->dma_irq, 594 pmac_ide_transfer, pmac_ide_flush, s); 595 } 596 597 type_init(macio_ide_register_types) 598