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 <jonathan.kim@amd.com>
Change-Id: Iad5f87092f2b82d5018013bba548979122a9bd02
[ROCm/ROCR-Runtime commit: b77189cf83]
이 커밋은 다음에 포함됨:
@@ -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<void *>(),
|
||||
0x1000,
|
||||
tmaBuf.As<void*>(),
|
||||
0x1000));
|
||||
|
||||
// compile and dispatch shader
|
||||
ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(jump_to_trap_gfx, isaBuf.As<char*>()));
|
||||
ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(trap_handler_gfx, trap.As<char*>()));
|
||||
|
||||
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<unsigned int*>();
|
||||
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
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ const std::vector<const char*> 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]
|
||||
)";
|
||||
|
||||
@@ -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_
|
||||
|
||||
새 이슈에서 참조
사용자 차단