Commit 225d4be7099f0cfdf5c85b4e4be1fa1e5169543c

Authored by blueswir1
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);