1 /* 2 * QEMU JAZZ RC4030 chipset 3 * 4 * Copyright (c) 2007-2009 Herve Poussineau 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "hw/hw.h" 26 #include "hw/mips/mips.h" 27 #include "qemu/timer.h" 28 29 /********************************************************/ 30 /* debug rc4030 */ 31 32 //#define DEBUG_RC4030 33 //#define DEBUG_RC4030_DMA 34 35 #ifdef DEBUG_RC4030 36 #define DPRINTF(fmt, ...) \ 37 do { printf("rc4030: " fmt , ## __VA_ARGS__); } while (0) 38 static const char* irq_names[] = { "parallel", "floppy", "sound", "video", 39 "network", "scsi", "keyboard", "mouse", "serial0", "serial1" }; 40 #else 41 #define DPRINTF(fmt, ...) 42 #endif 43 44 #define RC4030_ERROR(fmt, ...) \ 45 do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) 46 47 /********************************************************/ 48 /* rc4030 emulation */ 49 50 typedef struct dma_pagetable_entry { 51 int32_t frame; 52 int32_t owner; 53 } QEMU_PACKED dma_pagetable_entry; 54 55 #define DMA_PAGESIZE 4096 56 #define DMA_REG_ENABLE 1 57 #define DMA_REG_COUNT 2 58 #define DMA_REG_ADDRESS 3 59 60 #define DMA_FLAG_ENABLE 0x0001 61 #define DMA_FLAG_MEM_TO_DEV 0x0002 62 #define DMA_FLAG_TC_INTR 0x0100 63 #define DMA_FLAG_MEM_INTR 0x0200 64 #define DMA_FLAG_ADDR_INTR 0x0400 65 66 typedef struct rc4030State 67 { 68 uint32_t config; /* 0x0000: RC4030 config register */ 69 uint32_t revision; /* 0x0008: RC4030 Revision register */ 70 uint32_t invalid_address_register; /* 0x0010: Invalid Address register */ 71 72 /* DMA */ 73 uint32_t dma_regs[8][4]; 74 uint32_t dma_tl_base; /* 0x0018: DMA transl. table base */ 75 uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */ 76 77 /* cache */ 78 uint32_t cache_maint; /* 0x0030: Cache Maintenance */ 79 uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */ 80 uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */ 81 uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */ 82 uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */ 83 uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */ 84 85 uint32_t nmi_interrupt; /* 0x0200: interrupt source */ 86 uint32_t offset210; 87 uint32_t nvram_protect; /* 0x0220: NV ram protect register */ 88 uint32_t rem_speed[16]; 89 uint32_t imr_jazz; /* Local bus int enable mask */ 90 uint32_t isr_jazz; /* Local bus int source */ 91 92 /* timer */ 93 QEMUTimer *periodic_timer; 94 uint32_t itr; /* Interval timer reload */ 95 96 qemu_irq timer_irq; 97 qemu_irq jazz_bus_irq; 98 99 MemoryRegion iomem_chipset; 100 MemoryRegion iomem_jazzio; 101 } rc4030State; 102 103 static void set_next_tick(rc4030State *s) 104 { 105 qemu_irq_lower(s->timer_irq); 106 uint32_t tm_hz; 107 108 tm_hz = 1000 / (s->itr + 1); 109 110 timer_mod(s->periodic_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 111 get_ticks_per_sec() / tm_hz); 112 } 113 114 /* called for accesses to rc4030 */ 115 static uint32_t rc4030_readl(void *opaque, hwaddr addr) 116 { 117 rc4030State *s = opaque; 118 uint32_t val; 119 120 addr &= 0x3fff; 121 switch (addr & ~0x3) { 122 /* Global config register */ 123 case 0x0000: 124 val = s->config; 125 break; 126 /* Revision register */ 127 case 0x0008: 128 val = s->revision; 129 break; 130 /* Invalid Address register */ 131 case 0x0010: 132 val = s->invalid_address_register; 133 break; 134 /* DMA transl. table base */ 135 case 0x0018: 136 val = s->dma_tl_base; 137 break; 138 /* DMA transl. table limit */ 139 case 0x0020: 140 val = s->dma_tl_limit; 141 break; 142 /* Remote Failed Address */ 143 case 0x0038: 144 val = s->remote_failed_address; 145 break; 146 /* Memory Failed Address */ 147 case 0x0040: 148 val = s->memory_failed_address; 149 break; 150 /* I/O Cache Byte Mask */ 151 case 0x0058: 152 val = s->cache_bmask; 153 /* HACK */ 154 if (s->cache_bmask == (uint32_t)-1) 155 s->cache_bmask = 0; 156 break; 157 /* Remote Speed Registers */ 158 case 0x0070: 159 case 0x0078: 160 case 0x0080: 161 case 0x0088: 162 case 0x0090: 163 case 0x0098: 164 case 0x00a0: 165 case 0x00a8: 166 case 0x00b0: 167 case 0x00b8: 168 case 0x00c0: 169 case 0x00c8: 170 case 0x00d0: 171 case 0x00d8: 172 case 0x00e0: 173 case 0x00e8: 174 val = s->rem_speed[(addr - 0x0070) >> 3]; 175 break; 176 /* DMA channel base address */ 177 case 0x0100: 178 case 0x0108: 179 case 0x0110: 180 case 0x0118: 181 case 0x0120: 182 case 0x0128: 183 case 0x0130: 184 case 0x0138: 185 case 0x0140: 186 case 0x0148: 187 case 0x0150: 188 case 0x0158: 189 case 0x0160: 190 case 0x0168: 191 case 0x0170: 192 case 0x0178: 193 case 0x0180: 194 case 0x0188: 195 case 0x0190: 196 case 0x0198: 197 case 0x01a0: 198 case 0x01a8: 199 case 0x01b0: 200 case 0x01b8: 201 case 0x01c0: 202 case 0x01c8: 203 case 0x01d0: 204 case 0x01d8: 205 case 0x01e0: 206 case 0x01e8: 207 case 0x01f0: 208 case 0x01f8: 209 { 210 int entry = (addr - 0x0100) >> 5; 211 int idx = (addr & 0x1f) >> 3; 212 val = s->dma_regs[entry][idx]; 213 } 214 break; 215 /* Interrupt source */ 216 case 0x0200: 217 val = s->nmi_interrupt; 218 break; 219 /* Error type */ 220 case 0x0208: 221 val = 0; 222 break; 223 /* Offset 0x0210 */ 224 case 0x0210: 225 val = s->offset210; 226 break; 227 /* NV ram protect register */ 228 case 0x0220: 229 val = s->nvram_protect; 230 break; 231 /* Interval timer count */ 232 case 0x0230: 233 val = 0; 234 qemu_irq_lower(s->timer_irq); 235 break; 236 /* EISA interrupt */ 237 case 0x0238: 238 val = 7; /* FIXME: should be read from EISA controller */ 239 break; 240 default: 241 RC4030_ERROR("invalid read [" TARGET_FMT_plx "]\n", addr); 242 val = 0; 243 break; 244 } 245 246 if ((addr & ~3) != 0x230) { 247 DPRINTF("read 0x%02x at " TARGET_FMT_plx "\n", val, addr); 248 } 249 250 return val; 251 } 252 253 static uint32_t rc4030_readw(void *opaque, hwaddr addr) 254 { 255 uint32_t v = rc4030_readl(opaque, addr & ~0x3); 256 if (addr & 0x2) 257 return v >> 16; 258 else 259 return v & 0xffff; 260 } 261 262 static uint32_t rc4030_readb(void *opaque, hwaddr addr) 263 { 264 uint32_t v = rc4030_readl(opaque, addr & ~0x3); 265 return (v >> (8 * (addr & 0x3))) & 0xff; 266 } 267 268 static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val) 269 { 270 rc4030State *s = opaque; 271 addr &= 0x3fff; 272 273 DPRINTF("write 0x%02x at " TARGET_FMT_plx "\n", val, addr); 274 275 switch (addr & ~0x3) { 276 /* Global config register */ 277 case 0x0000: 278 s->config = val; 279 break; 280 /* DMA transl. table base */ 281 case 0x0018: 282 s->dma_tl_base = val; 283 break; 284 /* DMA transl. table limit */ 285 case 0x0020: 286 s->dma_tl_limit = val; 287 break; 288 /* DMA transl. table invalidated */ 289 case 0x0028: 290 break; 291 /* Cache Maintenance */ 292 case 0x0030: 293 s->cache_maint = val; 294 break; 295 /* I/O Cache Physical Tag */ 296 case 0x0048: 297 s->cache_ptag = val; 298 break; 299 /* I/O Cache Logical Tag */ 300 case 0x0050: 301 s->cache_ltag = val; 302 break; 303 /* I/O Cache Byte Mask */ 304 case 0x0058: 305 s->cache_bmask |= val; /* HACK */ 306 break; 307 /* I/O Cache Buffer Window */ 308 case 0x0060: 309 /* HACK */ 310 if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) { 311 hwaddr dest = s->cache_ptag & ~0x1; 312 dest += (s->cache_maint & 0x3) << 3; 313 cpu_physical_memory_write(dest, &val, 4); 314 } 315 break; 316 /* Remote Speed Registers */ 317 case 0x0070: 318 case 0x0078: 319 case 0x0080: 320 case 0x0088: 321 case 0x0090: 322 case 0x0098: 323 case 0x00a0: 324 case 0x00a8: 325 case 0x00b0: 326 case 0x00b8: 327 case 0x00c0: 328 case 0x00c8: 329 case 0x00d0: 330 case 0x00d8: 331 case 0x00e0: 332 case 0x00e8: 333 s->rem_speed[(addr - 0x0070) >> 3] = val; 334 break; 335 /* DMA channel base address */ 336 case 0x0100: 337 case 0x0108: 338 case 0x0110: 339 case 0x0118: 340 case 0x0120: 341 case 0x0128: 342 case 0x0130: 343 case 0x0138: 344 case 0x0140: 345 case 0x0148: 346 case 0x0150: 347 case 0x0158: 348 case 0x0160: 349 case 0x0168: 350 case 0x0170: 351 case 0x0178: 352 case 0x0180: 353 case 0x0188: 354 case 0x0190: 355 case 0x0198: 356 case 0x01a0: 357 case 0x01a8: 358 case 0x01b0: 359 case 0x01b8: 360 case 0x01c0: 361 case 0x01c8: 362 case 0x01d0: 363 case 0x01d8: 364 case 0x01e0: 365 case 0x01e8: 366 case 0x01f0: 367 case 0x01f8: 368 { 369 int entry = (addr - 0x0100) >> 5; 370 int idx = (addr & 0x1f) >> 3; 371 s->dma_regs[entry][idx] = val; 372 } 373 break; 374 /* Offset 0x0210 */ 375 case 0x0210: 376 s->offset210 = val; 377 break; 378 /* Interval timer reload */ 379 case 0x0228: 380 s->itr = val; 381 qemu_irq_lower(s->timer_irq); 382 set_next_tick(s); 383 break; 384 /* EISA interrupt */ 385 case 0x0238: 386 break; 387 default: 388 RC4030_ERROR("invalid write of 0x%02x at [" TARGET_FMT_plx "]\n", val, addr); 389 break; 390 } 391 } 392 393 static void rc4030_writew(void *opaque, hwaddr addr, uint32_t val) 394 { 395 uint32_t old_val = rc4030_readl(opaque, addr & ~0x3); 396 397 if (addr & 0x2) 398 val = (val << 16) | (old_val & 0x0000ffff); 399 else 400 val = val | (old_val & 0xffff0000); 401 rc4030_writel(opaque, addr & ~0x3, val); 402 } 403 404 static void rc4030_writeb(void *opaque, hwaddr addr, uint32_t val) 405 { 406 uint32_t old_val = rc4030_readl(opaque, addr & ~0x3); 407 408 switch (addr & 3) { 409 case 0: 410 val = val | (old_val & 0xffffff00); 411 break; 412 case 1: 413 val = (val << 8) | (old_val & 0xffff00ff); 414 break; 415 case 2: 416 val = (val << 16) | (old_val & 0xff00ffff); 417 break; 418 case 3: 419 val = (val << 24) | (old_val & 0x00ffffff); 420 break; 421 } 422 rc4030_writel(opaque, addr & ~0x3, val); 423 } 424 425 static const MemoryRegionOps rc4030_ops = { 426 .old_mmio = { 427 .read = { rc4030_readb, rc4030_readw, rc4030_readl, }, 428 .write = { rc4030_writeb, rc4030_writew, rc4030_writel, }, 429 }, 430 .endianness = DEVICE_NATIVE_ENDIAN, 431 }; 432 433 static void update_jazz_irq(rc4030State *s) 434 { 435 uint16_t pending; 436 437 pending = s->isr_jazz & s->imr_jazz; 438 439 #ifdef DEBUG_RC4030 440 if (s->isr_jazz != 0) { 441 uint32_t irq = 0; 442 DPRINTF("pending irqs:"); 443 for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) { 444 if (s->isr_jazz & (1 << irq)) { 445 printf(" %s", irq_names[irq]); 446 if (!(s->imr_jazz & (1 << irq))) { 447 printf("(ignored)"); 448 } 449 } 450 } 451 printf("\n"); 452 } 453 #endif 454 455 if (pending != 0) 456 qemu_irq_raise(s->jazz_bus_irq); 457 else 458 qemu_irq_lower(s->jazz_bus_irq); 459 } 460 461 static void rc4030_irq_jazz_request(void *opaque, int irq, int level) 462 { 463 rc4030State *s = opaque; 464 465 if (level) { 466 s->isr_jazz |= 1 << irq; 467 } else { 468 s->isr_jazz &= ~(1 << irq); 469 } 470 471 update_jazz_irq(s); 472 } 473 474 static void rc4030_periodic_timer(void *opaque) 475 { 476 rc4030State *s = opaque; 477 478 set_next_tick(s); 479 qemu_irq_raise(s->timer_irq); 480 } 481 482 static uint32_t jazzio_readw(void *opaque, hwaddr addr) 483 { 484 rc4030State *s = opaque; 485 uint32_t val; 486 uint32_t irq; 487 addr &= 0xfff; 488 489 switch (addr) { 490 /* Local bus int source */ 491 case 0x00: { 492 uint32_t pending = s->isr_jazz & s->imr_jazz; 493 val = 0; 494 irq = 0; 495 while (pending) { 496 if (pending & 1) { 497 DPRINTF("returning irq %s\n", irq_names[irq]); 498 val = (irq + 1) << 2; 499 break; 500 } 501 irq++; 502 pending >>= 1; 503 } 504 break; 505 } 506 /* Local bus int enable mask */ 507 case 0x02: 508 val = s->imr_jazz; 509 break; 510 default: 511 RC4030_ERROR("(jazz io controller) invalid read [" TARGET_FMT_plx "]\n", addr); 512 val = 0; 513 } 514 515 DPRINTF("(jazz io controller) read 0x%04x at " TARGET_FMT_plx "\n", val, addr); 516 517 return val; 518 } 519 520 static uint32_t jazzio_readb(void *opaque, hwaddr addr) 521 { 522 uint32_t v; 523 v = jazzio_readw(opaque, addr & ~0x1); 524 return (v >> (8 * (addr & 0x1))) & 0xff; 525 } 526 527 static uint32_t jazzio_readl(void *opaque, hwaddr addr) 528 { 529 uint32_t v; 530 v = jazzio_readw(opaque, addr); 531 v |= jazzio_readw(opaque, addr + 2) << 16; 532 return v; 533 } 534 535 static void jazzio_writew(void *opaque, hwaddr addr, uint32_t val) 536 { 537 rc4030State *s = opaque; 538 addr &= 0xfff; 539 540 DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, addr); 541 542 switch (addr) { 543 /* Local bus int enable mask */ 544 case 0x02: 545 s->imr_jazz = val; 546 update_jazz_irq(s); 547 break; 548 default: 549 RC4030_ERROR("(jazz io controller) invalid write of 0x%04x at [" TARGET_FMT_plx "]\n", val, addr); 550 break; 551 } 552 } 553 554 static void jazzio_writeb(void *opaque, hwaddr addr, uint32_t val) 555 { 556 uint32_t old_val = jazzio_readw(opaque, addr & ~0x1); 557 558 switch (addr & 1) { 559 case 0: 560 val = val | (old_val & 0xff00); 561 break; 562 case 1: 563 val = (val << 8) | (old_val & 0x00ff); 564 break; 565 } 566 jazzio_writew(opaque, addr & ~0x1, val); 567 } 568 569 static void jazzio_writel(void *opaque, hwaddr addr, uint32_t val) 570 { 571 jazzio_writew(opaque, addr, val & 0xffff); 572 jazzio_writew(opaque, addr + 2, (val >> 16) & 0xffff); 573 } 574 575 static const MemoryRegionOps jazzio_ops = { 576 .old_mmio = { 577 .read = { jazzio_readb, jazzio_readw, jazzio_readl, }, 578 .write = { jazzio_writeb, jazzio_writew, jazzio_writel, }, 579 }, 580 .endianness = DEVICE_NATIVE_ENDIAN, 581 }; 582 583 static void rc4030_reset(void *opaque) 584 { 585 rc4030State *s = opaque; 586 int i; 587 588 s->config = 0x410; /* some boards seem to accept 0x104 too */ 589 s->revision = 1; 590 s->invalid_address_register = 0; 591 592 memset(s->dma_regs, 0, sizeof(s->dma_regs)); 593 s->dma_tl_base = s->dma_tl_limit = 0; 594 595 s->remote_failed_address = s->memory_failed_address = 0; 596 s->cache_maint = 0; 597 s->cache_ptag = s->cache_ltag = 0; 598 s->cache_bmask = 0; 599 600 s->offset210 = 0x18186; 601 s->nvram_protect = 7; 602 for (i = 0; i < 15; i++) 603 s->rem_speed[i] = 7; 604 s->imr_jazz = 0x10; /* XXX: required by firmware, but why? */ 605 s->isr_jazz = 0; 606 607 s->itr = 0; 608 609 qemu_irq_lower(s->timer_irq); 610 qemu_irq_lower(s->jazz_bus_irq); 611 } 612 613 static int rc4030_load(QEMUFile *f, void *opaque, int version_id) 614 { 615 rc4030State* s = opaque; 616 int i, j; 617 618 if (version_id != 2) 619 return -EINVAL; 620 621 s->config = qemu_get_be32(f); 622 s->invalid_address_register = qemu_get_be32(f); 623 for (i = 0; i < 8; i++) 624 for (j = 0; j < 4; j++) 625 s->dma_regs[i][j] = qemu_get_be32(f); 626 s->dma_tl_base = qemu_get_be32(f); 627 s->dma_tl_limit = qemu_get_be32(f); 628 s->cache_maint = qemu_get_be32(f); 629 s->remote_failed_address = qemu_get_be32(f); 630 s->memory_failed_address = qemu_get_be32(f); 631 s->cache_ptag = qemu_get_be32(f); 632 s->cache_ltag = qemu_get_be32(f); 633 s->cache_bmask = qemu_get_be32(f); 634 s->offset210 = qemu_get_be32(f); 635 s->nvram_protect = qemu_get_be32(f); 636 for (i = 0; i < 15; i++) 637 s->rem_speed[i] = qemu_get_be32(f); 638 s->imr_jazz = qemu_get_be32(f); 639 s->isr_jazz = qemu_get_be32(f); 640 s->itr = qemu_get_be32(f); 641 642 set_next_tick(s); 643 update_jazz_irq(s); 644 645 return 0; 646 } 647 648 static void rc4030_save(QEMUFile *f, void *opaque) 649 { 650 rc4030State* s = opaque; 651 int i, j; 652 653 qemu_put_be32(f, s->config); 654 qemu_put_be32(f, s->invalid_address_register); 655 for (i = 0; i < 8; i++) 656 for (j = 0; j < 4; j++) 657 qemu_put_be32(f, s->dma_regs[i][j]); 658 qemu_put_be32(f, s->dma_tl_base); 659 qemu_put_be32(f, s->dma_tl_limit); 660 qemu_put_be32(f, s->cache_maint); 661 qemu_put_be32(f, s->remote_failed_address); 662 qemu_put_be32(f, s->memory_failed_address); 663 qemu_put_be32(f, s->cache_ptag); 664 qemu_put_be32(f, s->cache_ltag); 665 qemu_put_be32(f, s->cache_bmask); 666 qemu_put_be32(f, s->offset210); 667 qemu_put_be32(f, s->nvram_protect); 668 for (i = 0; i < 15; i++) 669 qemu_put_be32(f, s->rem_speed[i]); 670 qemu_put_be32(f, s->imr_jazz); 671 qemu_put_be32(f, s->isr_jazz); 672 qemu_put_be32(f, s->itr); 673 } 674 675 void rc4030_dma_memory_rw(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write) 676 { 677 rc4030State *s = opaque; 678 hwaddr entry_addr; 679 hwaddr phys_addr; 680 dma_pagetable_entry entry; 681 int index; 682 int ncpy, i; 683 684 i = 0; 685 for (;;) { 686 if (i == len) { 687 break; 688 } 689 690 ncpy = DMA_PAGESIZE - (addr & (DMA_PAGESIZE - 1)); 691 if (ncpy > len - i) 692 ncpy = len - i; 693 694 /* Get DMA translation table entry */ 695 index = addr / DMA_PAGESIZE; 696 if (index >= s->dma_tl_limit / sizeof(dma_pagetable_entry)) { 697 break; 698 } 699 entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry); 700 /* XXX: not sure. should we really use only lowest bits? */ 701 entry_addr &= 0x7fffffff; 702 cpu_physical_memory_read(entry_addr, &entry, sizeof(entry)); 703 704 /* Read/write data at right place */ 705 phys_addr = entry.frame + (addr & (DMA_PAGESIZE - 1)); 706 cpu_physical_memory_rw(phys_addr, &buf[i], ncpy, is_write); 707 708 i += ncpy; 709 addr += ncpy; 710 } 711 } 712 713 static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write) 714 { 715 rc4030State *s = opaque; 716 hwaddr dma_addr; 717 int dev_to_mem; 718 719 s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR); 720 721 /* Check DMA channel consistency */ 722 dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 1; 723 if (!(s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_ENABLE) || 724 (is_write != dev_to_mem)) { 725 s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR; 726 s->nmi_interrupt |= 1 << n; 727 return; 728 } 729 730 /* Get start address and len */ 731 if (len > s->dma_regs[n][DMA_REG_COUNT]) 732 len = s->dma_regs[n][DMA_REG_COUNT]; 733 dma_addr = s->dma_regs[n][DMA_REG_ADDRESS]; 734 735 /* Read/write data at right place */ 736 rc4030_dma_memory_rw(opaque, dma_addr, buf, len, is_write); 737 738 s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR; 739 s->dma_regs[n][DMA_REG_COUNT] -= len; 740 741 #ifdef DEBUG_RC4030_DMA 742 { 743 int i, j; 744 printf("rc4030 dma: Copying %d bytes %s host %p\n", 745 len, is_write ? "from" : "to", buf); 746 for (i = 0; i < len; i += 16) { 747 int n = 16; 748 if (n > len - i) { 749 n = len - i; 750 } 751 for (j = 0; j < n; j++) 752 printf("%02x ", buf[i + j]); 753 while (j++ < 16) 754 printf(" "); 755 printf("| "); 756 for (j = 0; j < n; j++) 757 printf("%c", isprint(buf[i + j]) ? buf[i + j] : '.'); 758 printf("\n"); 759 } 760 } 761 #endif 762 } 763 764 struct rc4030DMAState { 765 void *opaque; 766 int n; 767 }; 768 769 void rc4030_dma_read(void *dma, uint8_t *buf, int len) 770 { 771 rc4030_dma s = dma; 772 rc4030_do_dma(s->opaque, s->n, buf, len, 0); 773 } 774 775 void rc4030_dma_write(void *dma, uint8_t *buf, int len) 776 { 777 rc4030_dma s = dma; 778 rc4030_do_dma(s->opaque, s->n, buf, len, 1); 779 } 780 781 static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n) 782 { 783 rc4030_dma *s; 784 struct rc4030DMAState *p; 785 int i; 786 787 s = (rc4030_dma *)g_malloc0(sizeof(rc4030_dma) * n); 788 p = (struct rc4030DMAState *)g_malloc0(sizeof(struct rc4030DMAState) * n); 789 for (i = 0; i < n; i++) { 790 p->opaque = opaque; 791 p->n = i; 792 s[i] = p; 793 p++; 794 } 795 return s; 796 } 797 798 void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, 799 qemu_irq **irqs, rc4030_dma **dmas, 800 MemoryRegion *sysmem) 801 { 802 rc4030State *s; 803 804 s = g_malloc0(sizeof(rc4030State)); 805 806 *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16); 807 *dmas = rc4030_allocate_dmas(s, 4); 808 809 s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s); 810 s->timer_irq = timer; 811 s->jazz_bus_irq = jazz_bus; 812 813 qemu_register_reset(rc4030_reset, s); 814 register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s); 815 rc4030_reset(s); 816 817 memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s, 818 "rc4030.chipset", 0x300); 819 memory_region_add_subregion(sysmem, 0x80000000, &s->iomem_chipset); 820 memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s, 821 "rc4030.jazzio", 0x00001000); 822 memory_region_add_subregion(sysmem, 0xf0000000, &s->iomem_jazzio); 823 824 return s; 825 } 826