// // 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; } 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(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(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 /*! @} * @} */