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 "hw/hw.h" 40 #include "hw/isa/isa.h" 41 #include "hw/ppc/mac_dbdma.h" 42 #include "qemu/main-loop.h" 43 44 /* debug DBDMA */ 45 //#define DEBUG_DBDMA 46 47 #ifdef DEBUG_DBDMA 48 #define DBDMA_DPRINTF(fmt, ...) \ 49 do { printf("DBDMA: " fmt , ## __VA_ARGS__); } while (0) 50 #else 51 #define DBDMA_DPRINTF(fmt, ...) 52 #endif 53 54 /* 55 */ 56 57 /* 58 * DBDMA control/status registers. All little-endian. 59 */ 60 61 #define DBDMA_CONTROL 0x00 62 #define DBDMA_STATUS 0x01 63 #define DBDMA_CMDPTR_HI 0x02 64 #define DBDMA_CMDPTR_LO 0x03 65 #define DBDMA_INTR_SEL 0x04 66 #define DBDMA_BRANCH_SEL 0x05 67 #define DBDMA_WAIT_SEL 0x06 68 #define DBDMA_XFER_MODE 0x07 69 #define DBDMA_DATA2PTR_HI 0x08 70 #define DBDMA_DATA2PTR_LO 0x09 71 #define DBDMA_RES1 0x0A 72 #define DBDMA_ADDRESS_HI 0x0B 73 #define DBDMA_BRANCH_ADDR_HI 0x0C 74 #define DBDMA_RES2 0x0D 75 #define DBDMA_RES3 0x0E 76 #define DBDMA_RES4 0x0F 77 78 #define DBDMA_REGS 16 79 #define DBDMA_SIZE (DBDMA_REGS * sizeof(uint32_t)) 80 81 #define DBDMA_CHANNEL_SHIFT 7 82 #define DBDMA_CHANNEL_SIZE (1 << DBDMA_CHANNEL_SHIFT) 83 84 #define DBDMA_CHANNELS (0x1000 >> DBDMA_CHANNEL_SHIFT) 85 86 /* Bits in control and status registers */ 87 88 #define RUN 0x8000 89 #define PAUSE 0x4000 90 #define FLUSH 0x2000 91 #define WAKE 0x1000 92 #define DEAD 0x0800 93 #define ACTIVE 0x0400 94 #define BT 0x0100 95 #define DEVSTAT 0x00ff 96 97 /* 98 * DBDMA command structure. These fields are all little-endian! 99 */ 100 101 typedef struct dbdma_cmd { 102 uint16_t req_count; /* requested byte transfer count */ 103 uint16_t command; /* command word (has bit-fields) */ 104 uint32_t phy_addr; /* physical data address */ 105 uint32_t cmd_dep; /* command-dependent field */ 106 uint16_t res_count; /* residual count after completion */ 107 uint16_t xfer_status; /* transfer status */ 108 } dbdma_cmd; 109 110 /* DBDMA command values in command field */ 111 112 #define COMMAND_MASK 0xf000 113 #define OUTPUT_MORE 0x0000 /* transfer memory data to stream */ 114 #define OUTPUT_LAST 0x1000 /* ditto followed by end marker */ 115 #define INPUT_MORE 0x2000 /* transfer stream data to memory */ 116 #define INPUT_LAST 0x3000 /* ditto, expect end marker */ 117 #define STORE_WORD 0x4000 /* write word (4 bytes) to device reg */ 118 #define LOAD_WORD 0x5000 /* read word (4 bytes) from device reg */ 119 #define DBDMA_NOP 0x6000 /* do nothing */ 120 #define DBDMA_STOP 0x7000 /* suspend processing */ 121 122 /* Key values in command field */ 123 124 #define KEY_MASK 0x0700 125 #define KEY_STREAM0 0x0000 /* usual data stream */ 126 #define KEY_STREAM1 0x0100 /* control/status stream */ 127 #define KEY_STREAM2 0x0200 /* device-dependent stream */ 128 #define KEY_STREAM3 0x0300 /* device-dependent stream */ 129 #define KEY_STREAM4 0x0400 /* reserved */ 130 #define KEY_REGS 0x0500 /* device register space */ 131 #define KEY_SYSTEM 0x0600 /* system memory-mapped space */ 132 #define KEY_DEVICE 0x0700 /* device memory-mapped space */ 133 134 /* Interrupt control values in command field */ 135 136 #define INTR_MASK 0x0030 137 #define INTR_NEVER 0x0000 /* don't interrupt */ 138 #define INTR_IFSET 0x0010 /* intr if condition bit is 1 */ 139 #define INTR_IFCLR 0x0020 /* intr if condition bit is 0 */ 140 #define INTR_ALWAYS 0x0030 /* always interrupt */ 141 142 /* Branch control values in command field */ 143 144 #define BR_MASK 0x000c 145 #define BR_NEVER 0x0000 /* don't branch */ 146 #define BR_IFSET 0x0004 /* branch if condition bit is 1 */ 147 #define BR_IFCLR 0x0008 /* branch if condition bit is 0 */ 148 #define BR_ALWAYS 0x000c /* always branch */ 149 150 /* Wait control values in command field */ 151 152 #define WAIT_MASK 0x0003 153 #define WAIT_NEVER 0x0000 /* don't wait */ 154 #define WAIT_IFSET 0x0001 /* wait if condition bit is 1 */ 155 #define WAIT_IFCLR 0x0002 /* wait if condition bit is 0 */ 156 #define WAIT_ALWAYS 0x0003 /* always wait */ 157 158 typedef struct DBDMA_channel { 159 int channel; 160 uint32_t regs[DBDMA_REGS]; 161 qemu_irq irq; 162 DBDMA_io io; 163 DBDMA_rw rw; 164 DBDMA_flush flush; 165 dbdma_cmd current; 166 int processing; 167 } DBDMA_channel; 168 169 typedef struct { 170 MemoryRegion mem; 171 DBDMA_channel channels[DBDMA_CHANNELS]; 172 } DBDMAState; 173 174 #ifdef DEBUG_DBDMA 175 static void dump_dbdma_cmd(dbdma_cmd *cmd) 176 { 177 printf("dbdma_cmd %p\n", cmd); 178 printf(" req_count 0x%04x\n", le16_to_cpu(cmd->req_count)); 179 printf(" command 0x%04x\n", le16_to_cpu(cmd->command)); 180 printf(" phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr)); 181 printf(" cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep)); 182 printf(" res_count 0x%04x\n", le16_to_cpu(cmd->res_count)); 183 printf(" xfer_status 0x%04x\n", le16_to_cpu(cmd->xfer_status)); 184 } 185 #else 186 static void dump_dbdma_cmd(dbdma_cmd *cmd) 187 { 188 } 189 #endif 190 static void dbdma_cmdptr_load(DBDMA_channel *ch) 191 { 192 DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n", 193 ch->regs[DBDMA_CMDPTR_LO]); 194 cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO], 195 &ch->current, sizeof(dbdma_cmd)); 196 } 197 198 static void dbdma_cmdptr_save(DBDMA_channel *ch) 199 { 200 DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n", 201 ch->regs[DBDMA_CMDPTR_LO]); 202 DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n", 203 le16_to_cpu(ch->current.xfer_status), 204 le16_to_cpu(ch->current.res_count)); 205 cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO], 206 &ch->current, sizeof(dbdma_cmd)); 207 } 208 209 static void kill_channel(DBDMA_channel *ch) 210 { 211 DBDMA_DPRINTF("kill_channel\n"); 212 213 ch->regs[DBDMA_STATUS] |= DEAD; 214 ch->regs[DBDMA_STATUS] &= ~ACTIVE; 215 216 qemu_irq_raise(ch->irq); 217 } 218 219 static void conditional_interrupt(DBDMA_channel *ch) 220 { 221 dbdma_cmd *current = &ch->current; 222 uint16_t intr; 223 uint16_t sel_mask, sel_value; 224 uint32_t status; 225 int cond; 226 227 DBDMA_DPRINTF("%s\n", __func__); 228 229 intr = le16_to_cpu(current->command) & INTR_MASK; 230 231 switch(intr) { 232 case INTR_NEVER: /* don't interrupt */ 233 return; 234 case INTR_ALWAYS: /* always interrupt */ 235 qemu_irq_raise(ch->irq); 236 DBDMA_DPRINTF("%s: raise\n", __func__); 237 return; 238 } 239 240 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 241 242 sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f; 243 sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f; 244 245 cond = (status & sel_mask) == (sel_value & sel_mask); 246 247 switch(intr) { 248 case INTR_IFSET: /* intr if condition bit is 1 */ 249 if (cond) { 250 qemu_irq_raise(ch->irq); 251 DBDMA_DPRINTF("%s: raise\n", __func__); 252 } 253 return; 254 case INTR_IFCLR: /* intr if condition bit is 0 */ 255 if (!cond) { 256 qemu_irq_raise(ch->irq); 257 DBDMA_DPRINTF("%s: raise\n", __func__); 258 } 259 return; 260 } 261 } 262 263 static int conditional_wait(DBDMA_channel *ch) 264 { 265 dbdma_cmd *current = &ch->current; 266 uint16_t wait; 267 uint16_t sel_mask, sel_value; 268 uint32_t status; 269 int cond; 270 271 DBDMA_DPRINTF("conditional_wait\n"); 272 273 wait = le16_to_cpu(current->command) & WAIT_MASK; 274 275 switch(wait) { 276 case WAIT_NEVER: /* don't wait */ 277 return 0; 278 case WAIT_ALWAYS: /* always wait */ 279 return 1; 280 } 281 282 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 283 284 sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f; 285 sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f; 286 287 cond = (status & sel_mask) == (sel_value & sel_mask); 288 289 switch(wait) { 290 case WAIT_IFSET: /* wait if condition bit is 1 */ 291 if (cond) 292 return 1; 293 return 0; 294 case WAIT_IFCLR: /* wait if condition bit is 0 */ 295 if (!cond) 296 return 1; 297 return 0; 298 } 299 return 0; 300 } 301 302 static void next(DBDMA_channel *ch) 303 { 304 uint32_t cp; 305 306 ch->regs[DBDMA_STATUS] &= ~BT; 307 308 cp = ch->regs[DBDMA_CMDPTR_LO]; 309 ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd); 310 dbdma_cmdptr_load(ch); 311 } 312 313 static void branch(DBDMA_channel *ch) 314 { 315 dbdma_cmd *current = &ch->current; 316 317 ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep; 318 ch->regs[DBDMA_STATUS] |= BT; 319 dbdma_cmdptr_load(ch); 320 } 321 322 static void conditional_branch(DBDMA_channel *ch) 323 { 324 dbdma_cmd *current = &ch->current; 325 uint16_t br; 326 uint16_t sel_mask, sel_value; 327 uint32_t status; 328 int cond; 329 330 DBDMA_DPRINTF("conditional_branch\n"); 331 332 /* check if we must branch */ 333 334 br = le16_to_cpu(current->command) & BR_MASK; 335 336 switch(br) { 337 case BR_NEVER: /* don't branch */ 338 next(ch); 339 return; 340 case BR_ALWAYS: /* always branch */ 341 branch(ch); 342 return; 343 } 344 345 status = ch->regs[DBDMA_STATUS] & DEVSTAT; 346 347 sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f; 348 sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f; 349 350 cond = (status & sel_mask) == (sel_value & sel_mask); 351 352 switch(br) { 353 case BR_IFSET: /* branch if condition bit is 1 */ 354 if (cond) 355 branch(ch); 356 else 357 next(ch); 358 return; 359 case BR_IFCLR: /* branch if condition bit is 0 */ 360 if (!cond) 361 branch(ch); 362 else 363 next(ch); 364 return; 365 } 366 } 367 368 static QEMUBH *dbdma_bh; 369 static void channel_run(DBDMA_channel *ch); 370 371 static void dbdma_end(DBDMA_io *io) 372 { 373 DBDMA_channel *ch = io->channel; 374 dbdma_cmd *current = &ch->current; 375 376 DBDMA_DPRINTF("%s\n", __func__); 377 378 if (conditional_wait(ch)) 379 goto wait; 380 381 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 382 current->res_count = cpu_to_le16(io->len); 383 dbdma_cmdptr_save(ch); 384 if (io->is_last) 385 ch->regs[DBDMA_STATUS] &= ~FLUSH; 386 387 conditional_interrupt(ch); 388 conditional_branch(ch); 389 390 wait: 391 ch->processing = 0; 392 if ((ch->regs[DBDMA_STATUS] & RUN) && 393 (ch->regs[DBDMA_STATUS] & ACTIVE)) 394 channel_run(ch); 395 } 396 397 static void start_output(DBDMA_channel *ch, int key, uint32_t addr, 398 uint16_t req_count, int is_last) 399 { 400 DBDMA_DPRINTF("start_output\n"); 401 402 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 403 * are not implemented in the mac-io chip 404 */ 405 406 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key); 407 if (!addr || key > KEY_STREAM3) { 408 kill_channel(ch); 409 return; 410 } 411 412 ch->io.addr = addr; 413 ch->io.len = req_count; 414 ch->io.is_last = is_last; 415 ch->io.dma_end = dbdma_end; 416 ch->io.is_dma_out = 1; 417 ch->processing = 1; 418 if (ch->rw) { 419 ch->rw(&ch->io); 420 } 421 } 422 423 static void start_input(DBDMA_channel *ch, int key, uint32_t addr, 424 uint16_t req_count, int is_last) 425 { 426 DBDMA_DPRINTF("start_input\n"); 427 428 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 429 * are not implemented in the mac-io chip 430 */ 431 432 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key); 433 if (!addr || key > KEY_STREAM3) { 434 kill_channel(ch); 435 return; 436 } 437 438 ch->io.addr = addr; 439 ch->io.len = req_count; 440 ch->io.is_last = is_last; 441 ch->io.dma_end = dbdma_end; 442 ch->io.is_dma_out = 0; 443 ch->processing = 1; 444 if (ch->rw) { 445 ch->rw(&ch->io); 446 } 447 } 448 449 static void load_word(DBDMA_channel *ch, int key, uint32_t addr, 450 uint16_t len) 451 { 452 dbdma_cmd *current = &ch->current; 453 uint32_t val; 454 455 DBDMA_DPRINTF("load_word\n"); 456 457 /* only implements KEY_SYSTEM */ 458 459 if (key != KEY_SYSTEM) { 460 printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key); 461 kill_channel(ch); 462 return; 463 } 464 465 cpu_physical_memory_read(addr, &val, len); 466 467 if (len == 2) 468 val = (val << 16) | (current->cmd_dep & 0x0000ffff); 469 else if (len == 1) 470 val = (val << 24) | (current->cmd_dep & 0x00ffffff); 471 472 current->cmd_dep = val; 473 474 if (conditional_wait(ch)) 475 goto wait; 476 477 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 478 dbdma_cmdptr_save(ch); 479 ch->regs[DBDMA_STATUS] &= ~FLUSH; 480 481 conditional_interrupt(ch); 482 next(ch); 483 484 wait: 485 qemu_bh_schedule(dbdma_bh); 486 } 487 488 static void store_word(DBDMA_channel *ch, int key, uint32_t addr, 489 uint16_t len) 490 { 491 dbdma_cmd *current = &ch->current; 492 uint32_t val; 493 494 DBDMA_DPRINTF("store_word\n"); 495 496 /* only implements KEY_SYSTEM */ 497 498 if (key != KEY_SYSTEM) { 499 printf("DBDMA: STORE_WORD, unimplemented key %x\n", key); 500 kill_channel(ch); 501 return; 502 } 503 504 val = current->cmd_dep; 505 if (len == 2) 506 val >>= 16; 507 else if (len == 1) 508 val >>= 24; 509 510 cpu_physical_memory_write(addr, &val, len); 511 512 if (conditional_wait(ch)) 513 goto wait; 514 515 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 516 dbdma_cmdptr_save(ch); 517 ch->regs[DBDMA_STATUS] &= ~FLUSH; 518 519 conditional_interrupt(ch); 520 next(ch); 521 522 wait: 523 qemu_bh_schedule(dbdma_bh); 524 } 525 526 static void nop(DBDMA_channel *ch) 527 { 528 dbdma_cmd *current = &ch->current; 529 530 if (conditional_wait(ch)) 531 goto wait; 532 533 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]); 534 dbdma_cmdptr_save(ch); 535 536 conditional_interrupt(ch); 537 conditional_branch(ch); 538 539 wait: 540 qemu_bh_schedule(dbdma_bh); 541 } 542 543 static void stop(DBDMA_channel *ch) 544 { 545 ch->regs[DBDMA_STATUS] &= ~(ACTIVE|DEAD|FLUSH); 546 547 /* the stop command does not increment command pointer */ 548 } 549 550 static void channel_run(DBDMA_channel *ch) 551 { 552 dbdma_cmd *current = &ch->current; 553 uint16_t cmd, key; 554 uint16_t req_count; 555 uint32_t phy_addr; 556 557 DBDMA_DPRINTF("channel_run\n"); 558 dump_dbdma_cmd(current); 559 560 /* clear WAKE flag at command fetch */ 561 562 ch->regs[DBDMA_STATUS] &= ~WAKE; 563 564 cmd = le16_to_cpu(current->command) & COMMAND_MASK; 565 566 switch (cmd) { 567 case DBDMA_NOP: 568 nop(ch); 569 return; 570 571 case DBDMA_STOP: 572 stop(ch); 573 return; 574 } 575 576 key = le16_to_cpu(current->command) & 0x0700; 577 req_count = le16_to_cpu(current->req_count); 578 phy_addr = le32_to_cpu(current->phy_addr); 579 580 if (key == KEY_STREAM4) { 581 printf("command %x, invalid key 4\n", cmd); 582 kill_channel(ch); 583 return; 584 } 585 586 switch (cmd) { 587 case OUTPUT_MORE: 588 start_output(ch, key, phy_addr, req_count, 0); 589 return; 590 591 case OUTPUT_LAST: 592 start_output(ch, key, phy_addr, req_count, 1); 593 return; 594 595 case INPUT_MORE: 596 start_input(ch, key, phy_addr, req_count, 0); 597 return; 598 599 case INPUT_LAST: 600 start_input(ch, key, phy_addr, req_count, 1); 601 return; 602 } 603 604 if (key < KEY_REGS) { 605 printf("command %x, invalid key %x\n", cmd, key); 606 key = KEY_SYSTEM; 607 } 608 609 /* for LOAD_WORD and STORE_WORD, req_count is on 3 bits 610 * and BRANCH is invalid 611 */ 612 613 req_count = req_count & 0x0007; 614 if (req_count & 0x4) { 615 req_count = 4; 616 phy_addr &= ~3; 617 } else if (req_count & 0x2) { 618 req_count = 2; 619 phy_addr &= ~1; 620 } else 621 req_count = 1; 622 623 switch (cmd) { 624 case LOAD_WORD: 625 load_word(ch, key, phy_addr, req_count); 626 return; 627 628 case STORE_WORD: 629 store_word(ch, key, phy_addr, req_count); 630 return; 631 } 632 } 633 634 static void DBDMA_run(DBDMAState *s) 635 { 636 int channel; 637 638 for (channel = 0; channel < DBDMA_CHANNELS; channel++) { 639 DBDMA_channel *ch = &s->channels[channel]; 640 uint32_t status = ch->regs[DBDMA_STATUS]; 641 if (!ch->processing && (status & RUN) && (status & ACTIVE)) { 642 channel_run(ch); 643 } 644 } 645 } 646 647 static void DBDMA_run_bh(void *opaque) 648 { 649 DBDMAState *s = opaque; 650 651 DBDMA_DPRINTF("DBDMA_run_bh\n"); 652 653 DBDMA_run(s); 654 } 655 656 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, 657 DBDMA_rw rw, DBDMA_flush flush, 658 void *opaque) 659 { 660 DBDMAState *s = dbdma; 661 DBDMA_channel *ch = &s->channels[nchan]; 662 663 DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan); 664 665 ch->irq = irq; 666 ch->channel = nchan; 667 ch->rw = rw; 668 ch->flush = flush; 669 ch->io.opaque = opaque; 670 ch->io.channel = ch; 671 } 672 673 static void 674 dbdma_control_write(DBDMA_channel *ch) 675 { 676 uint16_t mask, value; 677 uint32_t status; 678 679 mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff; 680 value = ch->regs[DBDMA_CONTROL] & 0xffff; 681 682 value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT); 683 684 status = ch->regs[DBDMA_STATUS]; 685 686 status = (value & mask) | (status & ~mask); 687 688 if (status & WAKE) 689 status |= ACTIVE; 690 if (status & RUN) { 691 status |= ACTIVE; 692 status &= ~DEAD; 693 } 694 if (status & PAUSE) 695 status &= ~ACTIVE; 696 if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) { 697 /* RUN is cleared */ 698 status &= ~(ACTIVE|DEAD); 699 if ((status & FLUSH) && ch->flush) { 700 ch->flush(&ch->io); 701 status &= ~FLUSH; 702 } 703 } 704 705 DBDMA_DPRINTF(" status 0x%08x\n", status); 706 707 ch->regs[DBDMA_STATUS] = status; 708 709 if (status & ACTIVE) 710 qemu_bh_schedule(dbdma_bh); 711 if ((status & FLUSH) && ch->flush) 712 ch->flush(&ch->io); 713 } 714 715 static void dbdma_write(void *opaque, hwaddr addr, 716 uint64_t value, unsigned size) 717 { 718 int channel = addr >> DBDMA_CHANNEL_SHIFT; 719 DBDMAState *s = opaque; 720 DBDMA_channel *ch = &s->channels[channel]; 721 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; 722 723 DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n", 724 addr, value); 725 DBDMA_DPRINTF("channel 0x%x reg 0x%x\n", 726 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); 727 728 /* cmdptr cannot be modified if channel is RUN or ACTIVE */ 729 730 if (reg == DBDMA_CMDPTR_LO && 731 (ch->regs[DBDMA_STATUS] & (RUN | ACTIVE))) 732 return; 733 734 ch->regs[reg] = value; 735 736 switch(reg) { 737 case DBDMA_CONTROL: 738 dbdma_control_write(ch); 739 break; 740 case DBDMA_CMDPTR_LO: 741 /* 16-byte aligned */ 742 ch->regs[DBDMA_CMDPTR_LO] &= ~0xf; 743 dbdma_cmdptr_load(ch); 744 break; 745 case DBDMA_STATUS: 746 case DBDMA_INTR_SEL: 747 case DBDMA_BRANCH_SEL: 748 case DBDMA_WAIT_SEL: 749 /* nothing to do */ 750 break; 751 case DBDMA_XFER_MODE: 752 case DBDMA_CMDPTR_HI: 753 case DBDMA_DATA2PTR_HI: 754 case DBDMA_DATA2PTR_LO: 755 case DBDMA_ADDRESS_HI: 756 case DBDMA_BRANCH_ADDR_HI: 757 case DBDMA_RES1: 758 case DBDMA_RES2: 759 case DBDMA_RES3: 760 case DBDMA_RES4: 761 /* unused */ 762 break; 763 } 764 } 765 766 static uint64_t dbdma_read(void *opaque, hwaddr addr, 767 unsigned size) 768 { 769 uint32_t value; 770 int channel = addr >> DBDMA_CHANNEL_SHIFT; 771 DBDMAState *s = opaque; 772 DBDMA_channel *ch = &s->channels[channel]; 773 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; 774 775 value = ch->regs[reg]; 776 777 DBDMA_DPRINTF("readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value); 778 DBDMA_DPRINTF("channel 0x%x reg 0x%x\n", 779 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); 780 781 switch(reg) { 782 case DBDMA_CONTROL: 783 value = 0; 784 break; 785 case DBDMA_STATUS: 786 case DBDMA_CMDPTR_LO: 787 case DBDMA_INTR_SEL: 788 case DBDMA_BRANCH_SEL: 789 case DBDMA_WAIT_SEL: 790 /* nothing to do */ 791 break; 792 case DBDMA_XFER_MODE: 793 case DBDMA_CMDPTR_HI: 794 case DBDMA_DATA2PTR_HI: 795 case DBDMA_DATA2PTR_LO: 796 case DBDMA_ADDRESS_HI: 797 case DBDMA_BRANCH_ADDR_HI: 798 /* unused */ 799 value = 0; 800 break; 801 case DBDMA_RES1: 802 case DBDMA_RES2: 803 case DBDMA_RES3: 804 case DBDMA_RES4: 805 /* reserved */ 806 break; 807 } 808 809 return value; 810 } 811 812 static const MemoryRegionOps dbdma_ops = { 813 .read = dbdma_read, 814 .write = dbdma_write, 815 .endianness = DEVICE_LITTLE_ENDIAN, 816 .valid = { 817 .min_access_size = 4, 818 .max_access_size = 4, 819 }, 820 }; 821 822 static const VMStateDescription vmstate_dbdma_channel = { 823 .name = "dbdma_channel", 824 .version_id = 0, 825 .minimum_version_id = 0, 826 .minimum_version_id_old = 0, 827 .fields = (VMStateField[]) { 828 VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS), 829 VMSTATE_END_OF_LIST() 830 } 831 }; 832 833 static const VMStateDescription vmstate_dbdma = { 834 .name = "dbdma", 835 .version_id = 2, 836 .minimum_version_id = 2, 837 .minimum_version_id_old = 2, 838 .fields = (VMStateField[]) { 839 VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1, 840 vmstate_dbdma_channel, DBDMA_channel), 841 VMSTATE_END_OF_LIST() 842 } 843 }; 844 845 static void dbdma_reset(void *opaque) 846 { 847 DBDMAState *s = opaque; 848 int i; 849 850 for (i = 0; i < DBDMA_CHANNELS; i++) 851 memset(s->channels[i].regs, 0, DBDMA_SIZE); 852 } 853 854 void* DBDMA_init (MemoryRegion **dbdma_mem) 855 { 856 DBDMAState *s; 857 858 s = g_malloc0(sizeof(DBDMAState)); 859 860 memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000); 861 *dbdma_mem = &s->mem; 862 vmstate_register(NULL, -1, &vmstate_dbdma, s); 863 qemu_register_reset(dbdma_reset, s); 864 865 dbdma_bh = qemu_bh_new(DBDMA_run_bh, s); 866 867 return s; 868 } 869