1 /* 2 * PowerMac descriptor-based DMA emulation 3 * 4 * Copyright (c) 2005-2007 Fabrice Bellard 5 * Copyright (c) 2007 Jocelyn Mayer 6 * Copyright (c) 2009 Laurent Vivier 7 * 8 * some parts from linux-2.6.28, arch/powerpc/include/asm/dbdma.h 9 * 10 * Definitions for using the Apple Descriptor-Based DMA controller 11 * in Power Macintosh computers. 12 * 13 * Copyright (C) 1996 Paul Mackerras. 14 * 15 * some parts from mol 0.9.71 16 * 17 * Descriptor based DMA emulation 18 * 19 * Copyright (C) 1998-2004 Samuel Rydh (samuel@ibrium.se) 20 * 21 * Permission is hereby granted, free of charge, to any person obtaining a copy 22 * of this software and associated documentation files (the "Software"), to deal 23 * in the Software without restriction, including without limitation the rights 24 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 * copies of the Software, and to permit persons to whom the Software is 26 * furnished to do so, subject to the following conditions: 27 * 28 * The above copyright notice and this permission notice shall be included in 29 * all copies or substantial portions of the Software. 30 * 31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 34 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 * THE SOFTWARE. 38 */ 39 40 #include "qemu/osdep.h" 41 #include "hw/hw.h" 42 #include "hw/ppc/mac_dbdma.h" 43 #include "qemu/main-loop.h" 44 #include "qemu/module.h" 45 #include "qemu/log.h" 46 #include "sysemu/dma.h" 47 48 /* debug DBDMA */ 49 #define DEBUG_DBDMA 0 50 #define DEBUG_DBDMA_CHANMASK ((1ull << DBDMA_CHANNELS) - 1) 51 52 #define DBDMA_DPRINTF(fmt, ...) do { \ 53 if (DEBUG_DBDMA) { \ 54 printf("DBDMA: " fmt , ## __VA_ARGS__); \ 55 } \ 56 } while (0) 57 58 #define DBDMA_DPRINTFCH(ch, fmt, ...) do { \ 59 if (DEBUG_DBDMA) { \ 60 if ((1ul << (ch)->channel) & DEBUG_DBDMA_CHANMASK) { \ 61 printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \ 62 } \ 63 } \ 64 } while (0) 65 66 /* 67 */ 68 69 static DBDMAState *dbdma_from_ch(DBDMA_channel *ch) 70 { 71 return container_of(ch, DBDMAState, channels[ch->channel]); 72 } 73 74 #if DEBUG_DBDMA 75 static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd) 76 { 77 DBDMA_DPRINTFCH(ch, "dbdma_cmd %p\n", cmd); 78 DBDMA_DPRINTFCH(ch, " req_count 0x%04x\n", le16_to_cpu(cmd->req_count)); 79 DBDMA_DPRINTFCH(ch, " command 0x%04x\n", le16_to_cpu(cmd->command)); 80 DBDMA_DPRINTFCH(ch, " phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr)); 81 DBDMA_DPRINTFCH(ch, " cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep)); 82 DBDMA_DPRINTFCH(ch, " res_count 0x%04x\n", le16_to_cpu(cmd->res_count)); 83 DBDMA_DPRINTFCH(ch, " xfer_status 0x%04x\n", 84 le16_to_cpu(cmd->xfer_status)); 85 } 86 #else 87 static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd) 88 { 89 } 90 #endif 91 static void dbdma_cmdptr_load(DBDMA_channel *ch) 92 { 93 DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n", 94 ch->regs[DBDMA_CMDPTR_LO]); 95 dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], 96 &ch->current, sizeof(dbdma_cmd)); 97 } 98 99 static void dbdma_cmdptr_save(DBDMA_channel *ch) 100 { 101 DBDMA_DPRINTFCH(ch, "-> update 0x%08x stat=0x%08x, res=0x%04x\n", 102 ch->regs[DBDMA_CMDPTR_LO], 103 le16_to_cpu(ch->current.xfer_status), 104 le16_to_cpu(ch->current.res_count)); 105 dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], 106 &ch->current, sizeof(dbdma_cmd)); 107 } 108 109 static void kill_channel(DBDMA_channel *ch) 110 { 111 DBDMA_DPRINTFCH(ch, "kill_channel\n"); 112 113 ch->regs[DBDMA_STATUS] |= DEAD; 114 ch->regs[DBDMA_STATUS] &= ~ACTIVE; 115 116 qemu_irq_raise(ch->irq); 117 } 118 119 static void conditional_interrupt(DBDMA_channel *ch) 120 { 121 dbdma_cmd *current = &ch->current; 122 uint16_t intr; 123 uint16_t sel_mask, sel_value; 124 uint32_t status; 125 int cond; 126 127 DBDMA_DPRINTFCH(ch, "%s\n", __func__); 128 129 intr = le16_to_cpu(current->command) & INTR_MASK; 130 131 switch(intr) { 132 case INTR_NEVER: /* don't interrupt */ 133 return; 134 case INTR_ALWAYS: /* always interrupt */ 135 qemu_irq_raise(ch->irq); 136 DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__); 137 return; 138 } 139 140 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 141 142 sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f; 143 sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f; 144 145 cond = (status & sel_mask) == (sel_value & sel_mask); 146 147 switch(intr) { 148 case INTR_IFSET: /* intr if condition bit is 1 */ 149 if (cond) { 150 qemu_irq_raise(ch->irq); 151 DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__); 152 } 153 return; 154 case INTR_IFCLR: /* intr if condition bit is 0 */ 155 if (!cond) { 156 qemu_irq_raise(ch->irq); 157 DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__); 158 } 159 return; 160 } 161 } 162 163 static int conditional_wait(DBDMA_channel *ch) 164 { 165 dbdma_cmd *current = &ch->current; 166 uint16_t wait; 167 uint16_t sel_mask, sel_value; 168 uint32_t status; 169 int cond; 170 int res = 0; 171 172 wait = le16_to_cpu(current->command) & WAIT_MASK; 173 switch(wait) { 174 case WAIT_NEVER: /* don't wait */ 175 return 0; 176 case WAIT_ALWAYS: /* always wait */ 177 DBDMA_DPRINTFCH(ch, " [WAIT_ALWAYS]\n"); 178 return 1; 179 } 180 181 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 182 183 sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f; 184 sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f; 185 186 cond = (status & sel_mask) == (sel_value & sel_mask); 187 188 switch(wait) { 189 case WAIT_IFSET: /* wait if condition bit is 1 */ 190 if (cond) { 191 res = 1; 192 } 193 DBDMA_DPRINTFCH(ch, " [WAIT_IFSET=%d]\n", res); 194 break; 195 case WAIT_IFCLR: /* wait if condition bit is 0 */ 196 if (!cond) { 197 res = 1; 198 } 199 DBDMA_DPRINTFCH(ch, " [WAIT_IFCLR=%d]\n", res); 200 break; 201 } 202 return res; 203 } 204 205 static void next(DBDMA_channel *ch) 206 { 207 uint32_t cp; 208 209 ch->regs[DBDMA_STATUS] &= ~BT; 210 211 cp = ch->regs[DBDMA_CMDPTR_LO]; 212 ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd); 213 dbdma_cmdptr_load(ch); 214 } 215 216 static void branch(DBDMA_channel *ch) 217 { 218 dbdma_cmd *current = &ch->current; 219 220 ch->regs[DBDMA_CMDPTR_LO] = le32_to_cpu(current->cmd_dep); 221 ch->regs[DBDMA_STATUS] |= BT; 222 dbdma_cmdptr_load(ch); 223 } 224 225 static void conditional_branch(DBDMA_channel *ch) 226 { 227 dbdma_cmd *current = &ch->current; 228 uint16_t br; 229 uint16_t sel_mask, sel_value; 230 uint32_t status; 231 int cond; 232 233 /* check if we must branch */ 234 235 br = le16_to_cpu(current->command) & BR_MASK; 236 237 switch(br) { 238 case BR_NEVER: /* don't branch */ 239 next(ch); 240 return; 241 case BR_ALWAYS: /* always branch */ 242 DBDMA_DPRINTFCH(ch, " [BR_ALWAYS]\n"); 243 branch(ch); 244 return; 245 } 246 247 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 248 249 sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f; 250 sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f; 251 252 cond = (status & sel_mask) == (sel_value & sel_mask); 253 254 switch(br) { 255 case BR_IFSET: /* branch if condition bit is 1 */ 256 if (cond) { 257 DBDMA_DPRINTFCH(ch, " [BR_IFSET = 1]\n"); 258 branch(ch); 259 } else { 260 DBDMA_DPRINTFCH(ch, " [BR_IFSET = 0]\n"); 261 next(ch); 262 } 263 return; 264 case BR_IFCLR: /* branch if condition bit is 0 */ 265 if (!cond) { 266 DBDMA_DPRINTFCH(ch, " [BR_IFCLR = 1]\n"); 267 branch(ch); 268 } else { 269 DBDMA_DPRINTFCH(ch, " [BR_IFCLR = 0]\n"); 270 next(ch); 271 } 272 return; 273 } 274 } 275 276 static void channel_run(DBDMA_channel *ch); 277 278 static void dbdma_end(DBDMA_io *io) 279 { 280 DBDMA_channel *ch = io->channel; 281 dbdma_cmd *current = &ch->current; 282 283 DBDMA_DPRINTFCH(ch, "%s\n", __func__); 284 285 if (conditional_wait(ch)) 286 goto wait; 287 288 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 289 current->res_count = cpu_to_le16(io->len); 290 dbdma_cmdptr_save(ch); 291 if (io->is_last) 292 ch->regs[DBDMA_STATUS] &= ~FLUSH; 293 294 conditional_interrupt(ch); 295 conditional_branch(ch); 296 297 wait: 298 /* Indicate that we're ready for a new DMA round */ 299 ch->io.processing = false; 300 301 if ((ch->regs[DBDMA_STATUS] & RUN) && 302 (ch->regs[DBDMA_STATUS] & ACTIVE)) 303 channel_run(ch); 304 } 305 306 static void start_output(DBDMA_channel *ch, int key, uint32_t addr, 307 uint16_t req_count, int is_last) 308 { 309 DBDMA_DPRINTFCH(ch, "start_output\n"); 310 311 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 312 * are not implemented in the mac-io chip 313 */ 314 315 DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key); 316 if (!addr || key > KEY_STREAM3) { 317 kill_channel(ch); 318 return; 319 } 320 321 ch->io.addr = addr; 322 ch->io.len = req_count; 323 ch->io.is_last = is_last; 324 ch->io.dma_end = dbdma_end; 325 ch->io.is_dma_out = 1; 326 ch->io.processing = true; 327 if (ch->rw) { 328 ch->rw(&ch->io); 329 } 330 } 331 332 static void start_input(DBDMA_channel *ch, int key, uint32_t addr, 333 uint16_t req_count, int is_last) 334 { 335 DBDMA_DPRINTFCH(ch, "start_input\n"); 336 337 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 338 * are not implemented in the mac-io chip 339 */ 340 341 DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key); 342 if (!addr || key > KEY_STREAM3) { 343 kill_channel(ch); 344 return; 345 } 346 347 ch->io.addr = addr; 348 ch->io.len = req_count; 349 ch->io.is_last = is_last; 350 ch->io.dma_end = dbdma_end; 351 ch->io.is_dma_out = 0; 352 ch->io.processing = true; 353 if (ch->rw) { 354 ch->rw(&ch->io); 355 } 356 } 357 358 static void load_word(DBDMA_channel *ch, int key, uint32_t addr, 359 uint16_t len) 360 { 361 dbdma_cmd *current = &ch->current; 362 363 DBDMA_DPRINTFCH(ch, "load_word %d bytes, addr=%08x\n", len, addr); 364 365 /* only implements KEY_SYSTEM */ 366 367 if (key != KEY_SYSTEM) { 368 printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key); 369 kill_channel(ch); 370 return; 371 } 372 373 dma_memory_read(&address_space_memory, addr, ¤t->cmd_dep, len); 374 375 if (conditional_wait(ch)) 376 goto wait; 377 378 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 379 dbdma_cmdptr_save(ch); 380 ch->regs[DBDMA_STATUS] &= ~FLUSH; 381 382 conditional_interrupt(ch); 383 next(ch); 384 385 wait: 386 DBDMA_kick(dbdma_from_ch(ch)); 387 } 388 389 static void store_word(DBDMA_channel *ch, int key, uint32_t addr, 390 uint16_t len) 391 { 392 dbdma_cmd *current = &ch->current; 393 394 DBDMA_DPRINTFCH(ch, "store_word %d bytes, addr=%08x pa=%x\n", 395 len, addr, le32_to_cpu(current->cmd_dep)); 396 397 /* only implements KEY_SYSTEM */ 398 399 if (key != KEY_SYSTEM) { 400 printf("DBDMA: STORE_WORD, unimplemented key %x\n", key); 401 kill_channel(ch); 402 return; 403 } 404 405 dma_memory_write(&address_space_memory, addr, ¤t->cmd_dep, len); 406 407 if (conditional_wait(ch)) 408 goto wait; 409 410 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 411 dbdma_cmdptr_save(ch); 412 ch->regs[DBDMA_STATUS] &= ~FLUSH; 413 414 conditional_interrupt(ch); 415 next(ch); 416 417 wait: 418 DBDMA_kick(dbdma_from_ch(ch)); 419 } 420 421 static void nop(DBDMA_channel *ch) 422 { 423 dbdma_cmd *current = &ch->current; 424 425 if (conditional_wait(ch)) 426 goto wait; 427 428 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 429 dbdma_cmdptr_save(ch); 430 431 conditional_interrupt(ch); 432 conditional_branch(ch); 433 434 wait: 435 DBDMA_kick(dbdma_from_ch(ch)); 436 } 437 438 static void stop(DBDMA_channel *ch) 439 { 440 ch->regs[DBDMA_STATUS] &= ~(ACTIVE); 441 442 /* the stop command does not increment command pointer */ 443 } 444 445 static void channel_run(DBDMA_channel *ch) 446 { 447 dbdma_cmd *current = &ch->current; 448 uint16_t cmd, key; 449 uint16_t req_count; 450 uint32_t phy_addr; 451 452 DBDMA_DPRINTFCH(ch, "channel_run\n"); 453 dump_dbdma_cmd(ch, current); 454 455 /* clear WAKE flag at command fetch */ 456 457 ch->regs[DBDMA_STATUS] &= ~WAKE; 458 459 cmd = le16_to_cpu(current->command) & COMMAND_MASK; 460 461 switch (cmd) { 462 case DBDMA_NOP: 463 nop(ch); 464 return; 465 466 case DBDMA_STOP: 467 stop(ch); 468 return; 469 } 470 471 key = le16_to_cpu(current->command) & 0x0700; 472 req_count = le16_to_cpu(current->req_count); 473 phy_addr = le32_to_cpu(current->phy_addr); 474 475 if (key == KEY_STREAM4) { 476 printf("command %x, invalid key 4\n", cmd); 477 kill_channel(ch); 478 return; 479 } 480 481 switch (cmd) { 482 case OUTPUT_MORE: 483 DBDMA_DPRINTFCH(ch, "* OUTPUT_MORE *\n"); 484 start_output(ch, key, phy_addr, req_count, 0); 485 return; 486 487 case OUTPUT_LAST: 488 DBDMA_DPRINTFCH(ch, "* OUTPUT_LAST *\n"); 489 start_output(ch, key, phy_addr, req_count, 1); 490 return; 491 492 case INPUT_MORE: 493 DBDMA_DPRINTFCH(ch, "* INPUT_MORE *\n"); 494 start_input(ch, key, phy_addr, req_count, 0); 495 return; 496 497 case INPUT_LAST: 498 DBDMA_DPRINTFCH(ch, "* INPUT_LAST *\n"); 499 start_input(ch, key, phy_addr, req_count, 1); 500 return; 501 } 502 503 if (key < KEY_REGS) { 504 printf("command %x, invalid key %x\n", cmd, key); 505 key = KEY_SYSTEM; 506 } 507 508 /* for LOAD_WORD and STORE_WORD, req_count is on 3 bits 509 * and BRANCH is invalid 510 */ 511 512 req_count = req_count & 0x0007; 513 if (req_count & 0x4) { 514 req_count = 4; 515 phy_addr &= ~3; 516 } else if (req_count & 0x2) { 517 req_count = 2; 518 phy_addr &= ~1; 519 } else 520 req_count = 1; 521 522 switch (cmd) { 523 case LOAD_WORD: 524 DBDMA_DPRINTFCH(ch, "* LOAD_WORD *\n"); 525 load_word(ch, key, phy_addr, req_count); 526 return; 527 528 case STORE_WORD: 529 DBDMA_DPRINTFCH(ch, "* STORE_WORD *\n"); 530 store_word(ch, key, phy_addr, req_count); 531 return; 532 } 533 } 534 535 static void DBDMA_run(DBDMAState *s) 536 { 537 int channel; 538 539 for (channel = 0; channel < DBDMA_CHANNELS; channel++) { 540 DBDMA_channel *ch = &s->channels[channel]; 541 uint32_t status = ch->regs[DBDMA_STATUS]; 542 if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) { 543 channel_run(ch); 544 } 545 } 546 } 547 548 static void DBDMA_run_bh(void *opaque) 549 { 550 DBDMAState *s = opaque; 551 552 DBDMA_DPRINTF("-> DBDMA_run_bh\n"); 553 DBDMA_run(s); 554 DBDMA_DPRINTF("<- DBDMA_run_bh\n"); 555 } 556 557 void DBDMA_kick(DBDMAState *dbdma) 558 { 559 qemu_bh_schedule(dbdma->bh); 560 } 561 562 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, 563 DBDMA_rw rw, DBDMA_flush flush, 564 void *opaque) 565 { 566 DBDMAState *s = dbdma; 567 DBDMA_channel *ch = &s->channels[nchan]; 568 569 DBDMA_DPRINTFCH(ch, "DBDMA_register_channel 0x%x\n", nchan); 570 571 assert(rw); 572 assert(flush); 573 574 ch->irq = irq; 575 ch->rw = rw; 576 ch->flush = flush; 577 ch->io.opaque = opaque; 578 } 579 580 static void dbdma_control_write(DBDMA_channel *ch) 581 { 582 uint16_t mask, value; 583 uint32_t status; 584 bool do_flush = false; 585 586 mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff; 587 value = ch->regs[DBDMA_CONTROL] & 0xffff; 588 589 /* This is the status register which we'll update 590 * appropriately and store back 591 */ 592 status = ch->regs[DBDMA_STATUS]; 593 594 /* RUN and PAUSE are bits under SW control only 595 * FLUSH and WAKE are set by SW and cleared by HW 596 * DEAD, ACTIVE and BT are only under HW control 597 * 598 * We handle ACTIVE separately at the end of the 599 * logic to ensure all cases are covered. 600 */ 601 602 /* Setting RUN will tentatively activate the channel 603 */ 604 if ((mask & RUN) && (value & RUN)) { 605 status |= RUN; 606 DBDMA_DPRINTFCH(ch, " Setting RUN !\n"); 607 } 608 609 /* Clearing RUN 1->0 will stop the channel */ 610 if ((mask & RUN) && !(value & RUN)) { 611 /* This has the side effect of clearing the DEAD bit */ 612 status &= ~(DEAD | RUN); 613 DBDMA_DPRINTFCH(ch, " Clearing RUN !\n"); 614 } 615 616 /* Setting WAKE wakes up an idle channel if it's running 617 * 618 * Note: The doc doesn't say so but assume that only works 619 * on a channel whose RUN bit is set. 620 * 621 * We set WAKE in status, it's not terribly useful as it will 622 * be cleared on the next command fetch but it seems to mimmic 623 * the HW behaviour and is useful for the way we handle 624 * ACTIVE further down. 625 */ 626 if ((mask & WAKE) && (value & WAKE) && (status & RUN)) { 627 status |= WAKE; 628 DBDMA_DPRINTFCH(ch, " Setting WAKE !\n"); 629 } 630 631 /* PAUSE being set will deactivate (or prevent activation) 632 * of the channel. We just copy it over for now, ACTIVE will 633 * be re-evaluated later. 634 */ 635 if (mask & PAUSE) { 636 status = (status & ~PAUSE) | (value & PAUSE); 637 DBDMA_DPRINTFCH(ch, " %sing PAUSE !\n", 638 (value & PAUSE) ? "sett" : "clear"); 639 } 640 641 /* FLUSH is its own thing */ 642 if ((mask & FLUSH) && (value & FLUSH)) { 643 DBDMA_DPRINTFCH(ch, " Setting FLUSH !\n"); 644 /* We set flush directly in the status register, we do *NOT* 645 * set it in "status" so that it gets naturally cleared when 646 * we update the status register further down. That way it 647 * will be set only during the HW flush operation so it is 648 * visible to any completions happening during that time. 649 */ 650 ch->regs[DBDMA_STATUS] |= FLUSH; 651 do_flush = true; 652 } 653 654 /* If either RUN or PAUSE is clear, so should ACTIVE be, 655 * otherwise, ACTIVE will be set if we modified RUN, PAUSE or 656 * set WAKE. That means that PAUSE was just cleared, RUN was 657 * just set or WAKE was just set. 658 */ 659 if ((status & PAUSE) || !(status & RUN)) { 660 status &= ~ACTIVE; 661 DBDMA_DPRINTFCH(ch, " -> ACTIVE down !\n"); 662 663 /* We stopped processing, we want the underlying HW command 664 * to complete *before* we clear the ACTIVE bit. Otherwise 665 * we can get into a situation where the command status will 666 * have RUN or ACTIVE not set which is going to confuse the 667 * MacOS driver. 668 */ 669 do_flush = true; 670 } else if (mask & (RUN | PAUSE)) { 671 status |= ACTIVE; 672 DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n"); 673 } else if ((mask & WAKE) && (value & WAKE)) { 674 status |= ACTIVE; 675 DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n"); 676 } 677 678 DBDMA_DPRINTFCH(ch, " new status=0x%08x\n", status); 679 680 /* If we need to flush the underlying HW, do it now, this happens 681 * both on FLUSH commands and when stopping the channel for safety. 682 */ 683 if (do_flush && ch->flush) { 684 ch->flush(&ch->io); 685 } 686 687 /* Finally update the status register image */ 688 ch->regs[DBDMA_STATUS] = status; 689 690 /* If active, make sure the BH gets to run */ 691 if (status & ACTIVE) { 692 DBDMA_kick(dbdma_from_ch(ch)); 693 } 694 } 695 696 static void dbdma_write(void *opaque, hwaddr addr, 697 uint64_t value, unsigned size) 698 { 699 int channel = addr >> DBDMA_CHANNEL_SHIFT; 700 DBDMAState *s = opaque; 701 DBDMA_channel *ch = &s->channels[channel]; 702 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; 703 704 DBDMA_DPRINTFCH(ch, "writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n", 705 addr, value); 706 DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n", 707 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); 708 709 /* cmdptr cannot be modified if channel is ACTIVE */ 710 711 if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) { 712 return; 713 } 714 715 ch->regs[reg] = value; 716 717 switch(reg) { 718 case DBDMA_CONTROL: 719 dbdma_control_write(ch); 720 break; 721 case DBDMA_CMDPTR_LO: 722 /* 16-byte aligned */ 723 ch->regs[DBDMA_CMDPTR_LO] &= ~0xf; 724 dbdma_cmdptr_load(ch); 725 break; 726 case DBDMA_STATUS: 727 case DBDMA_INTR_SEL: 728 case DBDMA_BRANCH_SEL: 729 case DBDMA_WAIT_SEL: 730 /* nothing to do */ 731 break; 732 case DBDMA_XFER_MODE: 733 case DBDMA_CMDPTR_HI: 734 case DBDMA_DATA2PTR_HI: 735 case DBDMA_DATA2PTR_LO: 736 case DBDMA_ADDRESS_HI: 737 case DBDMA_BRANCH_ADDR_HI: 738 case DBDMA_RES1: 739 case DBDMA_RES2: 740 case DBDMA_RES3: 741 case DBDMA_RES4: 742 /* unused */ 743 break; 744 } 745 } 746 747 static uint64_t dbdma_read(void *opaque, hwaddr addr, 748 unsigned size) 749 { 750 uint32_t value; 751 int channel = addr >> DBDMA_CHANNEL_SHIFT; 752 DBDMAState *s = opaque; 753 DBDMA_channel *ch = &s->channels[channel]; 754 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; 755 756 value = ch->regs[reg]; 757 758 switch(reg) { 759 case DBDMA_CONTROL: 760 value = ch->regs[DBDMA_STATUS]; 761 break; 762 case DBDMA_STATUS: 763 case DBDMA_CMDPTR_LO: 764 case DBDMA_INTR_SEL: 765 case DBDMA_BRANCH_SEL: 766 case DBDMA_WAIT_SEL: 767 /* nothing to do */ 768 break; 769 case DBDMA_XFER_MODE: 770 case DBDMA_CMDPTR_HI: 771 case DBDMA_DATA2PTR_HI: 772 case DBDMA_DATA2PTR_LO: 773 case DBDMA_ADDRESS_HI: 774 case DBDMA_BRANCH_ADDR_HI: 775 /* unused */ 776 value = 0; 777 break; 778 case DBDMA_RES1: 779 case DBDMA_RES2: 780 case DBDMA_RES3: 781 case DBDMA_RES4: 782 /* reserved */ 783 break; 784 } 785 786 DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value); 787 DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n", 788 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); 789 790 return value; 791 } 792 793 static const MemoryRegionOps dbdma_ops = { 794 .read = dbdma_read, 795 .write = dbdma_write, 796 .endianness = DEVICE_LITTLE_ENDIAN, 797 .valid = { 798 .min_access_size = 4, 799 .max_access_size = 4, 800 }, 801 }; 802 803 static const VMStateDescription vmstate_dbdma_io = { 804 .name = "dbdma_io", 805 .version_id = 0, 806 .minimum_version_id = 0, 807 .fields = (VMStateField[]) { 808 VMSTATE_UINT64(addr, struct DBDMA_io), 809 VMSTATE_INT32(len, struct DBDMA_io), 810 VMSTATE_INT32(is_last, struct DBDMA_io), 811 VMSTATE_INT32(is_dma_out, struct DBDMA_io), 812 VMSTATE_BOOL(processing, struct DBDMA_io), 813 VMSTATE_END_OF_LIST() 814 } 815 }; 816 817 static const VMStateDescription vmstate_dbdma_cmd = { 818 .name = "dbdma_cmd", 819 .version_id = 0, 820 .minimum_version_id = 0, 821 .fields = (VMStateField[]) { 822 VMSTATE_UINT16(req_count, dbdma_cmd), 823 VMSTATE_UINT16(command, dbdma_cmd), 824 VMSTATE_UINT32(phy_addr, dbdma_cmd), 825 VMSTATE_UINT32(cmd_dep, dbdma_cmd), 826 VMSTATE_UINT16(res_count, dbdma_cmd), 827 VMSTATE_UINT16(xfer_status, dbdma_cmd), 828 VMSTATE_END_OF_LIST() 829 } 830 }; 831 832 static const VMStateDescription vmstate_dbdma_channel = { 833 .name = "dbdma_channel", 834 .version_id = 1, 835 .minimum_version_id = 1, 836 .fields = (VMStateField[]) { 837 VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS), 838 VMSTATE_STRUCT(io, struct DBDMA_channel, 0, vmstate_dbdma_io, DBDMA_io), 839 VMSTATE_STRUCT(current, struct DBDMA_channel, 0, vmstate_dbdma_cmd, 840 dbdma_cmd), 841 VMSTATE_END_OF_LIST() 842 } 843 }; 844 845 static const VMStateDescription vmstate_dbdma = { 846 .name = "dbdma", 847 .version_id = 3, 848 .minimum_version_id = 3, 849 .fields = (VMStateField[]) { 850 VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1, 851 vmstate_dbdma_channel, DBDMA_channel), 852 VMSTATE_END_OF_LIST() 853 } 854 }; 855 856 static void mac_dbdma_reset(DeviceState *d) 857 { 858 DBDMAState *s = MAC_DBDMA(d); 859 int i; 860 861 for (i = 0; i < DBDMA_CHANNELS; i++) { 862 memset(s->channels[i].regs, 0, DBDMA_SIZE); 863 } 864 } 865 866 static void dbdma_unassigned_rw(DBDMA_io *io) 867 { 868 DBDMA_channel *ch = io->channel; 869 dbdma_cmd *current = &ch->current; 870 uint16_t cmd; 871 qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n", 872 __func__, ch->channel); 873 ch->io.processing = false; 874 875 cmd = le16_to_cpu(current->command) & COMMAND_MASK; 876 if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST || 877 cmd == INPUT_MORE || cmd == INPUT_LAST) { 878 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 879 current->res_count = cpu_to_le16(io->len); 880 dbdma_cmdptr_save(ch); 881 } 882 } 883 884 static void dbdma_unassigned_flush(DBDMA_io *io) 885 { 886 DBDMA_channel *ch = io->channel; 887 qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n", 888 __func__, ch->channel); 889 } 890 891 static void mac_dbdma_init(Object *obj) 892 { 893 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 894 DBDMAState *s = MAC_DBDMA(obj); 895 int i; 896 897 for (i = 0; i < DBDMA_CHANNELS; i++) { 898 DBDMA_channel *ch = &s->channels[i]; 899 900 ch->rw = dbdma_unassigned_rw; 901 ch->flush = dbdma_unassigned_flush; 902 ch->channel = i; 903 ch->io.channel = ch; 904 } 905 906 memory_region_init_io(&s->mem, obj, &dbdma_ops, s, "dbdma", 0x1000); 907 sysbus_init_mmio(sbd, &s->mem); 908 } 909 910 static void mac_dbdma_realize(DeviceState *dev, Error **errp) 911 { 912 DBDMAState *s = MAC_DBDMA(dev); 913 914 s->bh = qemu_bh_new(DBDMA_run_bh, s); 915 } 916 917 static void mac_dbdma_class_init(ObjectClass *oc, void *data) 918 { 919 DeviceClass *dc = DEVICE_CLASS(oc); 920 921 dc->realize = mac_dbdma_realize; 922 dc->reset = mac_dbdma_reset; 923 dc->vmsd = &vmstate_dbdma; 924 } 925 926 static const TypeInfo mac_dbdma_type_info = { 927 .name = TYPE_MAC_DBDMA, 928 .parent = TYPE_SYS_BUS_DEVICE, 929 .instance_size = sizeof(DBDMAState), 930 .instance_init = mac_dbdma_init, 931 .class_init = mac_dbdma_class_init 932 }; 933 934 static void mac_dbdma_register_types(void) 935 { 936 type_register_static(&mac_dbdma_type_info); 937 } 938 939 type_init(mac_dbdma_register_types) 940