diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_context.cpp b/projects/clr/opencl/api/opencl/amdocl/cl_context.cpp index 5133863c12..35483646e2 100644 --- a/projects/clr/opencl/api/opencl/amdocl/cl_context.cpp +++ b/projects/clr/opencl/api/opencl/amdocl/cl_context.cpp @@ -21,6 +21,7 @@ #include "cl_platform_amd.h" #include "cl_sdi_amd.h" #include "cl_thread_trace_amd.h" +#include "cl_debugger_amd.h" #include #include @@ -564,6 +565,33 @@ clGetExtensionFunctionAddress(const char* func_name) #endif //_WIN32 CL_EXTENSION_ENTRYPOINT_CHECK(clGetKernelSubGroupInfoKHR); break; + case 'H': +#ifdef _WIN32 + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetCallBackFunctionsAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetCallBackArgumentsAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgFlushCacheAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetExceptionPolicyAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgGetExceptionPolicyAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetKernelExecutionModeAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgGetKernelExecutionModeAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgCreateEventAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgWaitEventAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgDestroyEventAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgRegisterDebuggerAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgUnregisterDebuggerAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetAclBinaryAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgWaveControlAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgAddressWatchAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgGetAqlPacketInfoAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgGetDispatchDebugInfoAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgMapKernelCodeAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgUnmapKernelCodeAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgMapScratchRingAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgUnmapScratchRingAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgGetKernelParamMemAMD); + CL_EXTENSION_ENTRYPOINT_CHECK(clHwDbgSetGlobalMemoryAMD); +#endif //_WIN32 + break; case 'I': CL_EXTENSION_ENTRYPOINT_CHECK(clIcdGetPlatformIDsKHR); break; diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.cpp b/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.cpp new file mode 100644 index 0000000000..508b494412 --- /dev/null +++ b/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.cpp @@ -0,0 +1,872 @@ +// +// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. +// +#include "cl_common.hpp" +#include "cl_debugger_amd.h" + +#include + +/*! \addtogroup API + * @{ + * + * \addtogroup AMD_Extensions + * @{ + * + */ + +/*! \brief Set up the the dispatch call back function + * + * \param device specifies the device to be used + * + * \param preDispatchFunction is the function to be called before dispatching the kernel + * + * \param postDispatchFunction is the function to be called after kernel execution + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetCallBackFunctionsAMD, ( + cl_device_id device, + cl_PreDispatchCallBackFunctionAMD preDispatchFunction, + cl_PostDispatchCallBackFunctionAMD postDispatchFunction)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + debugManager->setCallBackFunctions(preDispatchFunction, + postDispatchFunction); + + return CL_SUCCESS; +} +RUNTIME_EXIT + + +/*! \brief Set up the arguments of the dispatch call back function + * + * \param device specifies the device to be used + * + * \param preDispatchArgs is the arguments for the pre-dispatch callback function + * + * \param postDispatchArgs is the arguments for the post-dispatch callback function + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetCallBackArgumentsAMD, ( + cl_device_id device, + void * preDispatchArgs, + void * postDispatchArgs)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + debugManager->setCallBackArguments(preDispatchArgs, postDispatchArgs); + + return CL_SUCCESS; +} +RUNTIME_EXIT + + +/*! \brief Invalidate all cache on the device. + * + * \param device specifies the device to be used + * + * \param mask is the mask to specify which cache to be flush/invalidate + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgFlushCacheAMD, ( + cl_device_id device, + cl_dbg_gpu_cache_mask_amd mask)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->flushCache(mask.ui32All); +} +RUNTIME_EXIT + + +/*! \brief Set up an exception policy in the trap handler object + * + * \param device specifies the device to be used + * + * \param policy specifies the exception policy, which includes the exception mask, + * wave action, host action, wave mode. + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the policy is not specified (NULL) + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetExceptionPolicyAMD, ( + cl_device_id device, + cl_dbg_exception_policy_amd * policy)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == policy) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->setExceptionPolicy(policy); +} +RUNTIME_EXIT + + +/*! \brief Get the exception policy in the trap handler object + * + * \param device specifies the device to be used + * + * \param policy is a pointer to the memory where the policy is returned + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the policy storage is not specified + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgGetExceptionPolicyAMD, ( + cl_device_id device, + cl_dbg_exception_policy_amd * policy)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == policy) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->getExceptionPolicy(policy); +} +RUNTIME_EXIT + +/*! \brief Set up the kernel execution mode in the trap handler object + * + * \param device specifies the device to be used + * + * \param mode specifies the kernel execution mode, which indicate whether single + * step mode is used, how many CUs are reserved. + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the mode is not specified, ie, has a NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetKernelExecutionModeAMD, ( + cl_device_id device, + cl_dbg_kernel_exec_mode_amd * mode)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == mode) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->setKernelExecutionMode(mode); +} +RUNTIME_EXIT + + +/*! \brief Get the kernel execution mode in the trap handler object + * + * \param device specifies the device to be used + * + * \param mode is a pointer to the memory where the exectuion mode is returned + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the mode storage is not specified, ie, has a NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgGetKernelExecutionModeAMD, ( + cl_device_id device, + cl_dbg_kernel_exec_mode_amd * mode)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == mode) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->getKernelExecutionMode(mode); +} +RUNTIME_EXIT + +/*! \brief Create a trap event for debugging + * + * \param device specifies the device to be used + * + * \param autoReset is the auto reset flag + * + * \param pDebugEvent returns the debug event to be used for exception notification + * + * \param pEventId is the event ID, which is not used at this moment + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_OUT_OF_RESOURCES if fails to create the event + */ +RUNTIME_ENTRY(cl_int, clHwDbgCreateEventAMD, ( + cl_device_id device, + bool autoReset, + cl_dbg_event_amd * pDebugEvent, + cl_uint * pEventId )) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == pDebugEvent) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + // set it to zero for now - not used by OpenCL + *pEventId = 0; + *pDebugEvent = debugManager->createDebugEvent(autoReset); + + return (NULL == pDebugEvent) ? CL_OUT_OF_RESOURCES : CL_SUCCESS; + +} +RUNTIME_EXIT + +/*! \brief Wait for a debug event to be signaled + * + * \param device specifies the device to be used + * + * \param pDebugEvent is the debug event to be waited for + * + * \param pEventId is the event ID, which is not used at this moment + * + * \param timeOut is the duration for waiting + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_EVENT_TIMEOUT_AMD if timeout occurs + */ +RUNTIME_ENTRY(cl_int, clHwDbgWaitEventAMD, ( + cl_device_id device, + cl_dbg_event_amd pDebugEvent, + cl_uint pEventId, + cl_uint timeOut)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (0 == pDebugEvent) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->waitDebugEvent(pDebugEvent, timeOut); +} +RUNTIME_EXIT + +/*! \brief Destroy a trap event for debugging + * + * \param device specifies the device to be used + * + * \param pDebugEvent is the debug event to be waited for + * + * \param pEventId is the event ID, which is not used at this moment + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgDestroyEventAMD, ( + cl_device_id device, + cl_dbg_event_amd * pDebugEvent, + cl_uint * pEventId )) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == pDebugEvent) { + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->destroyDebugEvent(*pDebugEvent); +} +RUNTIME_EXIT + + +/*! \brief Register the debugger on a device + * + * \param context specifies the context for the debugger + * + * \param device specifies the device to be used + * + * \param pMessageStorge specifies the memory for trap message passing between KMD and OCL runtime + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_CONTEXT if the context is not valid + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pMEssageStorge value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_OUT_OF_RESOURCES if a host queue cannot be created for the debugger + */ +RUNTIME_ENTRY(cl_int, clHwDbgRegisterDebuggerAMD, ( + cl_context context, + cl_device_id device, + volatile void * pMessageStorage)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (!is_valid(context)) { + return CL_INVALID_CONTEXT; + } + + if (NULL == pMessageStorage) { + return CL_INVALID_VALUE; + } + + return as_amd(device)->hwDebugManagerInit(as_amd(context), + reinterpret_cast(pMessageStorage)); +} +RUNTIME_EXIT + + +/*! \brief Unregister the debugger on a device + * + * \param device specifies the device to be used + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgUnregisterDebuggerAMD, ( + cl_device_id device)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->unregisterDebugger(); +} +RUNTIME_EXIT + +/*! \brief Setup the pointer of the acl_binary to be used by the debugger + * + * \param device specifies the device to be used + * + * \param aclBinary specifies the ACL binary to be used + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the aclBinary is not provided + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetAclBinaryAMD, ( + cl_device_id device, + void * aclBinary)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == aclBinary) { + LogWarning("clHwDbgSetAclBinaryAMD: Invalid ACL binary argument."); + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + debugManager->setAclBinary(aclBinary); + + return CL_SUCCESS; +} +RUNTIME_EXIT + +/*! \brief Control the execution of wavefront on the GPU + * + * \param device specifies the device to be used + * + * \param action specifies the wave action - halt, resume, kill, debug + * + * \param mode specifies the wave mode + * + * \param trapId specifies the trap ID, which should be 0x7 + * + * \param waveAddress specifies the wave address for the wave control + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the waveMsg is not provided, invalid action or mode value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgWaveControlAMD, ( + cl_device_id device, + cl_dbg_waves_action_amd action, + cl_dbg_wave_mode_amd mode, + cl_uint trapId, + cl_dbg_wave_addr_amd waveAddress)) +{ + + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + // validate the passing arguments + // + if (action < 0 || action >= CL_DBG_WAVES_MAX) { + LogWarning("clHwDbgWaveControlAMD: Invalid wave action argument"); + return CL_INVALID_VALUE; + } + + if ((mode != CL_DBG_WAVEMODE_SINGLE) + && (mode != CL_DBG_WAVEMODE_BROADCAST) + && (mode != CL_DBG_WAVEMODE_BROADCAST_CU)) { + LogWarning("clHwDbgWaveControlAMD: Invalid wave mode argument"); + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->wavefrontControl(action, mode, trapId, (void *) &waveAddress); +} +RUNTIME_EXIT + + +/*! \brief Set watch points on memory address ranges to generate exception events + * + * \param device specifies the device to be used + * + * \param numWatchPoints specifies the number of watch points + * + * \param watchMode is the array of watch mode for the watch points + * + * \param watchAddress is the array of watch address for the watch points + * + * \param watchMask is the array of mask for the watch points + * + * \param watchEvent is the array of event for the watch points + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the number of points <= 0, or other parameters is not specified + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgAddressWatchAMD, ( + cl_device_id device, + cl_uint numWatchPoints, + cl_dbg_address_watch_mode_amd * watchMode, + void ** watchAddress, + cl_ulong * watchMask, + cl_dbg_event_amd * watchEvent)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + // validate the passing arguments + if (numWatchPoints <= 0) { + LogWarning("clHwDbgAddressWatchAMD: Invalid number of watch points argument"); + return CL_INVALID_VALUE; + } + + if (NULL == watchMode) { + LogWarning("clHwDbgAddressWatchAMD: Watch mode argument"); + return CL_INVALID_VALUE; + } + + if (NULL == watchAddress) { + LogWarning("clHwDbgAddressWatchAMD: Watch address argument"); + return CL_INVALID_VALUE; + } + + if (NULL == watchMask) { + LogWarning("clHwDbgAddressWatchAMD: Watch mask argument"); + return CL_INVALID_VALUE; + } + + //TODO: WC - confirm how the watch event is used. + // + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->setAddressWatch(numWatchPoints, watchAddress, watchMask, + reinterpret_cast(watchMode), + watchEvent); +} +RUNTIME_EXIT + + +/*! \brief Get the AQL packet information for kernel dispatch + * + * \param device specifies the device to be used + * + * \param aqlPacket specifies the AQL packet + * + * \param aqlCodeInfo specifies the kernel code and its size + * + * \param packetInfo points to the memory for the packet information to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgGetAqlPacketInfoAMD, ( + cl_device_id device, + const void * aqlCodeInfo, + cl_aql_packet_info_amd * packetInfo)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->getPacketAmdInfo(aqlCodeInfo, packetInfo); +} +RUNTIME_EXIT + + +/*! \brief Get the dispatch debug information + * + * \param device specifies the device to be used + * + * \param debugInfo points to the memory for the debug information to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgGetDispatchDebugInfoAMD, ( + cl_device_id device, + cl_dispatch_debug_info_amd * debugInfo)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->getDispatchDebugInfo((void *) debugInfo); +} +RUNTIME_EXIT + +/*! \brief Map the video memory for the kernel code to allow host access + * + * \param device specifies the device to be used + * + * \param aqlCodeAddress is the memory points to the returned host memory address for the kernel code + * + * \param aqlCodeSize returns the size of the kernel code + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgMapKernelCodeAMD, ( + cl_device_id device, + cl_ulong * aqlCodeAddress, + cl_uint * aqlCodeSize)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->mapKernelCode(aqlCodeAddress, aqlCodeSize); +} +RUNTIME_EXIT + +/*! \brief Unmap the video memory for the kernel code + * + * \param device specifies the device to be used (no needed, just to be consistent) + * + * \param aqlCodeAddress is the memory points to the mapped memory address for the kernel code + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgUnmapKernelCodeAMD, ( + cl_device_id device, + cl_ulong * aqlCodeAddress)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == aqlCodeAddress) { + LogWarning("clHwDbgUnmapKernelCodeAMD: Invalid AQL code address argument."); + return CL_INVALID_VALUE; + } + + // Shader buffer is always pinned to host memory so there is no need to unmap the memory. + // Just set it to 0 to avoid unwanted access + *aqlCodeAddress = 0; + + return CL_SUCCESS; +} +RUNTIME_EXIT + +/*! \brief Map the scratch ring's memory to allow CPU access + * + * \param device specifies the device to be used + * + * \param scratchRingAddr is the memory points to the returned host memory address for scratch ring + * + * \param scratchRingSize returns the size of the scratch ring + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgMapScratchRingAMD, ( + cl_device_id device, + cl_ulong * scratchRingAddr, + cl_uint * scratchRingSize)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->mapScratchRing(scratchRingAddr, scratchRingSize); +} +RUNTIME_EXIT + +/*! \brief Unmap the shader scratch ring's video memory + * + * \param device specifies the device to be used (no needed, just to be consistent) + * + * \param scratchRingAddr is the memory points to the mapped memory address for scratch ring + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgUnmapScratchRingAMD, ( + cl_device_id device, + cl_ulong * scratchRingAddr)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + if (NULL == scratchRingAddr) { + LogWarning("clHwDbgUnmapScratchRingAMD: Invalid scratch ring address argument."); + return CL_INVALID_VALUE; + } + + // Scratch ring buffer is always pinned to host memory so there is no need to unmap the memory. + // Just set it to NULL to avoid unwanted access + *scratchRingAddr = 0; + + return CL_SUCCESS; +} +RUNTIME_EXIT + + +/*! \brief Get the memory object associated with the kernel parameter + * + * \param device specifies the device to be used + * + * \param paramIdx is the index of of the kernel argument + * + * \param paramMem is pointer of the memory associated with the kernel argument to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the paramIdx is less than zero, or the paramMem has NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_INVALID_KERNEL_ARGS if it fails to get the memory object for the kernel argument + */ +RUNTIME_ENTRY(cl_int, clHwDbgGetKernelParamMemAMD, ( + cl_device_id device, + cl_uint paramIdx, + cl_ulong * paramMem)) +{ + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::Device* amdDevice = as_amd(device); + + if (paramIdx < 0) { + LogWarning("clHwDbgGetKernelParamMemAMD: Invalid parameter index argument."); + return CL_INVALID_VALUE; + } + + if (NULL == paramMem) { + LogWarning("clHwDbgGetKernelParamMemAMD: Invalid parameter member object argument."); + return CL_INVALID_VALUE; + } + + amd::HwDebugManager * debugManager = amdDevice->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + *paramMem = debugManager->getKernelParamMem(paramIdx); + + return (*paramMem == 0) ? CL_INVALID_KERNEL_ARGS : CL_SUCCESS; +} +RUNTIME_EXIT + +/*! \brief Set value of a global memory object + * + * \param device specifies the device to be used + * + * \param memObject is the memory object handle to be assigned the value specified in srcMem. + * + * \param offset is offset of the memory object + * + * \param srcMem points to the memory which contains the values to be assigned to the memory + * + * \param size size (in bytes) of the srcMem + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if memObj or srcPtr has NULL value, size <= 0 or offset < 0 + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +RUNTIME_ENTRY(cl_int, clHwDbgSetGlobalMemoryAMD, ( + cl_device_id device, + void * memObject, + cl_uint offset, + void * srcMem, + cl_uint size)) +{ + + if (!is_valid(device)) { + return CL_INVALID_DEVICE; + } + + amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr(); + if (NULL == debugManager) { + return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD; + } + + return debugManager->setGlobalMemory(memObject, offset, srcMem, size); +} +RUNTIME_EXIT + + +/*! @} + * @} + */ diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.h b/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.h new file mode 100644 index 0000000000..b1e17223ad --- /dev/null +++ b/projects/clr/opencl/api/opencl/amdocl/cl_debugger_amd.h @@ -0,0 +1,768 @@ +/* ============================================================ + +Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. + +Redistribution and use of this material is permitted under the following +conditions: + +Redistributions must retain the above copyright notice and all terms of this +license. + +In no event shall anyone redistributing or accessing or using this material +commence or participate in any arbitration or legal action relating to this +material against Advanced Micro Devices, Inc. or any copyright holders or +contributors. The foregoing shall survive any expiration or termination of +this license or any agreement or access or use related to this material. + +ANY BREACH OF ANY TERM OF THIS LICENSE SHALL RESULT IN THE IMMEDIATE REVOCATION +OF ALL RIGHTS TO REDISTRIBUTE, ACCESS OR USE THIS MATERIAL. + +THIS MATERIAL IS PROVIDED BY ADVANCED MICRO DEVICES, INC. AND ANY COPYRIGHT +HOLDERS AND CONTRIBUTORS "AS IS" IN ITS CURRENT CONDITION AND WITHOUT ANY +REPRESENTATIONS, GUARANTEE, OR WARRANTY OF ANY KIND OR IN ANY WAY RELATED TO +SUPPORT, INDEMNITY, ERROR FREE OR UNINTERRUPTED OPERATION, OR THAT IT IS FREE +FROM DEFECTS OR VIRUSES. ALL OBLIGATIONS ARE HEREBY DISCLAIMED - WHETHER +EXPRESS, IMPLIED, OR STATUTORY - INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED +WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +ACCURACY, COMPLETENESS, OPERABILITY, QUALITY OF SERVICE, OR NON-INFRINGEMENT. +IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. OR ANY COPYRIGHT HOLDERS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, REVENUE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED OR BASED ON ANY THEORY OF LIABILITY +ARISING IN ANY WAY RELATED TO THIS MATERIAL, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. THE ENTIRE AND AGGREGATE LIABILITY OF ADVANCED MICRO DEVICES, +INC. AND ANY COPYRIGHT HOLDERS AND CONTRIBUTORS SHALL NOT EXCEED TEN DOLLARS +(US $10.00). ANYONE REDISTRIBUTING OR ACCESSING OR USING THIS MATERIAL ACCEPTS +THIS ALLOCATION OF RISK AND AGREES TO RELEASE ADVANCED MICRO DEVICES, INC. AND +ANY COPYRIGHT HOLDERS AND CONTRIBUTORS FROM ANY AND ALL LIABILITIES, +OBLIGATIONS, CLAIMS, OR DEMANDS IN EXCESS OF TEN DOLLARS (US $10.00). THE +FOREGOING ARE ESSENTIAL TERMS OF THIS LICENSE AND, IF ANY OF THESE TERMS ARE +CONSTRUED AS UNENFORCEABLE, FAIL IN ESSENTIAL PURPOSE, OR BECOME VOID OR +DETRIMENTAL TO ADVANCED MICRO DEVICES, INC. OR ANY COPYRIGHT HOLDERS OR +CONTRIBUTORS FOR ANY REASON, THEN ALL RIGHTS TO REDISTRIBUTE, ACCESS OR USE +THIS MATERIAL SHALL TERMINATE IMMEDIATELY. MOREOVER, THE FOREGOING SHALL +SURVIVE ANY EXPIRATION OR TERMINATION OF THIS LICENSE OR ANY AGREEMENT OR +ACCESS OR USE RELATED TO THIS MATERIAL. + +NOTICE IS HEREBY PROVIDED, AND BY REDISTRIBUTING OR ACCESSING OR USING THIS +MATERIAL SUCH NOTICE IS ACKNOWLEDGED, THAT THIS MATERIAL MAY BE SUBJECT TO +RESTRICTIONS UNDER THE LAWS AND REGULATIONS OF THE UNITED STATES OR OTHER +COUNTRIES, WHICH INCLUDE BUT ARE NOT LIMITED TO, U.S. EXPORT CONTROL LAWS SUCH +AS THE EXPORT ADMINISTRATION REGULATIONS AND NATIONAL SECURITY CONTROLS AS +DEFINED THEREUNDER, AS WELL AS STATE DEPARTMENT CONTROLS UNDER THE U.S. +MUNITIONS LIST. THIS MATERIAL MAY NOT BE USED, RELEASED, TRANSFERRED, IMPORTED, +EXPORTED AND/OR RE-EXPORTED IN ANY MANNER PROHIBITED UNDER ANY APPLICABLE LAWS, +INCLUDING U.S. EXPORT CONTROL LAWS REGARDING SPECIFICALLY DESIGNATED PERSONS, +COUNTRIES AND NATIONALS OF COUNTRIES SUBJECT TO NATIONAL SECURITY CONTROLS. +MOREOVER, THE FOREGOING SHALL SURVIVE ANY EXPIRATION OR TERMINATION OF ANY +LICENSE OR AGREEMENT OR ACCESS OR USE RELATED TO THIS MATERIAL. + +NOTICE REGARDING THE U.S. GOVERNMENT AND DOD AGENCIES: This material is +provided with "RESTRICTED RIGHTS" and/or "LIMITED RIGHTS" as applicable to +computer software and technical data, respectively. Use, duplication, +distribution or disclosure by the U.S. Government and/or DOD agencies is +subject to the full extent of restrictions in all applicable regulations, +including those found at FAR52.227 and DFARS252.227 et seq. and any successor +regulations thereof. Use of this material by the U.S. Government and/or DOD +agencies is acknowledgment of the proprietary rights of any copyright holders +and contributors, including those of Advanced Micro Devices, Inc., as well as +the provisions of FAR52.227-14 through 23 regarding privately developed and/or +commercial computer software. + +This license forms the entire agreement regarding the subject matter hereof and +supersedes all proposals and prior discussions and writings between the parties +with respect thereto. This license does not affect any ownership, rights, title, +or interest in, or relating to, this material. No terms of this license can be +modified or waived, and no breach of this license can be excused, unless done +so in a writing signed by all affected parties. Each term of this license is +separately enforceable. If any term of this license is determined to be or +becomes unenforceable or illegal, such term shall be reformed to the minimum +extent necessary in order for this license to remain in effect in accordance + +with its terms as modified by such reformation. This license shall be governed +by and construed in accordance with the laws of the State of Texas without +regard to rules on conflicts of law of any state or jurisdiction or the United +Nations Convention on the International Sale of Goods. All disputes arising out +of this license shall be subject to the jurisdiction of the federal and state +courts in Austin, Texas, and all defenses are hereby waived concerning personal +jurisdiction and venue of these courts. + +============================================================ */ + +#ifndef __CL_DEBUGGER_AMD_H +#define __CL_DEBUGGER_AMD_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +/****************************************** +* Private AMD extension cl_dbg * +******************************************/ +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +#define CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD -80 +#define CL_DEBUGGER_REGISTER_FAILURE_AMD -81 +#define CL_TRAP_HANDLER_NOT_DEFINED_AMD -82 +#define CL_EVENT_TIMEOUT_AMD -83 + + +typedef cl_ulong cl_dbg_event_amd; //! debug event + +/*! \brief Wave actions used to control the wave execution on the hardware + * + * The wave action enumerations are used to specify the desired + * behavior when calling the wave control function. Overall, there are + * five types of operations that can be specified. + */ +enum cl_dbg_waves_action_amd +{ + CL_DBG_WAVES_DONT_USE_ZERO = 0, //! NOT USED + CL_DBG_WAVES_HALT = 1, //! halt wave + CL_DBG_WAVES_RESUME = 2, //! resume wave + CL_DBG_WAVES_KILL = 3, //! kill wave + CL_DBG_WAVES_DEBUG = 4, //! debug wave + CL_DBG_WAVES_TRAP = 5, //! trap + CL_DBG_WAVES_MAX +}; + +/*! \brief Host actions when encountering an exception in the kernel. + * + * The host action enumeration is used to specify the desired host + * response in the event thatn a device kernel exception is encountered. + */ +enum cl_dbg_host_action_amd +{ + CL_DBG_HOST_IGNORE = 1, //! ignore the kernel exception + CL_DBG_HOST_EXIT = 2, //! exit the host application on a kernel exception + CL_DBG_HOST_NOTIFY = 4 //! report the kernel exception +}; + +/*! \brief Mode of the wave action when calling the wave control function + * + * The wave mode enumerations are used to specify the desired + * broadcast level when calling the wave control function. + */ +enum cl_dbg_wave_mode_amd +{ + CL_DBG_WAVEMODE_SINGLE = 0, //! send command to single wave + CL_DBG_WAVEMODE_BROADCAST = 2, //! send command to wave with match VMID + CL_DBG_WAVEMODE_BROADCAST_CU = 3, //! send command to wave with match VMID with specific CU + CL_DBG_WAVEMODE_MAX +}; + +/*! \brief Enumeration of address watch mode + * + * This enumeration indicates the different modes of address watch. + */ +enum cl_dbg_address_watch_mode_amd +{ + CL_DBG_ADDR_WATCH_MODE_READ = 0, //! Read operations only + CL_DBG_ADDR_WATCH_MODE_NONREAD = 1, //! Write or Atomic operations only + CL_DBG_ADDR_WATCH_MODE_ATOMIC = 2, //! Atomic Operations only + CL_DBG_ADDR_WATCH_MODE_ALL = 3, //! Read, Write or Atomic operations + CL_DBG_ADDR_WATCH_MODE_MAX //! Number of address watch modes +}; + +/*! \brief Dispatch exception policy descriptor + * + * The dispatch exception policy descriptor is used to define the + * expected exception policy in the event an exception is encountered + * on the associated dispatch. + */ +typedef struct _cl_dbg_exception_policy_amd +{ + cl_uint exceptionMask; //! exception mask + cl_dbg_waves_action_amd waveAction; //! wave action + cl_dbg_host_action_amd hostAction; //! host action + cl_dbg_wave_mode_amd waveMode; //! wave mode +} cl_dbg_exception_policy_amd; + +/*! \brief Kernel execution mode + * + * This structure is used to control the kernel execution mode. The + * following aspects are included in this structure: + * 1. Regular execution or debug mode (0: regular execution (default), + * 1: debug mode) + * 2. SQ debugger mode on/off + * 3. Disable L1 scalar cache (0: enable (default), 1: disable) + * 4. Disable L1 vector cache (0: enable (default), 1: disable) + * 5. Disable L2 cache (0: enable (default), 1: disable) + * 6. Num of CUs reserved for display (0 (default), 7: max) + */ +typedef struct _cl_dbg_kernel_exec_mode_amd +{ + union { + struct { + cl_uint monitorMode : 1; + cl_uint gpuSingleStepMode : 1; + cl_uint disableL1Scalar : 1; + cl_uint disableL1Vector : 1; + cl_uint disableL2Cache : 1; + cl_uint reservedCuNum : 3; + cl_uint reserved : 24; + }; + cl_uint ui32All; + }; +} cl_dbg_kernel_exec_mode_amd; + +/*! \brief GPU cache mask + * + * This structure is used to specify the GPU cache to be flushed/invalidated + */ +typedef struct _cl_dbg_gpu_cache_mask_amd +{ + union { + struct { + cl_uint sqICache : 1; //! instruction cache + cl_uint sqKCache : 1; //! data cache + cl_uint tcL1 : 1; //! tcL1 cache + cl_uint tcL2 : 1; //! tcL2 cache + cl_uint reserved : 28; + }; + cl_uint ui32All; + }; +} cl_dbg_gpu_cache_mask_amd; + +/*! \brief Dispatch Debug Info + * + * This structure is used to store the scratch and global memory descriptors + */ +typedef struct _cl_dispatch_debug_info_amd +{ + cl_uint scratchMemoryDescriptor[4]; //! Scratch memory descriptors + cl_uint globalMemoryDescriptor[4]; //! Global memory descriptors +} cl_dispatch_debug_info_amd; + +/*! \brief AQL Packet Info + * + * This structure is used to store AQL packet informatin for kernel dispatch + */ +typedef struct _cl_aql_packet_info_amd +{ + unsigned int trapReservedVgprIndex; //! VGPR index reserved for trap + //! value is -1 when kernel was not compiled + //! in debug mode. + cl_uint scratchBufferWaveOffset; //! scratch buffer wave offset + //! value is -1 when kernel was not compiled + //! in debug mode or scratch buffer is not enabled + void *pointerToIsaBuffer; //! Pointer to buffer containing ISA + size_t sizeOfIsaBuffer; //! Size of the ISA buffer + + cl_uint numberOfVgprs; //! Number of VGPRs used by the kernel + cl_uint numberOfSgprs; //! Number of SGPRs used by the kernel + size_t sizeOfStaticGroupMemory; //! Static local memory used by the kernel +} cl_aql_packet_info_amd; + +/*! \brief Wave address + * + * This structure specifies the wave for the SQ control command + */ +typedef struct _cl_dbg_wave_addr_amd +{ + cl_uint shaderEngine : 2; //! Shader engine + cl_uint shaderArray : 1; //! Shader array + cl_uint computeUnit : 4; //! Compute unit + cl_uint simd : 2; //! SIMD id + cl_uint wave : 4; //! Wave id + cl_uint vmid : 4; //! VMID + cl_uint reserved : 15; + +} cl_dbg_wave_addr_amd; + +/*! \brief Pre-dispatch call back function signature + * + * This is the signature of the call back fuction before the kernel + * dispatch. The call back function is to indicate the start of the + * the kernel launch. It is used by the debugger. + */ +typedef void * (*cl_PreDispatchCallBackFunctionAMD) ( cl_device_id device, + void *ocl_event_handle, + const void *aql_packet, + void *acl_binary, + cl_ulong *device_trap_buffer, + void *user_args); + +/*! \brief Post-dispatch call back function signature + * + * This is the signature of the call back fuction after the kernel + * dispatch. The call back function is to indicate the completion of + * the the kernel launch. It is used by the debugger. + */ +typedef void * (*cl_PostDispatchCallBackFunctionAMD) ( cl_device_id device, + cl_ulong event, + void *user_args); + +/*! \brief Set up the dispatch call back function pointers + * + * \param device specifies the device to be used + * + * \param preDispatchFunction is the function to be called before dispatching the kernel + * + * \param postDispatchFunction is the function to be called after kernel execution + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetCallBackFunctionsAMD( + cl_device_id /* device */, + cl_PreDispatchCallBackFunctionAMD /* preDispatchFunction */, + cl_PostDispatchCallBackFunctionAMD /* postDispatchFunction */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Set up the arguments of the dispatch call back function + * + * \param device specifies the device to be used + * + * \param preDispatchArgs is the arguments for the pre-dispatch callback function + * + * \param postDispatchArgs is the arguments for the post-dispatch callback function + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetCallBackArgumentsAMD( + cl_device_id /* device */, + void * /* preDispatchArgs */, + void * /* postDispatchArgs */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Invalidate all cache on the device. + * + * \param device specifies the device to be used + * + * \param mask is the mask to specify which cache to be flush/invalidate + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgFlushCacheAMD( + cl_device_id /* device */, + cl_dbg_gpu_cache_mask_amd /* mask */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Set up an exception policy in the trap handler object + * + * \param device specifies the device to be used + * + * \param policy specifies the exception policy, which includes the exception mask, + * wave action, host action, wave mode. + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the policy is not specified (NULL) + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetExceptionPolicyAMD( + cl_device_id /* device */, + cl_dbg_exception_policy_amd * /* policy */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Get the exception policy in the trap handler object + * + * \param device specifies the device to be used + * + * \param policy is a pointer to the memory where the policy is returned + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the policy storage is not specified + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgGetExceptionPolicyAMD( + cl_device_id /* device */, + cl_dbg_exception_policy_amd * /* policy */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Set up the kernel execution mode in the trap handler object + * + * \param device specifies the device to be used + * + * \param mode specifies the kernel execution mode, which indicate whether single + * step mode is used, how many CUs are reserved. + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the mode is not specified, ie, has a NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetKernelExecutionModeAMD( + cl_device_id /* device */, + cl_dbg_kernel_exec_mode_amd * /* mode */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Get the kernel execution mode in the trap handler object + * + * \param device specifies the device to be used + * + * \param mode is a pointer to the memory where the exectuion mode is returned + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the mode storage is not specified, ie, has a NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgGetKernelExecutionModeAMD( + cl_device_id /* device */, + cl_dbg_kernel_exec_mode_amd * /* mode */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Create a debug event + * + * \param device specifies the device to be used + * + * \param autoReset is the auto reset flag + * + * \param pDebugEvent returns the debug event to be used for exception notification + * + * \param pEventId is the event ID, which is not used at this moment + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_OUT_OF_RESOURCES if fails to create the event + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgCreateEventAMD( + cl_device_id /* device */, + bool /* autoReset */, + cl_dbg_event_amd * /* pDebugEvent */, + cl_uint * /* pEventId */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Wait for a debug event to be signaled + * + * \param device specifies the device to be used + * + * \param pDebugEvent is the debug event to be waited for + * + * \param pEventId is the event ID, which is not used at this moment + * + * \param timeOut is the duration for waiting + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_EVENT_TIMEOUT_AMD if timeout occurs + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgWaitEventAMD( + cl_device_id /* device */, + cl_dbg_event_amd /* pDebugEvent */, + cl_uint /* pEventId */, + cl_uint /* timeOut */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Destroy a debug event + * + * \param device specifies the device to be used + * + * \param pDebugEvent is the debug event to be waited for + * + * \param pEventId is the event ID, which is not used at this moment + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pDebugEvent value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgDestroyEventAMD( + cl_device_id /* device */, + cl_dbg_event_amd * /* pDebugEvent */, + cl_uint * /* pEventId */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Register the debugger on a device + * + * \param context specifies the context for the debugger + * + * \param device specifies the device to be used + * + * \param pMessageStorge specifies the memory for trap message passing between KMD and OCL runtime + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_CONTEXT if the context is not valid + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the pMEssageStorge value is NULL + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_OUT_OF_RESOURCES if a host queue cannot be created for the debugger + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgRegisterDebuggerAMD( + cl_context /* context */, + cl_device_id /* device */, + volatile void * /* pMessageStorage */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Unregister the debugger on a device + * + * \param device specifies the device to be used + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgUnregisterDebuggerAMD( + cl_device_id /* device */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Setup the pointer of the acl_binary to be used by the debugger + * + * \param device specifies the device to be used + * + * \param aclBinary specifies the ACL binary to be used + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the aclBinary is not provided + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetAclBinaryAMD( + cl_device_id /* device */, + void * /* aclBinary */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Control the execution of wavefront on the GPU + * + * \param device specifies the device to be used + * + * \param action specifies the wave action - halt, resume, kill, debug + * + * \param mode specifies the wave mode + * + * \param trapID specifies the trap ID, which should be 0x7 + * + * \param waveAddress specifies the wave address for the wave control + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the waveMsg is not provided, invalid action or mode value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgWaveControlAMD( + cl_device_id /* device */, + cl_dbg_waves_action_amd /* action */, + cl_dbg_wave_mode_amd /* mode */, + cl_uint /* trapId */, + cl_dbg_wave_addr_amd /* waveAddress */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Set watch points on memory address ranges to generate exception events + * + * \param device specifies the device to be used + * + * \param numWatchPoints specifies the number of watch points + * + * \param watchMode is the array of watch mode for the watch points + * + * \param watchAddress is the array of watch address for the watch points + * + * \param watchMask is the array of mask for the watch points + * + * \param watchEvent is the array of event for the watch points + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the number of points <= 0, or other parameters is not specified + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgAddressWatchAMD( + cl_device_id /* device */, + cl_uint /* numWatchPoints */, + cl_dbg_address_watch_mode_amd * /* watchMode */, + void ** /* watchAddress */, + cl_ulong * /* watchMask */, + cl_dbg_event_amd * /* watchEvent */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Get the packaet information for kernel execution + * + * \param device specifies the device to be used + * + * \param aqlCodeInfo specifies the kernel code and its size + * + * \param packetInfo points to the memory for the packet information to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgGetAqlPacketInfoAMD( + cl_device_id /* device */, + const void * /* aqlCodeInfo */, + cl_aql_packet_info_amd * /* packetInfo */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Get the dispatch debug information + * + * \param device specifies the device to be used + * + * \param debugInfo points to the memory for the debug information to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgGetDispatchDebugInfoAMD( + cl_device_id /* device */, + cl_dispatch_debug_info_amd * /* debugInfo */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Map the video memory for the kernel code to allow host access + * + * \param device specifies the device to be used + * + * \param aqlCodeAddress is the memory points to the returned host memory address for the kernel code + * + * \param aqlCodeSize returns the size of the kernel code + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgMapKernelCodeAMD( + cl_device_id /* device */, + cl_ulong * /* aqlCodeAddress */, + cl_uint * /* aqlCodeSize */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Unmap the video memory for the kernel code + * + * \param device specifies the device to be used (no needed, just to be consistent) + * + * \param aqlCodeAddress is the memory points to the mapped memory address for the kernel code + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgUnmapKernelCodeAMD( + cl_device_id /* device */, + cl_ulong * /* aqlCodeAddress */ +) CL_API_SUFFIX__VERSION_2_0; + + +/*! \brief Map the shader scratch ring's video memory to allow CPU access + * + * \param device specifies the device to be used + * + * \param scratchRingAddr is the memory points to the returned host memory address for scratch ring + * + * \param scratchRingSize returns the size of the scratch ring + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgMapScratchRingAMD( + cl_device_id /* device */, + cl_ulong * /* scratchRingAddr */, + cl_uint * /* scratchRingSize */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Unmap the shader scratch ring's video memory + * + * \param device specifies the device to be used (no needed, just to be consistent) + * + * \param scratchRingAddr is the memory points to the mapped memory address for scratch ring + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgUnmapScratchRingAMD( + cl_device_id /* device */, + cl_ulong * /* scratchRingAddr */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Get the memory object associated with the kernel parameter + * + * \param device specifies the device to be used + * + * \param paramIdx is the index of of the kernel argument + * + * \param paramMem is pointer of the memory associated with the kernel argument to be returned + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if the paramIdx is less than zero, or the paramMem has NULL value + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + * - CL_INVALID_KERNEL_ARGS if it fails to get the memory object for the kernel argument + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgGetKernelParamMemAMD( + cl_device_id /* devicepointer */, + cl_uint /* paramIdx */, + cl_ulong * /* paramMem */ +) CL_API_SUFFIX__VERSION_2_0; + +/*! \brief Set value of a global memory object + * + * \param device specifies the device to be used + * + * \param memObject is the memory object handle to be assigned the value specified in srcMem. + * + * \param offset is offset of the memory object + * + * \param srcMem points to the memory which contains the values to be assigned to the memory + * + * \param size size (in bytes) of the srcMem + * + * \return One of the following values: + * - CL_SUCCESS if the event occurs before the timeout + * - CL_INVALID_DEVICE if the device is not valid + * - CL_INVALID_VALUE if memObj or srcPtr has NULL value, size <= 0 or offset < 0 + * - CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD if there is no HW DEBUG manager + */ +extern CL_API_ENTRY cl_int CL_API_CALL clHwDbgSetGlobalMemoryAMD( + cl_device_id /* device */, + void * /* memObject */, + cl_uint /* offset */, + void * /* srcMem */, + cl_uint /* size */ +) CL_API_SUFFIX__VERSION_2_0; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif /*__cplusplus*/ + +#endif /*__CL_DEBUGGER_AMD_H*/