drm/amdkfd: Enable SQ watchpoint for gfx10
There are new control registers introduced in gfx10 used to configure hardware watchpoints triggered by SMEM instructions: SQ_WATCH{0,1,2,3}_{CNTL_ADDR_HI,ADDR_L}. Those registers work in a similar way as the TCP_WATCH* registers currently used for gfx9 and above. This patch adds support to program the SQ_WATCH registers for gfx10. The SQ_WATCH?_CNTL.MASK field has one bit more than TCP_WATCH?_CNTL.MASK, so SQ watchpoints can have a finer granularity than TCP_WATCH watchpoints. In this patch, we keep the capabilities advertised to the debugger unchanged (HSA_DBG_WATCH_ADDR_MASK_*_BIT_GFX10) as this reflects what both TCP and SQ watchpoints can do and both watchpoints are configured together. Signed-off-by: Lancelot SIX <lancelot.six@amd.com> Reviewed-by: Jonathan Kim <jonathan.kim@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
59d99deb33
commit
bd31e5026d
@ -881,6 +881,7 @@ uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
#define TCP_WATCH_STRIDE (mmTCP_WATCH1_ADDR_H - mmTCP_WATCH0_ADDR_H)
|
||||
#define SQ_WATCH_STRIDE (mmSQ_WATCH1_ADDR_H - mmSQ_WATCH0_ADDR_H)
|
||||
uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
|
||||
uint64_t watch_address,
|
||||
uint32_t watch_address_mask,
|
||||
@ -889,55 +890,93 @@ uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
|
||||
uint32_t debug_vmid,
|
||||
uint32_t inst)
|
||||
{
|
||||
/* SQ_WATCH?_ADDR_* and TCP_WATCH?_ADDR_* are programmed with the
|
||||
* same values.
|
||||
*/
|
||||
uint32_t watch_address_high;
|
||||
uint32_t watch_address_low;
|
||||
uint32_t watch_address_cntl;
|
||||
|
||||
watch_address_cntl = 0;
|
||||
uint32_t tcp_watch_address_cntl;
|
||||
uint32_t sq_watch_address_cntl;
|
||||
|
||||
watch_address_low = lower_32_bits(watch_address);
|
||||
watch_address_high = upper_32_bits(watch_address) & 0xffff;
|
||||
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = 0;
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VMID,
|
||||
debug_vmid);
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MODE,
|
||||
watch_mode);
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MASK,
|
||||
watch_address_mask >> 7);
|
||||
|
||||
sq_watch_address_cntl = 0;
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VMID,
|
||||
debug_vmid);
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
MODE,
|
||||
watch_mode);
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
MASK,
|
||||
watch_address_mask >> 6);
|
||||
|
||||
/* Turning off this watch point until we set all the registers */
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VALID,
|
||||
0);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
tcp_watch_address_cntl);
|
||||
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VALID,
|
||||
0);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
sq_watch_address_cntl);
|
||||
|
||||
/* Program {TCP,SQ}_WATCH?_ADDR* */
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_H) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_L) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_H) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_L) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
|
||||
/* Enable the watch point */
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VALID,
|
||||
1);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
tcp_watch_address_cntl);
|
||||
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VALID,
|
||||
1);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
sq_watch_address_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -953,8 +992,14 @@ uint32_t kgd_gfx_v10_clear_address_watch(struct amdgpu_device *adev,
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef TCP_WATCH_STRIDE
|
||||
#undef SQ_WATCH_STRIDE
|
||||
|
||||
|
||||
/* kgd_gfx_v10_get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values
|
||||
|
Loading…
x
Reference in New Issue
Block a user