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