Files
rocm-systems/opencl/api/opencl/amdocl/cl_debugger_amd.cpp
T
foreman e51bb49ce6 P4 to Git Change 1131897 by wchau@wchau_WINDOWS7_OCL on 2015/03/18 10:50:41
ECR #399840 - OpenCL Runtime HW Debug support development -  add support to the VI asics &  support the use case of debug registeration in a pre-dispatch callback function

	** Cross branch check-in with CL1131894

Affected files ...

... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_debugger_amd.cpp#7 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugmanager.cpp#9 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#501 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.hpp#139 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputrap.hpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#355 edit
2015-03-18 11:26:04 -04:00

953 lines
28 KiB
C++

//
// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
//
#include "cl_common.hpp"
#include "cl_debugger_amd.h"
#include <cstring>
/*! \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;
}
debugManager->flushCache(mask.ui32All);
return CL_SUCCESS;
}
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;
}
debugManager->setExceptionPolicy(policy);
return CL_SUCCESS;
}
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;
}
debugManager->getExceptionPolicy(policy);
return CL_SUCCESS;
}
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;
}
debugManager->setKernelExecutionMode(mode);
return CL_SUCCESS;
}
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;
}
debugManager->getKernelExecutionMode(mode);
return CL_SUCCESS;
}
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;
}
debugManager->destroyDebugEvent(pDebugEvent);
return CL_SUCCESS;
}
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;
}
if (NULL == as_amd(device)->hwDebugMgr()) {
return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD;
}
return as_amd(device)->hwDebugManagerInit(as_amd(context),
reinterpret_cast<uintptr_t>(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;
}
debugManager->unregisterDebugger();
return CL_SUCCESS;
}
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;
}
debugManager->wavefrontControl(action, mode, trapId, (void *) &waveAddress);
return CL_SUCCESS;
}
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;
}
debugManager->setAddressWatch(numWatchPoints, watchAddress, watchMask,
reinterpret_cast<cl_ulong *>(watchMode),
watchEvent);
return CL_SUCCESS;
}
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;
}
debugManager->getPacketAmdInfo(aqlCodeInfo, packetInfo);
return CL_SUCCESS;
}
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;
}
if (NULL == debugInfo) {
LogWarning("clHwDbgGetDispatchDebugInfoAMD: Invalid debug information pointer.");
return CL_INVALID_VALUE;
}
amd::HwDebugManager * debugManager = as_amd(device)->hwDebugMgr();
if (NULL == debugManager) {
return CL_HWDBG_MANAGER_NOT_AVAILABLE_AMD;
}
debugManager->getDispatchDebugInfo((void *) debugInfo);
return CL_SUCCESS;
}
RUNTIME_EXIT
/*! \brief Map the video memory for the kernel code to allow host access
*
* \param device specifies the device to be used
*
* \param aqlCodeInfo specifies the kernel code and its size
*
* \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,
void * aqlCodeInfo))
{
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->mapKernelCode(aqlCodeInfo);
return CL_SUCCESS;
}
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;
}
debugManager->mapScratchRing(scratchRingAddr, scratchRingSize);
return CL_SUCCESS;
}
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_mem * 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,
cl_mem 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;
}
if (0 > offset || 0 >= size) {
return CL_INVALID_VALUE;
}
amd::Memory* globalMem = as_amd(memObject);
debugManager->setGlobalMemory(globalMem, offset, srcMem, size);
return CL_SUCCESS;
}
RUNTIME_EXIT
/*! \brief Install the trap handler of a given type
*
* \param device specifies the device to be used
*
* \param trapType is the type of trap handler
*
* \param trapHandler is the pointer of trap handler (TBA)
*
* \param trapBuffer is the pointer of trap handler buffer (TMA)
*
* \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, clHwDbgInstallTrapAMD, (
cl_device_id device,
cl_dbg_trap_type_amd trapType,
cl_mem trapHandler,
cl_mem trapBuffer))
{
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;
}
amd::Memory* pTrapHandler = as_amd(trapHandler);
amd::Memory* pTrapBuffer = as_amd(trapBuffer);
debugManager->installTrap(trapType, pTrapHandler, pTrapBuffer);
return CL_SUCCESS;
}
RUNTIME_EXIT
/*! @}
* @}
*/