Commit ff403da6 authored by Blue Swirl's avatar Blue Swirl
Browse files

DVMA translation errors raise a module error irq (NMI)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3880 c046a42c-6fe2-441c-8c8c-71466251a162
parent 4254fab8
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -112,21 +112,28 @@ typedef struct IOMMUState {
    uint32_t regs[IOMMU_NREGS];
    target_phys_addr_t iostart;
    uint32_t version;
    qemu_irq irq;
} IOMMUState;

static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
{
    IOMMUState *s = opaque;
    target_phys_addr_t saddr;
    uint32_t ret;

    saddr = (addr - s->addr) >> 2;
    switch (saddr) {
    default:
        DPRINTF("read reg[%d] = %x\n", (int)saddr, s->regs[saddr]);
        return s->regs[saddr];
        ret = s->regs[saddr];
        break;
    case IOMMU_AFAR:
    case IOMMU_AFSR:
        ret = s->regs[saddr];
        qemu_irq_lower(s->irq);
        break;
    }
    return 0;
    DPRINTF("read reg[%d] = %x\n", (int)saddr, ret);
    return ret;
}

static void iommu_mem_writew(void *opaque, target_phys_addr_t addr,
@@ -180,8 +187,13 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr,
        DPRINTF("page flush %x\n", val);
        s->regs[saddr] = val & IOMMU_PGFLUSH_MASK;
        break;
    case IOMMU_AFAR:
        s->regs[saddr] = val;
        qemu_irq_lower(s->irq);
        break;
    case IOMMU_AFSR:
        s->regs[saddr] = (val & IOMMU_AFSR_MASK) | IOMMU_AFSR_RESV;
        qemu_irq_lower(s->irq);
        break;
    case IOMMU_SBCFG0:
    case IOMMU_SBCFG1:
@@ -255,6 +267,7 @@ static void iommu_bad_addr(IOMMUState *s, target_phys_addr_t addr,
    if (!is_write)
        s->regs[IOMMU_AFSR] |= IOMMU_AFSR_RD;
    s->regs[IOMMU_AFAR] = addr;
    qemu_irq_raise(s->irq);
}

void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
@@ -324,9 +337,10 @@ static void iommu_reset(void *opaque)
    s->regs[IOMMU_CTRL] = s->version;
    s->regs[IOMMU_ARBEN] = IOMMU_MID;
    s->regs[IOMMU_AFSR] = IOMMU_AFSR_RESV;
    qemu_irq_lower(s->irq);
}

void *iommu_init(target_phys_addr_t addr, uint32_t version)
void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq)
{
    IOMMUState *s;
    int iommu_io_memory;
@@ -337,6 +351,7 @@ void *iommu_init(target_phys_addr_t addr, uint32_t version)

    s->addr = addr;
    s->version = version;
    s->irq = irq;

    iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read,
                                             iommu_mem_write, s);
+8 −3
Original line number Diff line number Diff line
@@ -436,7 +436,6 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
    prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;

    /* set up devices */
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
                                       hwdef->intctl_base + 0x10000ULL,
                                       &hwdef->intbit_to_level[0],
@@ -451,6 +450,9 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
                                     prom_offset | IO_MEM_ROM);
    }

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
                       slavio_irq[hwdef->me_irq]);

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
                              iommu, &espdma_irq, &esp_reset);

@@ -597,7 +599,8 @@ static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size,
    slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base,
                                      &slavio_irq, cpu_irqs);

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
                       slavio_irq[hwdef->me_irq]);

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
                              iommu, &espdma_irq, &esp_reset);
@@ -1091,7 +1094,9 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, int RAM_size,

    for (i = 0; i < MAX_IOUNITS; i++)
        if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1)
            iounits[i] = iommu_init(hwdef->iounit_bases[i], hwdef->iounit_version);
            iounits[i] = iommu_init(hwdef->iounit_bases[i],
                                    hwdef->iounit_version,
                                    sbi_irq[hwdef->me_irq]);

    espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq],
                              iounits[0], &espdma_irq, &esp_reset);
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
/* Devices used by sparc32 system.  */

/* iommu.c */
void *iommu_init(target_phys_addr_t addr, uint32_t version);
void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq);
void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr,
                                 uint8_t *buf, int len, int is_write);
static inline void sparc_iommu_memory_read(void *opaque,