From a10eaed8dc49b8547f8d5c152b040d224a2f449f Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Mon, 25 Apr 2022 11:19:09 -0400 Subject: [PATCH] kfdtest: add hit trap event test Check that a jump to trap event can be picked up by the debugger. Signed-off-by: Jonathan Kim Change-Id: Iad5f87092f2b82d5018013bba548979122a9bd02 [ROCm/ROCR-Runtime commit: b77189cf8384fed7a8e53687d505e49c42afeca9] --- .../tests/kfdtest/src/KFDDBGTest.cpp | 75 ++++++++++++++++++ .../tests/kfdtest/src/ShaderStore.cpp | 78 +++++++++++++++++++ .../tests/kfdtest/src/ShaderStore.hpp | 4 + 3 files changed, 157 insertions(+) diff --git a/projects/rocr-runtime/tests/kfdtest/src/KFDDBGTest.cpp b/projects/rocr-runtime/tests/kfdtest/src/KFDDBGTest.cpp index a93c1563dc..3fe6f58e7b 100644 --- a/projects/rocr-runtime/tests/kfdtest/src/KFDDBGTest.cpp +++ b/projects/rocr-runtime/tests/kfdtest/src/KFDDBGTest.cpp @@ -237,3 +237,78 @@ exit: LOG() << std::endl; TEST_END } + +TEST_F(KFDDBGTest, HitTrapEvent) { + TEST_START(TESTPROFILE_RUNALL) + if (m_FamilyId >= FAMILY_AI) { + int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); + + if (hsaKmtCheckRuntimeDebugSupport()) { + LOG() << "Skip test as debug API not supported"; + goto exit; + } + + ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; + + // create shader and trap bufs then enable 2nd level trap + HsaMemoryBuffer isaBuf(PAGE_SIZE, defaultGPUNode, true, false, true); + HsaMemoryBuffer trapStatusBuf(PAGE_SIZE, defaultGPUNode, true, false, false); + + HsaMemoryBuffer trap(PAGE_SIZE*2, defaultGPUNode, true, false, true); + HsaMemoryBuffer tmaBuf(PAGE_SIZE, defaultGPUNode, false, false, false); + + ASSERT_SUCCESS(hsaKmtSetTrapHandler(defaultGPUNode, + trap.As(), + 0x1000, + tmaBuf.As(), + 0x1000)); + + // compile and dispatch shader + ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(jump_to_trap_gfx, isaBuf.As())); + ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(trap_handler_gfx, trap.As())); + + uint32_t rDebug; + ASSERT_SUCCESS(hsaKmtRuntimeEnable(&rDebug, true)); + + BaseDebug *debug = new BaseDebug(); + struct kfd_runtime_info r_info = {0}; + ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), getpid(), 0)); + ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED); + + PM4Queue queue; + HsaQueueResource *qResources; + ASSERT_SUCCESS(queue.Create(defaultGPUNode)); + + unsigned int* trapStatus = trapStatusBuf.As(); + trapStatus[0] = 0; + Dispatch *dispatch; + dispatch = new Dispatch(isaBuf); + dispatch->SetArgs(&trapStatus[0], NULL); + dispatch->SetDim(1, 1, 1); + + /* Subscribe to trap events and submit the queue */ + uint64_t trapMask = KFD_EC_MASK(EC_QUEUE_WAVE_TRAP); + debug->SetExceptionsEnabled(trapMask); + dispatch->Submit(queue); + + /* Wait for trap event */ + uint32_t QueueId = -1; + ASSERT_SUCCESS(debug->QueryDebugEvent(&trapMask, NULL, &QueueId, 5000)); + ASSERT_NE(QueueId, -1); + ASSERT_EQ(trapMask, KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | KFD_EC_MASK(EC_QUEUE_NEW)); + + dispatch->Sync(); + EXPECT_SUCCESS(queue.Destroy()); + + ASSERT_NE(trapStatus[0], 0); + + debug->Detach(); + hsaKmtRuntimeDisable(); + } else { + LOG() << "Skipping test: Test not supported on family ID 0x" + << m_FamilyId << "." << std::endl; + } +exit: + LOG() << std::endl; + TEST_END +} diff --git a/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.cpp b/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.cpp index 58a2f6674e..827072ee5a 100644 --- a/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.cpp +++ b/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.cpp @@ -80,6 +80,13 @@ const std::vector ShaderList = { " .else\n"\ " v_cmp_lt_u32 vcc, \\src0, \\vsrc1\n"\ " .endif\n"\ + " .endm\n"\ + " .macro V_CMP_EQ_U32 src0, vsrc1\n"\ + " .if (.amdgcn.gfx_generation_number >= 10)\n"\ + " v_cmp_eq_u32 vcc_lo, \\src0, \\vsrc1\n"\ + " .else\n"\ + " v_cmp_eq_u32 vcc, \\src0, \\vsrc1\n"\ + " .endif\n"\ " .endm\n" /* Macros for portable flat load/store/atomic instructions. @@ -893,3 +900,74 @@ const char *GwsAtomicIncreaseIsa = s_waitcnt 0 s_endpgm )"; + +const char *jump_to_trap_gfx = + SHADER_START + SHADER_MACROS_U32 + R"( + /*copy the parameters from scalar registers to vector registers*/ + v_mov_b32 v4, 0 + v_mov_b32 v0, s0 + v_mov_b32 v1, s1 + s_trap 1 + EXIT_LOOP: + V_CMP_EQ_U32 v4, 0 + s_cbranch_vccnz EXIT_LOOP + flat_store_dword v[0:1], v4 + s_waitcnt vmcnt(0)&lgkmcnt(0) + s_endpgm +)"; + +const char *trap_handler_gfx = + SHADER_START + R"( + CHECK_VMFAULT: + /*if trap jumped to by vmfault, restore skip m0 signalling*/ + s_getreg_b32 ttmp14, hwreg(HW_REG_TRAPSTS) + s_and_b32 ttmp2, ttmp14, 0x800 + s_cbranch_scc1 RESTORE_AND_EXIT + GET_DOORBELL: + .if .amdgcn.gfx_generation_number < 11 + s_mov_b32 ttmp2, exec_lo + s_mov_b32 ttmp3, exec_hi + s_mov_b32 exec_lo, 0x80000000 + s_sendmsg 10 + WAIT_SENDMSG: + /*wait until msb is cleared (i.e. doorbell fetched)*/ + s_nop 7 + s_bitcmp0_b32 exec_lo, 0x1F + s_cbranch_scc0 WAIT_SENDMSG + /* restore exec */ + s_mov_b32 exec_hi, ttmp3 + s_and_b32 exec_lo, exec_lo, 0xfff + s_mov_b32 ttmp3, exec_lo + s_mov_b32 exec_lo, ttmp2 + .else + s_sendmsg_rtn_b32 ttmp3, sendmsg(MSG_RTN_GET_DOORBELL) + s_waitcnt lgkmcnt(0) + s_and_b32 ttmp3, ttmp3, 0x3ff + .endif + s_mov_b32 ttmp2, m0 + s_or_b32 ttmp3, ttmp3, 0x800 + /* set m0, send interrupt and restore m0 and exit trap*/ + s_mov_b32 m0, ttmp3 + s_nop 0x0 + s_sendmsg sendmsg(MSG_INTERRUPT) + s_waitcnt lgkmcnt(0) + s_mov_b32 m0, ttmp2 + v_mov_b32 v4, ttmp1 + /* restore and increment program counter to skip shader trap jump*/ + s_add_u32 ttmp0, ttmp0, 4 + s_addc_u32 ttmp1, ttmp1, 0 + s_and_b32 ttmp1, ttmp1, 0xffff + RESTORE_AND_EXIT: + /* restore SQ_WAVE_IB_STS */ + s_lshr_b32 ttmp2, ttmp11, (26 - 15) + s_and_b32 ttmp2, ttmp2, (0x8000 | 0x1F0000) + s_setreg_b32 hwreg(HW_REG_IB_STS), ttmp2 + /* restore SQ_WAVE_STATUS */ + s_and_b64 exec, exec, exec + s_and_b64 vcc, vcc, vcc + s_setreg_b32 hwreg(HW_REG_STATUS), ttmp12 + s_rfe_b64 [ttmp0, ttmp1] +)"; diff --git a/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.hpp b/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.hpp index 3964a5b397..e975e28499 100644 --- a/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.hpp +++ b/projects/rocr-runtime/tests/kfdtest/src/ShaderStore.hpp @@ -62,4 +62,8 @@ extern const char *ReadMemoryIsa; extern const char *GwsInitIsa; extern const char *GwsAtomicIncreaseIsa; +/* HitTrapEvent */ +extern const char *jump_to_trap_gfx; +extern const char *trap_handler_gfx; + #endif // _SHADERSTORE_H_