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, | ... | ... |