v3d: Add an isr to the simulator to catch GMP violations.
authorEric Anholt <eric@anholt.net>
Fri, 4 Jan 2019 17:17:15 +0000 (09:17 -0800)
committerEric Anholt <eric@anholt.net>
Mon, 14 Jan 2019 21:18:02 +0000 (13:18 -0800)
Otherwise, the simulator raises the GMP interrupt and waits for it to be
handled, and v3d ends up spinning in v3d_hw_tick().  Aborting right when
violation happens gives us a chance to look at the backtrace of whatever
thread triggered the violation.

src/gallium/drivers/v3d/v3d_simulator_wrapper.cpp
src/gallium/drivers/v3d/v3d_simulator_wrapper.h
src/gallium/drivers/v3d/v3dx_simulator.c

index 7b04ded2b530de730fdf7e1f810276a3e40eb6d2..15db767d5345d0c5bead7f34f14e1c090286fadb 100644 (file)
@@ -83,6 +83,11 @@ int v3d_hw_get_version(struct v3d_hw *hw)
         return ident->tech_version * 10 + ident->revision;
 }
 
+void
+v3d_hw_set_isr(struct v3d_hw *hw, void (*isr)(uint32_t status))
+{
+        hw->set_isr(isr);
 }
 
+}
 #endif /* USE_V3D_SIMULATOR */
index 8b5dca15ed94fbe5b2e90dd24fb5b44fa32d617a..b20ea2484b447a84e3df27818565dc4346f3d8fe 100644 (file)
@@ -38,6 +38,7 @@ uint32_t v3d_hw_read_reg(struct v3d_hw *hw, uint32_t reg);
 void v3d_hw_write_reg(struct v3d_hw *hw, uint32_t reg, uint32_t val);
 void v3d_hw_tick(struct v3d_hw *hw);
 int v3d_hw_get_version(struct v3d_hw *hw);
+void v3d_hw_set_isr(struct v3d_hw *hw, void (*isr)(uint32_t status));
 
 #ifdef __cplusplus
 }
index 940b8f2ce32562144c9aa4b995b650aec5b6aa68..e6db838c0de6c1317ddd82bdb76cf55b24583ed2 100644 (file)
@@ -157,6 +157,32 @@ v3dX(simulator_get_param_ioctl)(struct v3d_hw *v3d,
         abort();
 }
 
+static struct v3d_hw *v3d_isr_hw;
+
+static void
+v3d_isr(uint32_t hub_status)
+{
+        struct v3d_hw *v3d = v3d_isr_hw;
+
+        /* Check the per-core bits */
+        if (hub_status & (1 << 0)) {
+                uint32_t core_status = V3D_READ(V3D_CTL_0_INT_STS);
+
+                if (core_status & V3D_CTL_0_INT_STS_INT_GMPV_SET) {
+                        fprintf(stderr, "GMP violation at 0x%08x\n",
+                                V3D_READ(V3D_GMP_0_VIO_ADDR));
+                        abort();
+                } else {
+                        fprintf(stderr,
+                                "Unexpected ISR with core status 0x%08x\n",
+                                core_status);
+                }
+                abort();
+        }
+
+        return;
+}
+
 void
 v3dX(simulator_init_regs)(struct v3d_hw *v3d)
 {
@@ -171,6 +197,13 @@ v3dX(simulator_init_regs)(struct v3d_hw *v3d)
          */
         V3D_WRITE(V3D_CTL_0_MISCCFG, V3D_CTL_1_MISCCFG_OVRTMUOUT_SET);
 #endif
+
+        uint32_t core_interrupts = V3D_CTL_0_INT_STS_INT_GMPV_SET;
+        V3D_WRITE(V3D_CTL_0_INT_MSK_SET, ~core_interrupts);
+        V3D_WRITE(V3D_CTL_0_INT_MSK_CLR, core_interrupts);
+
+        v3d_isr_hw = v3d;
+        v3d_hw_set_isr(v3d, v3d_isr);
 }
 
 void