Revision 9ea0b7a1 hw/rc4030.c

b/hw/rc4030.c
1 1
/*
2 2
 * QEMU JAZZ RC4030 chipset
3 3
 *
4
 * Copyright (c) 2007-2008 Hervé Poussineau
4
 * Copyright (c) 2007-2009 Herve Poussineau
5 5
 *
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
66 66
typedef struct rc4030State
67 67
{
68 68
    uint32_t config; /* 0x0000: RC4030 config register */
69
    uint32_t revision; /* 0x0008: RC4030 Revision register */
69 70
    uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
70 71

  
71 72
    /* DMA */
......
74 75
    uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */
75 76

  
76 77
    /* cache */
78
    uint32_t cache_maint; /* 0x0030: Cache Maintenance */
77 79
    uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */
78 80
    uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */
79 81
    uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */
80 82
    uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */
81 83
    uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
82
    uint32_t cache_bwin; /* 0x0060: I/O Cache Buffer Window */
83 84

  
85
    uint32_t nmi_interrupt; /* 0x0200: interrupt source */
84 86
    uint32_t offset210;
85 87
    uint32_t nvram_protect; /* 0x0220: NV ram protect register */
86
    uint32_t offset238;
87
    uint32_t rem_speed[15];
88
    uint32_t rem_speed[16];
88 89
    uint32_t imr_jazz; /* Local bus int enable mask */
89 90
    uint32_t isr_jazz; /* Local bus int source */
90 91

  
......
118 119
    case 0x0000:
119 120
        val = s->config;
120 121
        break;
122
    /* Revision register */
123
    case 0x0008:
124
        val = s->revision;
125
        break;
121 126
    /* Invalid Address register */
122 127
    case 0x0010:
123 128
        val = s->invalid_address_register;
......
161 166
    case 0x00d0:
162 167
    case 0x00d8:
163 168
    case 0x00e0:
169
    case 0x00e8:
164 170
        val = s->rem_speed[(addr - 0x0070) >> 3];
165 171
        break;
166 172
    /* DMA channel base address */
......
202 208
            val = s->dma_regs[entry][idx];
203 209
        }
204 210
        break;
205
    /* Offset 0x0208 */
211
    /* Interrupt source */
212
    case 0x0200:
213
        val = s->nmi_interrupt;
214
        break;
215
    /* Error type */
206 216
    case 0x0208:
207 217
        val = 0;
208 218
        break;
......
219 229
        val = 0;
220 230
        qemu_irq_lower(s->timer_irq);
221 231
        break;
222
    /* Offset 0x0238 */
232
    /* EISA interrupt */
223 233
    case 0x0238:
224
        val = s->offset238;
234
        val = 7; /* FIXME: should be read from EISA controller */
225 235
        break;
226 236
    default:
227 237
        RC4030_ERROR("invalid read [" TARGET_FMT_plx "]\n", addr);
......
275 285
        break;
276 286
    /* Cache Maintenance */
277 287
    case 0x0030:
278
        RC4030_ERROR("Cache maintenance not handled yet (val 0x%02x)\n", val);
288
        s->cache_maint = val;
279 289
        break;
280 290
    /* I/O Cache Physical Tag */
281 291
    case 0x0048:
......
291 301
        break;
292 302
    /* I/O Cache Buffer Window */
293 303
    case 0x0060:
294
        s->cache_bwin = val;
295 304
        /* HACK */
296 305
        if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
297
            target_phys_addr_t dests[] = { 4, 0, 8, 0x10 };
298
            static int current = 0;
299
            target_phys_addr_t dest = 0 + dests[current];
300
            uint8_t buf;
301
            current = (current + 1) % (ARRAY_SIZE(dests));
302
            buf = s->cache_bwin - 1;
303
            cpu_physical_memory_rw(dest, &buf, 1, 1);
306
            target_phys_addr_t dest = s->cache_ptag & ~0x1;
307
            dest += (s->cache_maint & 0x3) << 3;
308
            cpu_physical_memory_rw(dest, (uint8_t*)&val, 4, 1);
304 309
        }
305 310
        break;
306 311
    /* Remote Speed Registers */
......
319 324
    case 0x00d0:
320 325
    case 0x00d8:
321 326
    case 0x00e0:
327
    case 0x00e8:
322 328
        s->rem_speed[(addr - 0x0070) >> 3] = val;
323 329
        break;
324 330
    /* DMA channel base address */
......
370 376
        qemu_irq_lower(s->timer_irq);
371 377
        set_next_tick(s);
372 378
        break;
379
    /* EISA interrupt */
380
    case 0x0238:
381
        break;
373 382
    default:
374 383
        RC4030_ERROR("invalid write of 0x%02x at [" TARGET_FMT_plx "]\n", val, addr);
375 384
        break;
......
580 589
    int i;
581 590

  
582 591
    s->config = 0x410; /* some boards seem to accept 0x104 too */
592
    s->revision = 1;
583 593
    s->invalid_address_register = 0;
584 594

  
585 595
    memset(s->dma_regs, 0, sizeof(s->dma_regs));
586 596
    s->dma_tl_base = s->dma_tl_limit = 0;
587 597

  
588 598
    s->remote_failed_address = s->memory_failed_address = 0;
599
    s->cache_maint = 0;
589 600
    s->cache_ptag = s->cache_ltag = 0;
590
    s->cache_bmask = s->cache_bwin = 0;
601
    s->cache_bmask = 0;
591 602

  
592 603
    s->offset210 = 0x18186;
593 604
    s->nvram_protect = 7;
594
    s->offset238 = 7;
595 605
    for (i = 0; i < 15; i++)
596 606
        s->rem_speed[i] = 7;
597
    s->imr_jazz = s->isr_jazz = 0;
607
    s->imr_jazz = 0x10; /* XXX: required by firmware, but why? */
608
    s->isr_jazz = 0;
598 609

  
599 610
    s->itr = 0;
600 611

  
......
607 618
    rc4030State* s = opaque;
608 619
    int i, j;
609 620

  
610
    if (version_id != 1)
621
    if (version_id != 2)
611 622
        return -EINVAL;
612 623

  
613 624
    s->config = qemu_get_be32(f);
......
617 628
            s->dma_regs[i][j] = qemu_get_be32(f);
618 629
    s->dma_tl_base = qemu_get_be32(f);
619 630
    s->dma_tl_limit = qemu_get_be32(f);
631
    s->cache_maint = qemu_get_be32(f);
620 632
    s->remote_failed_address = qemu_get_be32(f);
621 633
    s->memory_failed_address = qemu_get_be32(f);
622 634
    s->cache_ptag = qemu_get_be32(f);
623 635
    s->cache_ltag = qemu_get_be32(f);
624 636
    s->cache_bmask = qemu_get_be32(f);
625
    s->cache_bwin = qemu_get_be32(f);
626 637
    s->offset210 = qemu_get_be32(f);
627 638
    s->nvram_protect = qemu_get_be32(f);
628
    s->offset238 = qemu_get_be32(f);
629 639
    for (i = 0; i < 15; i++)
630 640
        s->rem_speed[i] = qemu_get_be32(f);
631 641
    s->imr_jazz = qemu_get_be32(f);
......
650 660
            qemu_put_be32(f, s->dma_regs[i][j]);
651 661
    qemu_put_be32(f, s->dma_tl_base);
652 662
    qemu_put_be32(f, s->dma_tl_limit);
663
    qemu_put_be32(f, s->cache_maint);
653 664
    qemu_put_be32(f, s->remote_failed_address);
654 665
    qemu_put_be32(f, s->memory_failed_address);
655 666
    qemu_put_be32(f, s->cache_ptag);
656 667
    qemu_put_be32(f, s->cache_ltag);
657 668
    qemu_put_be32(f, s->cache_bmask);
658
    qemu_put_be32(f, s->cache_bwin);
659 669
    qemu_put_be32(f, s->offset210);
660 670
    qemu_put_be32(f, s->nvram_protect);
661
    qemu_put_be32(f, s->offset238);
662 671
    for (i = 0; i < 15; i++)
663 672
        qemu_put_be32(f, s->rem_speed[i]);
664 673
    qemu_put_be32(f, s->imr_jazz);
......
666 675
    qemu_put_be32(f, s->itr);
667 676
}
668 677

  
669
static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write)
678
static void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len, int is_write)
670 679
{
671 680
    rc4030State *s = opaque;
672 681
    target_phys_addr_t entry_addr;
673
    target_phys_addr_t dma_addr, phys_addr;
682
    target_phys_addr_t phys_addr;
674 683
    dma_pagetable_entry entry;
675
    int index, dev_to_mem;
684
    int index;
676 685
    int ncpy, i;
677 686

  
678
    s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
679

  
680
    /* Check DMA channel consistency */
681
    dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 1;
682
    if (!(s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_ENABLE) ||
683
        (is_write != dev_to_mem)) {
684
        s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR;
685
        return;
686
    }
687

  
688
    if (len > s->dma_regs[n][DMA_REG_COUNT])
689
        len = s->dma_regs[n][DMA_REG_COUNT];
690

  
691
    dma_addr = s->dma_regs[n][DMA_REG_ADDRESS];
692 687
    i = 0;
693 688
    for (;;) {
694 689
        if (i == len) {
695
            s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR;
696 690
            break;
697 691
        }
698 692

  
699
        ncpy = DMA_PAGESIZE - (dma_addr & (DMA_PAGESIZE - 1));
693
        ncpy = DMA_PAGESIZE - (addr & (DMA_PAGESIZE - 1));
700 694
        if (ncpy > len - i)
701 695
            ncpy = len - i;
702 696

  
703 697
        /* Get DMA translation table entry */
704
        index = dma_addr / DMA_PAGESIZE;
698
        index = addr / DMA_PAGESIZE;
705 699
        if (index >= s->dma_tl_limit / sizeof(dma_pagetable_entry)) {
706
            s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR;
707 700
            break;
708 701
        }
709 702
        entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry);
......
712 705
        cpu_physical_memory_rw(entry_addr, (uint8_t *)&entry, sizeof(entry), 0);
713 706

  
714 707
        /* Read/write data at right place */
715
        phys_addr = entry.frame + (dma_addr & (DMA_PAGESIZE - 1));
708
        phys_addr = entry.frame + (addr & (DMA_PAGESIZE - 1));
716 709
        cpu_physical_memory_rw(phys_addr, &buf[i], ncpy, is_write);
717 710

  
718 711
        i += ncpy;
719
        dma_addr += ncpy;
720
        s->dma_regs[n][DMA_REG_COUNT] -= ncpy;
712
        addr += ncpy;
713
    }
714
}
715

  
716
static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_write)
717
{
718
    rc4030State *s = opaque;
719
    target_phys_addr_t dma_addr;
720
    int dev_to_mem;
721

  
722
    s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
723

  
724
    /* Check DMA channel consistency */
725
    dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 1;
726
    if (!(s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_ENABLE) ||
727
        (is_write != dev_to_mem)) {
728
        s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_MEM_INTR;
729
        s->nmi_interrupt |= 1 << n;
730
        return;
721 731
    }
722 732

  
733
    /* Get start address and len */
734
    if (len > s->dma_regs[n][DMA_REG_COUNT])
735
        len = s->dma_regs[n][DMA_REG_COUNT];
736
    dma_addr = s->dma_regs[n][DMA_REG_ADDRESS];
737

  
738
    /* Read/write data at right place */
739
    rc4030_dma_memory_rw(opaque, dma_addr, buf, len, is_write);
740

  
741
    s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR;
742
    s->dma_regs[n][DMA_REG_COUNT] -= len;
743

  
723 744
#ifdef DEBUG_RC4030_DMA
724 745
    {
725 746
        int i, j;
......
792 813
    s->jazz_bus_irq = jazz_bus;
793 814

  
794 815
    qemu_register_reset(rc4030_reset, s);
795
    register_savevm("rc4030", 0, 1, rc4030_save, rc4030_load, s);
816
    register_savevm("rc4030", 0, 2, rc4030_save, rc4030_load, s);
796 817
    rc4030_reset(s);
797 818

  
798 819
    s_chipset = cpu_register_io_memory(0, rc4030_read, rc4030_write, s);

Also available in: Unified diff