From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> 1. We need to tell the compiler mmio access cannot be optimized away (volatile). 2. We need to ensure we don't exit with forcewake left on. Signal threads to exit in a controlled fashion and install atexit handler just in case. v2: Do not assert from the threads. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> --- tests/gen7_forcewake_mt.c | 68 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/tests/gen7_forcewake_mt.c b/tests/gen7_forcewake_mt.c index 07320ef9e8ac..608217fe652a 100644 --- a/tests/gen7_forcewake_mt.c +++ b/tests/gen7_forcewake_mt.c @@ -44,6 +44,7 @@ IGT_TEST_DESCRIPTION("Exercise a suspect workaround required for" struct thread { pthread_t thread; + bool run; void *mmio; int fd; int bit; @@ -106,14 +107,26 @@ static void *igfx_get_mmio(void) static void *thread(void *arg) { struct thread *t = arg; - uint32_t *forcewake_mt = (uint32_t *)((char *)t->mmio + FORCEWAKE_MT); + volatile uint32_t *forcewake_mt = + (uint32_t *)((char *)t->mmio + FORCEWAKE_MT); uint32_t bit = 1 << t->bit; - while (1) { + while (t->run) { + uint32_t reg; + *forcewake_mt = bit << 16 | bit; - igt_assert(*forcewake_mt & bit); + reg = *forcewake_mt; + if (!(reg & bit)) { + igt_warn("Bit %u did not set! (val=%x)\n", t->bit, reg); + return (void *)-1; + } *forcewake_mt = bit << 16; - igt_assert((*forcewake_mt & bit) == 0); + reg = *forcewake_mt; + if (reg & bit) { + igt_warn("Bit %u did not clear! (val=%x)\n", + t->bit, reg); + return (void *)-1; + } } return NULL; @@ -121,13 +134,39 @@ static void *thread(void *arg) #define MI_STORE_REGISTER_MEM (0x24<<23) +static void *mmio_base; + +static void cleanup(int sig) +{ + volatile uint32_t *forcewake_mt = + (uint32_t *)((char *)mmio_base + FORCEWAKE_MT); + unsigned int bit; + + for (bit = 2; bit < 16; bit++) { + uint32_t val = 1 << bit; + uint32_t reg; + + *forcewake_mt = val << 16; + reg = *forcewake_mt; + if (reg & val) + igt_warn("Failed to restore bit %u! (val=%x)\n", + bit, reg); + } +} + igt_simple_main { struct thread t[16]; + bool success = true; int i; + mmio_base = igfx_get_mmio(); + t[0].fd = drm_open_driver(DRIVER_INTEL); - t[0].mmio = igfx_get_mmio(); + t[0].run = true; + t[0].mmio = mmio_base; + + igt_install_exit_handler(cleanup); for (i = 2; i < 16; i++) { t[i] = t[0]; @@ -201,4 +240,23 @@ igt_simple_main usleep(1000); } + + for (i = 2; i < 16; i++) + t[i].run = false; + + for (i = 2; i < 16; i++) { + void *threadret = NULL; + int ret; + + ret = pthread_join(t[i].thread, &threadret); + if (ret) { + igt_warn("failed to join thread%u! (%d)\n", i, ret); + success = false; + } else if (threadret) { + igt_warn("thread%u failed! (%p)\n", i, threadret); + success = false; + } + } + + igt_assert(success); } -- 2.14.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx