Commit e0f85f46 authored by Jonathan Kim's avatar Jonathan Kim Committed by Alex Deucher
Browse files

drm/amdkfd: add debug set and clear address watch points operation



Shader read, write and atomic memory operations can be alerted to the
debugger as an address watch exception.

Allow the debugger to pass in a watch point to a particular memory
address per device.

Note that there exists only 4 watch points per devices to date, so have
the KFD keep track of what watch points are allocated or not.

Signed-off-by: default avatarJonathan Kim <jonathan.kim@amd.com>
Reviewed-by: default avatarFelix Kuehling <felix.kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a70a93fa
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -118,6 +118,55 @@ static uint32_t kgd_aldebaran_set_wave_launch_mode(struct amdgpu_device *adev,
	return data;
	return data;
}
}


#define TCP_WATCH_STRIDE (regTCP_WATCH1_ADDR_H - regTCP_WATCH0_ADDR_H)
static uint32_t kgd_gfx_aldebaran_set_address_watch(
					struct amdgpu_device *adev,
					uint64_t watch_address,
					uint32_t watch_address_mask,
					uint32_t watch_id,
					uint32_t watch_mode,
					uint32_t debug_vmid)
{
	uint32_t watch_address_high;
	uint32_t watch_address_low;
	uint32_t watch_address_cntl;

	watch_address_cntl = 0;
	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_WATCH0_CNTL,
			MODE,
			watch_mode);

	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
			TCP_WATCH0_CNTL,
			MASK,
			watch_address_mask >> 6);

	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
			TCP_WATCH0_CNTL,
			VALID,
			1);

	WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_H) +
			(watch_id * TCP_WATCH_STRIDE)),
			watch_address_high);

	WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_L) +
			(watch_id * TCP_WATCH_STRIDE)),
			watch_address_low);

	return watch_address_cntl;
}

uint32_t kgd_gfx_aldebaran_clear_address_watch(struct amdgpu_device *adev,
					uint32_t watch_id)
{
	return 0;
}

const struct kfd2kgd_calls aldebaran_kfd2kgd = {
const struct kfd2kgd_calls aldebaran_kfd2kgd = {
	.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
	.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
	.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
	.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
@@ -141,6 +190,8 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
	.validate_trap_override_request = kgd_aldebaran_validate_trap_override_request,
	.validate_trap_override_request = kgd_aldebaran_validate_trap_override_request,
	.set_wave_launch_trap_override = kgd_aldebaran_set_wave_launch_trap_override,
	.set_wave_launch_trap_override = kgd_aldebaran_set_wave_launch_trap_override,
	.set_wave_launch_mode = kgd_aldebaran_set_wave_launch_mode,
	.set_wave_launch_mode = kgd_aldebaran_set_wave_launch_mode,
	.set_address_watch = kgd_gfx_aldebaran_set_address_watch,
	.clear_address_watch = kgd_gfx_aldebaran_clear_address_watch,
	.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
	.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
	.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
	.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
	.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings,
	.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings,
+2 −0
Original line number Original line Diff line number Diff line
@@ -413,6 +413,8 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
	.validate_trap_override_request = kgd_gfx_v9_validate_trap_override_request,
	.validate_trap_override_request = kgd_gfx_v9_validate_trap_override_request,
	.set_wave_launch_trap_override = kgd_gfx_v9_set_wave_launch_trap_override,
	.set_wave_launch_trap_override = kgd_gfx_v9_set_wave_launch_trap_override,
	.set_wave_launch_mode = kgd_gfx_v9_set_wave_launch_mode,
	.set_wave_launch_mode = kgd_gfx_v9_set_wave_launch_mode,
	.set_address_watch = kgd_gfx_v9_set_address_watch,
	.clear_address_watch = kgd_gfx_v9_clear_address_watch,
	.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
	.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
	.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
	.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
	.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
	.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
+78 −0
Original line number Original line Diff line number Diff line
@@ -880,6 +880,82 @@ uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
	return 0;
	return 0;
}
}


#define TCP_WATCH_STRIDE (mmTCP_WATCH1_ADDR_H - mmTCP_WATCH0_ADDR_H)
uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
					uint64_t watch_address,
					uint32_t watch_address_mask,
					uint32_t watch_id,
					uint32_t watch_mode,
					uint32_t debug_vmid)
{
	uint32_t watch_address_high;
	uint32_t watch_address_low;
	uint32_t watch_address_cntl;

	watch_address_cntl = 0;

	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_WATCH0_CNTL,
			VMID,
			debug_vmid);
	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
			TCP_WATCH0_CNTL,
			MODE,
			watch_mode);
	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
			TCP_WATCH0_CNTL,
			MASK,
			watch_address_mask >> 7);

	/* Turning off this watch point until we set all the registers */
	watch_address_cntl = REG_SET_FIELD(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);

	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);

	/* Enable the watch point */
	watch_address_cntl = REG_SET_FIELD(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);

	return 0;
}

uint32_t kgd_gfx_v10_clear_address_watch(struct amdgpu_device *adev,
					uint32_t watch_id)
{
	uint32_t watch_address_cntl;

	watch_address_cntl = 0;

	WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
			(watch_id * TCP_WATCH_STRIDE)),
			watch_address_cntl);

	return 0;
}


/* kgd_gfx_v10_get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values
/* kgd_gfx_v10_get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values
 * The values read are:
 * The values read are:
 *     ib_offload_wait_time     -- Wait Count for Indirect Buffer Offloads.
 *     ib_offload_wait_time     -- Wait Count for Indirect Buffer Offloads.
@@ -969,6 +1045,8 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
	.validate_trap_override_request = kgd_gfx_v10_validate_trap_override_request,
	.validate_trap_override_request = kgd_gfx_v10_validate_trap_override_request,
	.set_wave_launch_trap_override = kgd_gfx_v10_set_wave_launch_trap_override,
	.set_wave_launch_trap_override = kgd_gfx_v10_set_wave_launch_trap_override,
	.set_wave_launch_mode = kgd_gfx_v10_set_wave_launch_mode,
	.set_wave_launch_mode = kgd_gfx_v10_set_wave_launch_mode,
	.set_address_watch = kgd_gfx_v10_set_address_watch,
	.clear_address_watch = kgd_gfx_v10_clear_address_watch,
	.get_iq_wait_times = kgd_gfx_v10_get_iq_wait_times,
	.get_iq_wait_times = kgd_gfx_v10_get_iq_wait_times,
	.build_grace_period_packet_info = kgd_gfx_v10_build_grace_period_packet_info,
	.build_grace_period_packet_info = kgd_gfx_v10_build_grace_period_packet_info,
	.program_trap_handler_settings = program_trap_handler_settings,
	.program_trap_handler_settings = program_trap_handler_settings,
+8 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,14 @@ uint32_t kgd_gfx_v10_set_wave_launch_trap_override(struct amdgpu_device *adev,
uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
					 uint8_t wave_launch_mode,
					 uint8_t wave_launch_mode,
					 uint32_t vmid);
					 uint32_t vmid);
uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
					uint64_t watch_address,
					uint32_t watch_address_mask,
					uint32_t watch_id,
					uint32_t watch_mode,
					uint32_t debug_vmid);
uint32_t kgd_gfx_v10_clear_address_watch(struct amdgpu_device *adev,
					uint32_t watch_id);
void kgd_gfx_v10_get_iq_wait_times(struct amdgpu_device *adev, uint32_t *wait_times);
void kgd_gfx_v10_get_iq_wait_times(struct amdgpu_device *adev, uint32_t *wait_times);
void kgd_gfx_v10_build_grace_period_packet_info(struct amdgpu_device *adev,
void kgd_gfx_v10_build_grace_period_packet_info(struct amdgpu_device *adev,
					       uint32_t wait_times,
					       uint32_t wait_times,
+3 −2
Original line number Original line Diff line number Diff line
@@ -678,6 +678,7 @@ const struct kfd2kgd_calls gfx_v10_3_kfd2kgd = {
	.disable_debug_trap = kgd_gfx_v10_disable_debug_trap,
	.disable_debug_trap = kgd_gfx_v10_disable_debug_trap,
	.validate_trap_override_request = kgd_gfx_v10_validate_trap_override_request,
	.validate_trap_override_request = kgd_gfx_v10_validate_trap_override_request,
	.set_wave_launch_trap_override = kgd_gfx_v10_set_wave_launch_trap_override,
	.set_wave_launch_trap_override = kgd_gfx_v10_set_wave_launch_trap_override,
	.set_wave_launch_mode = kgd_gfx_v10_set_wave_launch_mode
	.set_wave_launch_mode = kgd_gfx_v10_set_wave_launch_mode,

	.set_address_watch = kgd_gfx_v10_set_address_watch,
	.clear_address_watch = kgd_gfx_v10_clear_address_watch
};
};
Loading