Skip to content

Commit bd31e50

Browse files
lancesixalexdeucher
authored andcommitted
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 <[email protected]> Reviewed-by: Jonathan Kim <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 59d99de commit bd31e50

File tree

1 file changed

+58
-13
lines changed

1 file changed

+58
-13
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
881881
}
882882

883883
#define TCP_WATCH_STRIDE (mmTCP_WATCH1_ADDR_H - mmTCP_WATCH0_ADDR_H)
884+
#define SQ_WATCH_STRIDE (mmSQ_WATCH1_ADDR_H - mmSQ_WATCH0_ADDR_H)
884885
uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
885886
uint64_t watch_address,
886887
uint32_t watch_address_mask,
@@ -889,55 +890,93 @@ uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
889890
uint32_t debug_vmid,
890891
uint32_t inst)
891892
{
893+
/* SQ_WATCH?_ADDR_* and TCP_WATCH?_ADDR_* are programmed with the
894+
* same values.
895+
*/
892896
uint32_t watch_address_high;
893897
uint32_t watch_address_low;
894-
uint32_t watch_address_cntl;
895-
896-
watch_address_cntl = 0;
898+
uint32_t tcp_watch_address_cntl;
899+
uint32_t sq_watch_address_cntl;
897900

898901
watch_address_low = lower_32_bits(watch_address);
899902
watch_address_high = upper_32_bits(watch_address) & 0xffff;
900903

901-
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
904+
tcp_watch_address_cntl = 0;
905+
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
902906
TCP_WATCH0_CNTL,
903907
VMID,
904908
debug_vmid);
905-
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
909+
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
906910
TCP_WATCH0_CNTL,
907911
MODE,
908912
watch_mode);
909-
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
913+
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
910914
TCP_WATCH0_CNTL,
911915
MASK,
912916
watch_address_mask >> 7);
913917

918+
sq_watch_address_cntl = 0;
919+
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
920+
SQ_WATCH0_CNTL,
921+
VMID,
922+
debug_vmid);
923+
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
924+
SQ_WATCH0_CNTL,
925+
MODE,
926+
watch_mode);
927+
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
928+
SQ_WATCH0_CNTL,
929+
MASK,
930+
watch_address_mask >> 6);
931+
914932
/* Turning off this watch point until we set all the registers */
915-
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
933+
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
916934
TCP_WATCH0_CNTL,
917935
VALID,
918936
0);
919-
920937
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
921938
(watch_id * TCP_WATCH_STRIDE)),
922-
watch_address_cntl);
939+
tcp_watch_address_cntl);
940+
941+
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
942+
SQ_WATCH0_CNTL,
943+
VALID,
944+
0);
945+
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
946+
(watch_id * SQ_WATCH_STRIDE)),
947+
sq_watch_address_cntl);
923948

949+
/* Program {TCP,SQ}_WATCH?_ADDR* */
924950
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_H) +
925951
(watch_id * TCP_WATCH_STRIDE)),
926952
watch_address_high);
927-
928953
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_L) +
929954
(watch_id * TCP_WATCH_STRIDE)),
930955
watch_address_low);
931956

957+
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_H) +
958+
(watch_id * SQ_WATCH_STRIDE)),
959+
watch_address_high);
960+
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_L) +
961+
(watch_id * SQ_WATCH_STRIDE)),
962+
watch_address_low);
963+
932964
/* Enable the watch point */
933-
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
965+
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
934966
TCP_WATCH0_CNTL,
935967
VALID,
936968
1);
937-
938969
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
939970
(watch_id * TCP_WATCH_STRIDE)),
940-
watch_address_cntl);
971+
tcp_watch_address_cntl);
972+
973+
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
974+
SQ_WATCH0_CNTL,
975+
VALID,
976+
1);
977+
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
978+
(watch_id * SQ_WATCH_STRIDE)),
979+
sq_watch_address_cntl);
941980

942981
return 0;
943982
}
@@ -953,8 +992,14 @@ uint32_t kgd_gfx_v10_clear_address_watch(struct amdgpu_device *adev,
953992
(watch_id * TCP_WATCH_STRIDE)),
954993
watch_address_cntl);
955994

995+
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
996+
(watch_id * SQ_WATCH_STRIDE)),
997+
watch_address_cntl);
998+
956999
return 0;
9571000
}
1001+
#undef TCP_WATCH_STRIDE
1002+
#undef SQ_WATCH_STRIDE
9581003

9591004

9601005
/* kgd_gfx_v10_get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values

0 commit comments

Comments
 (0)