Commit ff403da6a76ac4879da101768e5a956c9582b8db
1 parent
4254fab8
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
Showing
3 changed files
with
28 additions
and
8 deletions
hw/iommu.c
| ... | ... | @@ -112,21 +112,28 @@ typedef struct IOMMUState { |
| 112 | 112 | uint32_t regs[IOMMU_NREGS]; |
| 113 | 113 | target_phys_addr_t iostart; |
| 114 | 114 | uint32_t version; |
| 115 | + qemu_irq irq; | |
| 115 | 116 | } IOMMUState; |
| 116 | 117 | |
| 117 | 118 | static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) |
| 118 | 119 | { |
| 119 | 120 | IOMMUState *s = opaque; |
| 120 | 121 | target_phys_addr_t saddr; |
| 122 | + uint32_t ret; | |
| 121 | 123 | |
| 122 | 124 | saddr = (addr - s->addr) >> 2; |
| 123 | 125 | switch (saddr) { |
| 124 | 126 | default: |
| 125 | - DPRINTF("read reg[%d] = %x\n", (int)saddr, s->regs[saddr]); | |
| 126 | - return s->regs[saddr]; | |
| 127 | + ret = s->regs[saddr]; | |
| 128 | + break; | |
| 129 | + case IOMMU_AFAR: | |
| 130 | + case IOMMU_AFSR: | |
| 131 | + ret = s->regs[saddr]; | |
| 132 | + qemu_irq_lower(s->irq); | |
| 127 | 133 | break; |
| 128 | 134 | } |
| 129 | - return 0; | |
| 135 | + DPRINTF("read reg[%d] = %x\n", (int)saddr, ret); | |
| 136 | + return ret; | |
| 130 | 137 | } |
| 131 | 138 | |
| 132 | 139 | 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, |
| 180 | 187 | DPRINTF("page flush %x\n", val); |
| 181 | 188 | s->regs[saddr] = val & IOMMU_PGFLUSH_MASK; |
| 182 | 189 | break; |
| 190 | + case IOMMU_AFAR: | |
| 191 | + s->regs[saddr] = val; | |
| 192 | + qemu_irq_lower(s->irq); | |
| 193 | + break; | |
| 183 | 194 | case IOMMU_AFSR: |
| 184 | 195 | s->regs[saddr] = (val & IOMMU_AFSR_MASK) | IOMMU_AFSR_RESV; |
| 196 | + qemu_irq_lower(s->irq); | |
| 185 | 197 | break; |
| 186 | 198 | case IOMMU_SBCFG0: |
| 187 | 199 | case IOMMU_SBCFG1: |
| ... | ... | @@ -255,6 +267,7 @@ static void iommu_bad_addr(IOMMUState *s, target_phys_addr_t addr, |
| 255 | 267 | if (!is_write) |
| 256 | 268 | s->regs[IOMMU_AFSR] |= IOMMU_AFSR_RD; |
| 257 | 269 | s->regs[IOMMU_AFAR] = addr; |
| 270 | + qemu_irq_raise(s->irq); | |
| 258 | 271 | } |
| 259 | 272 | |
| 260 | 273 | void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, |
| ... | ... | @@ -324,9 +337,10 @@ static void iommu_reset(void *opaque) |
| 324 | 337 | s->regs[IOMMU_CTRL] = s->version; |
| 325 | 338 | s->regs[IOMMU_ARBEN] = IOMMU_MID; |
| 326 | 339 | s->regs[IOMMU_AFSR] = IOMMU_AFSR_RESV; |
| 340 | + qemu_irq_lower(s->irq); | |
| 327 | 341 | } |
| 328 | 342 | |
| 329 | -void *iommu_init(target_phys_addr_t addr, uint32_t version) | |
| 343 | +void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq) | |
| 330 | 344 | { |
| 331 | 345 | IOMMUState *s; |
| 332 | 346 | int iommu_io_memory; |
| ... | ... | @@ -337,6 +351,7 @@ void *iommu_init(target_phys_addr_t addr, uint32_t version) |
| 337 | 351 | |
| 338 | 352 | s->addr = addr; |
| 339 | 353 | s->version = version; |
| 354 | + s->irq = irq; | |
| 340 | 355 | |
| 341 | 356 | iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, |
| 342 | 357 | iommu_mem_write, s); | ... | ... |
hw/sun4m.c
| ... | ... | @@ -436,7 +436,6 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, |
| 436 | 436 | prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; |
| 437 | 437 | |
| 438 | 438 | /* set up devices */ |
| 439 | - iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version); | |
| 440 | 439 | slavio_intctl = slavio_intctl_init(hwdef->intctl_base, |
| 441 | 440 | hwdef->intctl_base + 0x10000ULL, |
| 442 | 441 | &hwdef->intbit_to_level[0], |
| ... | ... | @@ -451,6 +450,9 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, |
| 451 | 450 | prom_offset | IO_MEM_ROM); |
| 452 | 451 | } |
| 453 | 452 | |
| 453 | + iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, | |
| 454 | + slavio_irq[hwdef->me_irq]); | |
| 455 | + | |
| 454 | 456 | espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], |
| 455 | 457 | iommu, &espdma_irq, &esp_reset); |
| 456 | 458 | |
| ... | ... | @@ -597,7 +599,8 @@ static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size, |
| 597 | 599 | slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base, |
| 598 | 600 | &slavio_irq, cpu_irqs); |
| 599 | 601 | |
| 600 | - iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version); | |
| 602 | + iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, | |
| 603 | + slavio_irq[hwdef->me_irq]); | |
| 601 | 604 | |
| 602 | 605 | espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], |
| 603 | 606 | iommu, &espdma_irq, &esp_reset); |
| ... | ... | @@ -1091,7 +1094,9 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, int RAM_size, |
| 1091 | 1094 | |
| 1092 | 1095 | for (i = 0; i < MAX_IOUNITS; i++) |
| 1093 | 1096 | if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1) |
| 1094 | - iounits[i] = iommu_init(hwdef->iounit_bases[i], hwdef->iounit_version); | |
| 1097 | + iounits[i] = iommu_init(hwdef->iounit_bases[i], | |
| 1098 | + hwdef->iounit_version, | |
| 1099 | + sbi_irq[hwdef->me_irq]); | |
| 1095 | 1100 | |
| 1096 | 1101 | espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq], |
| 1097 | 1102 | iounits[0], &espdma_irq, &esp_reset); | ... | ... |
hw/sun4m.h
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | /* Devices used by sparc32 system. */ |
| 5 | 5 | |
| 6 | 6 | /* iommu.c */ |
| 7 | -void *iommu_init(target_phys_addr_t addr, uint32_t version); | |
| 7 | +void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq); | |
| 8 | 8 | void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, |
| 9 | 9 | uint8_t *buf, int len, int is_write); |
| 10 | 10 | static inline void sparc_iommu_memory_read(void *opaque, | ... | ... |