Commit 225d4be7099f0cfdf5c85b4e4be1fa1e5169543c
1 parent
981a2e99
Log invalid accesses (no faults generated yet)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3115 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
30 additions
and
2 deletions
hw/iommu.c
@@ -59,6 +59,20 @@ do { printf("IOMMU: " fmt , ##args); } while (0) | @@ -59,6 +59,20 @@ do { printf("IOMMU: " fmt , ##args); } while (0) | ||
59 | #define IOMMU_PGFLUSH (0x0018 >> 2) | 59 | #define IOMMU_PGFLUSH (0x0018 >> 2) |
60 | #define IOMMU_PGFLUSH_MASK 0xffffffff | 60 | #define IOMMU_PGFLUSH_MASK 0xffffffff |
61 | 61 | ||
62 | +#define IOMMU_AFSR (0x1000 >> 2) | ||
63 | +#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */ | ||
64 | +#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */ | ||
65 | +#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */ | ||
66 | +#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */ | ||
67 | +#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */ | ||
68 | +#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */ | ||
69 | +#define IOMMU_AFSR_RESV 0x00f00000 /* Reserved, forced to 0x8 by hardware */ | ||
70 | +#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */ | ||
71 | +#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */ | ||
72 | +#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */ | ||
73 | + | ||
74 | +#define IOMMU_AFAR (0x1004 >> 2) | ||
75 | + | ||
62 | #define IOMMU_SBCFG0 (0x1010 >> 2) /* SBUS configration per-slot */ | 76 | #define IOMMU_SBCFG0 (0x1010 >> 2) /* SBUS configration per-slot */ |
63 | #define IOMMU_SBCFG1 (0x1014 >> 2) /* SBUS configration per-slot */ | 77 | #define IOMMU_SBCFG1 (0x1014 >> 2) /* SBUS configration per-slot */ |
64 | #define IOMMU_SBCFG2 (0x1018 >> 2) /* SBUS configration per-slot */ | 78 | #define IOMMU_SBCFG2 (0x1018 >> 2) /* SBUS configration per-slot */ |
@@ -218,6 +232,16 @@ static target_phys_addr_t iommu_translate_pa(IOMMUState *s, | @@ -218,6 +232,16 @@ static target_phys_addr_t iommu_translate_pa(IOMMUState *s, | ||
218 | return pa; | 232 | return pa; |
219 | } | 233 | } |
220 | 234 | ||
235 | +static void iommu_bad_addr(IOMMUState *s, target_phys_addr_t addr, int is_write) | ||
236 | +{ | ||
237 | + DPRINTF("bad addr " TARGET_FMT_plx "\n", addr); | ||
238 | + s->regs[IOMMU_AFSR] = IOMMU_AFSR_ERR | IOMMU_AFSR_LE | (8 << 20) | | ||
239 | + IOMMU_AFSR_FAV; | ||
240 | + if (!is_write) | ||
241 | + s->regs[IOMMU_AFSR] |= IOMMU_AFSR_RD; | ||
242 | + s->regs[IOMMU_AFAR] = addr; | ||
243 | +} | ||
244 | + | ||
221 | void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, | 245 | void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, |
222 | uint8_t *buf, int len, int is_write) | 246 | uint8_t *buf, int len, int is_write) |
223 | { | 247 | { |
@@ -231,12 +255,16 @@ void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, | @@ -231,12 +255,16 @@ void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, | ||
231 | if (l > len) | 255 | if (l > len) |
232 | l = len; | 256 | l = len; |
233 | flags = iommu_page_get_flags(opaque, page); | 257 | flags = iommu_page_get_flags(opaque, page); |
234 | - if (!(flags & IOPTE_VALID)) | 258 | + if (!(flags & IOPTE_VALID)) { |
259 | + iommu_bad_addr(opaque, page, is_write); | ||
235 | return; | 260 | return; |
261 | + } | ||
236 | phys_addr = iommu_translate_pa(opaque, addr, flags); | 262 | phys_addr = iommu_translate_pa(opaque, addr, flags); |
237 | if (is_write) { | 263 | if (is_write) { |
238 | - if (!(flags & IOPTE_WRITE)) | 264 | + if (!(flags & IOPTE_WRITE)) { |
265 | + iommu_bad_addr(opaque, page, is_write); | ||
239 | return; | 266 | return; |
267 | + } | ||
240 | cpu_physical_memory_write(phys_addr, buf, len); | 268 | cpu_physical_memory_write(phys_addr, buf, len); |
241 | } else { | 269 | } else { |
242 | cpu_physical_memory_read(phys_addr, buf, len); | 270 | cpu_physical_memory_read(phys_addr, buf, len); |