diff options
author | Yair Shachar <yair.shachar@amd.com> | 2014-10-13 11:29:03 +0300 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2015-06-03 21:52:33 +0300 |
commit | 37910359f0877d3c22a56f384d3714fa79d51cad (patch) | |
tree | 37debba0d185a62f4f8e17b352114a2da97fb885 | |
parent | b2253458a3d71dca866298fdebbcb243d707a51d (diff) |
Add H/W debugger module
Signed-off-by: Yair Shachar <yair.shachar@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r-- | src/debug.c | 178 |
1 files changed, 174 insertions, 4 deletions
diff --git a/src/debug.c b/src/debug.c index dab3a51..46f72e7 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,6 +24,9 @@ */ #include "libhsakmt.h" +#include "linux/kfd_ioctl.h" +#include <stdlib.h> +#include <string.h> HSAKMT_STATUS HSAKMTAPI @@ -31,9 +34,25 @@ hsaKmtDbgRegister( HSAuint32 NodeId //IN ) { + HSAKMT_STATUS result; + uint32_t gpu_id; CHECK_KFD_OPEN(); - return HSAKMT_STATUS_NOT_SUPPORTED; + result = validate_nodeid(NodeId, &gpu_id); + if (result != HSAKMT_STATUS_SUCCESS) + return result; + + struct kfd_ioctl_dbg_register_args args; + memset(&args, 0, sizeof(args)); + args.gpu_id = gpu_id; + long err = kmtIoctl(kfd_fd, AMDKFD_IOC_DBG_REGISTER, &args); + + if (err == 0) + result = HSAKMT_STATUS_SUCCESS; + else + result = HSAKMT_STATUS_ERROR; + + return (result); } HSAKMT_STATUS @@ -42,9 +61,24 @@ hsaKmtDbgUnregister( HSAuint32 NodeId //IN ) { + HSAKMT_STATUS result; + uint32_t gpu_id; CHECK_KFD_OPEN(); - return HSAKMT_STATUS_NOT_SUPPORTED; + result = validate_nodeid(NodeId, &gpu_id); + if (result != HSAKMT_STATUS_SUCCESS) + return result; + + struct kfd_ioctl_dbg_unregister_args args; + memset(&args, 0, sizeof(args)); + args.gpu_id = gpu_id; + long err = kmtIoctl(kfd_fd, AMDKFD_IOC_DBG_UNREGISTER, &args); + if (err == 0) + result = HSAKMT_STATUS_SUCCESS; + else + result = HSAKMT_STATUS_ERROR; + + return (result); } HSAKMT_STATUS @@ -57,9 +91,64 @@ hsaKmtDbgWavefrontControl( HsaDbgWaveMessage* DbgWaveMsgRing //IN (? - see thunk API doc!) ) { + HSAKMT_STATUS result; + uint32_t gpu_id; + + struct kfd_ioctl_dbg_wave_control_args *args; + CHECK_KFD_OPEN(); - return HSAKMT_STATUS_NOT_SUPPORTED; + result = validate_nodeid(NodeId, &gpu_id); + if (result != HSAKMT_STATUS_SUCCESS) + return result; + + /* Determine Size of the ioctl buffer */ + uint32_t buff_size = sizeof(Operand) + + sizeof(Mode) + sizeof(TrapId) + + sizeof(DbgWaveMsgRing->DbgWaveMsg) + + sizeof(DbgWaveMsgRing->MemoryVA) + + sizeof(*args); + + args = (struct kfd_ioctl_dbg_wave_control_args*) malloc(buff_size); + if (args == NULL) + return HSAKMT_STATUS_ERROR; + + memset(args, 0, buff_size); + + args->gpu_id = gpu_id; + args->buf_size_in_bytes = buff_size; + + /* increment pointer to the start of the non fixed part */ + unsigned char* run_ptr = (unsigned char*)args + sizeof(*args); + + /* save variable content pointer for kfd */ + args->content_ptr = (uint64_t) run_ptr; + + /* insert items, and increment pointer accordingly */ + *((HSA_DBG_WAVEOP*)run_ptr) = Operand; + run_ptr += sizeof(Operand); + + *((HSA_DBG_WAVEMODE*)run_ptr) = Mode; + run_ptr += sizeof(Mode); + + *((HSAuint32*)run_ptr) = TrapId; + run_ptr += sizeof(TrapId); + + *((HsaDbgWaveMessageAMD*)run_ptr) = DbgWaveMsgRing->DbgWaveMsg; + run_ptr += sizeof(DbgWaveMsgRing->DbgWaveMsg); + + *((void**)run_ptr) = DbgWaveMsgRing->MemoryVA; + run_ptr += sizeof(DbgWaveMsgRing->MemoryVA); + + /* send to kernel */ + long err = kmtIoctl(kfd_fd, AMDKFD_IOC_DBG_WAVE_CONTROL, args); + + free (args); + + if (err == 0) + return HSAKMT_STATUS_SUCCESS; + else + return HSAKMT_STATUS_ERROR; } HSAKMT_STATUS @@ -73,7 +162,88 @@ hsaKmtDbgAddressWatch( HsaEvent* WatchEvent[] //IN, optional ) { + HSAKMT_STATUS result; + uint32_t gpu_id; + struct kfd_ioctl_dbg_address_watch_args *args; + uint32_t buff_size; + uint32_t watch_mask_items, watch_event_items; + HSAuint32 i; + + /* + * Determine the size of the watch mask and event buffers + * the value is NULL if and only if no vector data should be attached + */ + + watch_mask_items = WatchMask[0] > 0 ? NumWatchPoints : 1; + watch_event_items = WatchEvent != NULL ? NumWatchPoints : 0; + CHECK_KFD_OPEN(); - return HSAKMT_STATUS_NOT_SUPPORTED; + result = validate_nodeid(NodeId, &gpu_id); + if (result != HSAKMT_STATUS_SUCCESS) + return result; + + if (NumWatchPoints > MAX_ALLOWED_NUM_POINTS) + return HSAKMT_STATUS_INVALID_PARAMETER; + + /* + * Size and structure of the ioctl buffer is dynamic in this case + * Here we calculate the buff size. + */ + + buff_size = sizeof(NumWatchPoints) + + (sizeof(WatchMode[0]) + sizeof(WatchAddress[0])) * + NumWatchPoints + + watch_mask_items * sizeof(HSAuint64) + + watch_event_items * sizeof(HsaEvent*)+ + sizeof(*args); + + args = (struct kfd_ioctl_dbg_address_watch_args*) malloc(buff_size); + if (args == NULL) + return HSAKMT_STATUS_ERROR; + + memset(args, 0, buff_size); + + args->gpu_id = gpu_id; + args->buf_size_in_bytes = buff_size; + + /* increment pointer to the start of the non fixed part */ + unsigned char* run_ptr = (unsigned char*)args + sizeof(*args); + + /* save variable content pointer for kfd */ + args->content_ptr = (uint64_t) run_ptr; + + /* insert items, and increment pointer accordingly */ + *((HSAuint32*)run_ptr) = NumWatchPoints; + run_ptr += sizeof(NumWatchPoints); + + for (i = 0 ; i < NumWatchPoints ; i++) { + *((HSA_DBG_WATCH_MODE*)run_ptr) = WatchMode[i]; + run_ptr += sizeof(WatchMode[i]); + } + + for (i = 0 ; i < NumWatchPoints ; i++) { + *((void**)run_ptr) = WatchAddress[i]; + run_ptr += sizeof(WatchAddress[i]); + } + + for (i = 0 ; i < watch_mask_items ; i++) { + *((HSAuint64*)run_ptr) = WatchMask[i]; + run_ptr += sizeof(WatchMask[i]); + } + + for (i = 0 ; i < watch_event_items ; i++) { + *((HsaEvent**)run_ptr) = WatchEvent[i]; + run_ptr += sizeof(WatchEvent[i]); + } + + /* send to kernel */ + long err = kmtIoctl(kfd_fd, AMDKFD_IOC_DBG_ADDRESS_WATCH, args); + + free (args); + + if (err != 0) + return HSAKMT_STATUS_ERROR; + + return HSAKMT_STATUS_SUCCESS; } |