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