summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYair Shachar <yair.shachar@amd.com>2014-10-13 11:29:03 +0300
committerOded Gabbay <oded.gabbay@gmail.com>2015-06-03 21:52:33 +0300
commit37910359f0877d3c22a56f384d3714fa79d51cad (patch)
tree37debba0d185a62f4f8e17b352114a2da97fb885
parentb2253458a3d71dca866298fdebbcb243d707a51d (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.c178
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;
}