[Public] > -----Original Message----- > From: Six, Lancelot <Lancelot.Six@xxxxxxx> > Sent: Friday, April 12, 2024 8:54 AM > To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: Kim, Jonathan <Jonathan.Kim@xxxxxxx>; Six, Lancelot > <Lancelot.Six@xxxxxxx> > Subject: [PATCH] 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@xxxxxxx> Reviewed-by: Jonathan Kim <jonathan.kim@xxxxxxx> > --- > .../drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c | 71 > +++++++++++++++---- > 1 file changed, 58 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c > index 69810b3f1c63..3ab6c3aa0ad1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c > @@ -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 > > base-commit: fd1be4972efe2c3f1183404572c34e2b5549c07e > -- > 2.34.1