2021-12-08 10:10:27 +00:00
/*
2025-01-06 22:12:14 +00:00
* Copyright ( C ) 2021 - 2025 Intel Corporation
2021-12-08 10:10:27 +00:00
*
* SPDX - License - Identifier : MIT
*
*/
# include "shared/source/debug_settings/debug_settings_manager.h"
2024-08-29 22:35:24 +00:00
# include "shared/source/execution_environment/execution_environment.h"
2022-10-28 09:25:16 +00:00
# include "shared/source/execution_environment/root_device_environment.h"
2024-03-18 23:41:10 +00:00
# include "shared/source/helpers/basic_math.h"
2024-07-15 10:22:52 +00:00
# include "shared/source/helpers/bit_helpers.h"
2023-01-24 15:33:52 +00:00
# include "shared/source/helpers/common_types.h"
2023-04-24 09:02:15 +00:00
# include "shared/source/helpers/constants.h"
2021-12-10 12:55:55 +00:00
# include "shared/source/helpers/debug_helpers.h"
2023-02-01 16:23:01 +00:00
# include "shared/source/helpers/gfx_core_helper.h"
2022-02-16 09:42:58 +00:00
# include "shared/source/helpers/hw_info.h"
# include "shared/source/helpers/ptr_math.h"
2022-02-28 13:56:41 +00:00
# include "shared/source/helpers/string.h"
2024-03-18 23:41:10 +00:00
# include "shared/source/memory_manager/graphics_allocation.h"
2021-12-10 12:55:55 +00:00
# include "shared/source/os_interface/linux/cache_info.h"
2024-03-18 23:41:10 +00:00
# include "shared/source/os_interface/linux/drm_buffer_object.h"
2022-10-28 09:25:16 +00:00
# include "shared/source/os_interface/linux/drm_neo.h"
2022-05-17 17:16:13 +00:00
# include "shared/source/os_interface/linux/drm_wrappers.h"
2023-06-20 07:34:12 +00:00
# include "shared/source/os_interface/linux/engine_info.h"
2022-07-15 13:12:14 +02:00
# include "shared/source/os_interface/linux/i915_prelim.h"
2021-12-08 10:10:27 +00:00
# include "shared/source/os_interface/linux/ioctl_helper.h"
2024-03-18 23:41:10 +00:00
# include "shared/source/os_interface/linux/os_context_linux.h"
2022-10-28 09:25:16 +00:00
# include "shared/source/os_interface/linux/sys_calls.h"
2023-03-10 12:28:11 +00:00
# include "shared/source/os_interface/product_helper.h"
2024-08-29 22:35:24 +00:00
# include "shared/source/utilities/logger.h"
2021-12-08 10:10:27 +00:00
2022-01-03 14:16:00 +00:00
# include <algorithm>
2021-12-10 12:55:55 +00:00
# include <cerrno>
# include <cstring>
2022-11-18 14:38:56 +00:00
# include <fcntl.h>
2022-10-11 12:36:19 +00:00
# include <iostream>
2021-12-15 11:08:44 +00:00
# include <sys/ioctl.h>
2021-12-10 12:55:55 +00:00
2021-12-08 10:10:27 +00:00
namespace NEO {
2023-12-27 16:23:42 +00:00
IoctlHelperPrelim20 : : IoctlHelperPrelim20 ( Drm & drmArg ) : IoctlHelperI915 ( drmArg ) {
2023-01-02 11:52:22 +00:00
const auto & productHelper = this - > drm . getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
handleExecBufferInNonBlockMode = productHelper . isNonBlockingGpuSubmissionSupported ( ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . ForceNonblockingExecbufferCalls . get ( ) ! = - 1 ) {
handleExecBufferInNonBlockMode = debugManager . flags . ForceNonblockingExecbufferCalls . get ( ) ;
2022-11-03 07:46:57 +00:00
}
if ( handleExecBufferInNonBlockMode ) {
2022-10-28 09:25:16 +00:00
auto fileDescriptor = this - > drm . getFileDescriptor ( ) ;
2023-10-10 14:49:54 +00:00
auto flags = SysCalls : : fcntl ( fileDescriptor , F_GETFL ) ;
[[maybe_unused]] auto status = SysCalls : : fcntl ( fileDescriptor , F_SETFL , flags | O_NONBLOCK ) ;
DEBUG_BREAK_IF ( status ! = 0 ) ;
2022-10-28 09:25:16 +00:00
}
} ;
2022-09-20 07:07:59 +00:00
bool IoctlHelperPrelim20 : : isSetPairAvailable ( ) {
int setPairSupported = 0 ;
GetParam getParam { } ;
getParam . param = PRELIM_I915_PARAM_HAS_SET_PAIR ;
getParam . value = & setPairSupported ;
2023-12-12 08:48:32 +00:00
int retVal = IoctlHelper : : ioctl ( DrmIoctl : : getparam , & getParam ) ;
2022-09-20 07:07:59 +00:00
if ( retVal ) {
return false ;
}
return setPairSupported ;
}
2023-03-08 04:06:00 +00:00
bool IoctlHelperPrelim20 : : isChunkingAvailable ( ) {
int chunkSupported = 0 ;
GetParam getParam { } ;
getParam . param = PRELIM_I915_PARAM_HAS_CHUNK_SIZE ;
getParam . value = & chunkSupported ;
2023-12-12 08:48:32 +00:00
int retVal = IoctlHelper : : ioctl ( DrmIoctl : : getparam , & getParam ) ;
2023-03-08 04:06:00 +00:00
if ( retVal ) {
return false ;
}
return chunkSupported ;
}
2023-06-20 07:34:12 +00:00
bool IoctlHelperPrelim20 : : getTopologyDataAndMap ( const HardwareInfo & hwInfo , DrmQueryTopologyData & topologyData , TopologyMap & topologyMap ) {
2023-12-13 09:05:31 +00:00
auto request = this - > getDrmParamValue ( DrmParam : : queryComputeSlices ) ;
2023-06-20 07:34:12 +00:00
auto engineInfo = drm . getEngineInfo ( ) ;
auto nTiles = hwInfo . gtSystemInfo . MultiTileArchInfo . TileCount ;
2023-11-30 08:32:25 +00:00
auto useNewQuery = debugManager . flags . UseNewQueryTopoIoctl . get ( ) & &
2023-06-20 07:34:12 +00:00
engineInfo & &
( nTiles > 0 ) ;
if ( useNewQuery ) {
bool success = true ;
int sliceCount = 0 ;
int subSliceCount = 0 ;
int euCount = 0 ;
for ( auto i = 0u ; i < nTiles ; i + + ) {
auto classInstance = engineInfo - > getEngineInstance ( i , hwInfo . capabilityTable . defaultEngineType ) ;
UNRECOVERABLE_IF ( ! classInstance ) ;
uint32_t flags = classInstance - > engineClass ;
flags | = ( classInstance - > engineInstance < < 8 ) ;
2023-10-02 14:26:33 +00:00
auto dataQuery = drm . query < uint64_t > ( request , flags ) ;
2023-06-20 07:34:12 +00:00
if ( dataQuery . empty ( ) ) {
success = false ;
break ;
}
auto data = reinterpret_cast < QueryTopologyInfo * > ( dataQuery . data ( ) ) ;
DrmQueryTopologyData tileTopologyData = { } ;
TopologyMapping mapping ;
if ( ! this - > translateTopologyInfo ( data , tileTopologyData , mapping ) ) {
success = false ;
break ;
}
// pick smallest config
sliceCount = ( sliceCount = = 0 ) ? tileTopologyData . sliceCount : std : : min ( sliceCount , tileTopologyData . sliceCount ) ;
subSliceCount = ( subSliceCount = = 0 ) ? tileTopologyData . subSliceCount : std : : min ( subSliceCount , tileTopologyData . subSliceCount ) ;
euCount = ( euCount = = 0 ) ? tileTopologyData . euCount : std : : min ( euCount , tileTopologyData . euCount ) ;
2024-07-23 21:03:35 +00:00
topologyData . maxSlices = std : : max ( topologyData . maxSlices , tileTopologyData . maxSlices ) ;
topologyData . maxSubSlicesPerSlice = std : : max ( topologyData . maxSubSlicesPerSlice , tileTopologyData . maxSubSlicesPerSlice ) ;
topologyData . maxEusPerSubSlice = std : : max ( topologyData . maxEusPerSubSlice , static_cast < int > ( data - > maxEusPerSubslice ) ) ;
2023-06-20 07:34:12 +00:00
topologyMap [ i ] = mapping ;
}
if ( success ) {
topologyData . sliceCount = sliceCount ;
topologyData . subSliceCount = subSliceCount ;
topologyData . euCount = euCount ;
return true ;
}
}
// fallback to DRM_I915_QUERY_TOPOLOGY_INFO
2023-12-27 16:23:42 +00:00
return IoctlHelperI915 : : getTopologyDataAndMap ( hwInfo , topologyData , topologyMap ) ;
2023-06-20 07:34:12 +00:00
}
2022-06-29 16:49:29 +00:00
bool IoctlHelperPrelim20 : : isVmBindAvailable ( ) {
2024-02-09 10:34:56 +00:00
const auto & productHelper = drm . getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
if ( ! productHelper . isNewResidencyModelSupported ( ) ) {
return false ;
}
2022-02-15 09:33:27 +00:00
int vmBindSupported = 0 ;
2022-05-24 16:13:02 +00:00
GetParam getParam { } ;
2022-02-15 09:33:27 +00:00
getParam . param = PRELIM_I915_PARAM_HAS_VM_BIND ;
getParam . value = & vmBindSupported ;
2023-12-12 08:48:32 +00:00
int retVal = IoctlHelper : : ioctl ( DrmIoctl : : getparam , & getParam ) ;
2022-02-15 09:33:27 +00:00
if ( retVal ) {
return false ;
}
return vmBindSupported ;
}
2024-05-22 13:31:31 +00:00
int IoctlHelperPrelim20 : : createGemExt ( const MemRegionsVec & memClassInstances , size_t allocSize , uint32_t & handle , uint64_t patIndex , std : : optional < uint32_t > vmId , int32_t pairHandle , bool isChunked , uint32_t numOfChunks , std : : optional < uint32_t > memPolicyMode , std : : optional < std : : vector < unsigned long > > memPolicyNodemask , std : : optional < bool > isCoherent ) {
2021-12-22 14:25:53 +00:00
uint32_t regionsSize = static_cast < uint32_t > ( memClassInstances . size ( ) ) ;
2021-12-28 13:19:45 +00:00
std : : vector < prelim_drm_i915_gem_memory_class_instance > regions ( regionsSize ) ;
2021-12-22 14:25:53 +00:00
for ( uint32_t i = 0 ; i < regionsSize ; i + + ) {
2021-12-28 13:19:45 +00:00
regions [ i ] . memory_class = memClassInstances [ i ] . memoryClass ;
regions [ i ] . memory_instance = memClassInstances [ i ] . memoryInstance ;
2021-12-22 14:25:53 +00:00
}
2021-12-08 10:10:27 +00:00
prelim_drm_i915_gem_object_param regionParam { } ;
2021-12-22 14:25:53 +00:00
regionParam . size = regionsSize ;
2021-12-28 13:19:45 +00:00
regionParam . data = reinterpret_cast < uintptr_t > ( regions . data ( ) ) ;
2021-12-08 10:10:27 +00:00
regionParam . param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_MEMORY_REGIONS ;
prelim_drm_i915_gem_create_ext_setparam setparamRegion { } ;
setparamRegion . base . name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM ;
setparamRegion . param = regionParam ;
2022-04-27 11:21:53 +00:00
prelim_drm_i915_gem_create_ext_vm_private vmPrivate { } ;
2022-09-20 07:07:59 +00:00
prelim_drm_i915_gem_create_ext_setparam pairSetparamRegion { } ;
2023-03-08 04:06:00 +00:00
prelim_drm_i915_gem_create_ext_setparam chunkingParamRegion { } ;
2023-12-06 19:30:05 +00:00
prelim_drm_i915_gem_create_ext_memory_policy memPolicy { } ;
2022-09-20 07:07:59 +00:00
2022-05-31 16:14:00 +00:00
if ( vmId ! = std : : nullopt ) {
2022-04-27 11:21:53 +00:00
vmPrivate . base . name = PRELIM_I915_GEM_CREATE_EXT_VM_PRIVATE ;
2022-05-31 16:14:00 +00:00
vmPrivate . vm_id = vmId . value ( ) ;
2022-09-20 07:07:59 +00:00
}
2023-12-06 19:30:05 +00:00
if ( memPolicyMode ! = std : : nullopt ) {
UNRECOVERABLE_IF ( memPolicyNodemask = = std : : nullopt ) ;
memPolicy . base . name = PRELIM_I915_GEM_CREATE_EXT_MEMORY_POLICY ;
memPolicy . mode = memPolicyMode . value ( ) ;
memPolicy . flags = 0 ;
memPolicy . nodemask_max = static_cast < uint32_t > ( memPolicyNodemask . value ( ) . size ( ) ) ;
memPolicy . nodemask_ptr = reinterpret_cast < uintptr_t > ( memPolicyNodemask . value ( ) . data ( ) ) ;
}
2022-09-20 07:07:59 +00:00
if ( pairHandle ! = - 1 ) {
pairSetparamRegion . base . name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM ;
pairSetparamRegion . param . param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_SET_PAIR ;
pairSetparamRegion . param . data = pairHandle ;
}
2023-07-26 00:59:11 +00:00
size_t chunkingSize = 0u ;
2023-03-08 04:06:00 +00:00
if ( isChunked ) {
2023-07-26 00:59:11 +00:00
chunkingSize = allocSize / numOfChunks ;
2023-03-08 04:06:00 +00:00
chunkingParamRegion . base . name = PRELIM_I915_GEM_CREATE_EXT_SETPARAM ;
chunkingParamRegion . param . param = PRELIM_I915_OBJECT_PARAM | PRELIM_I915_PARAM_SET_CHUNK_SIZE ;
UNRECOVERABLE_IF ( chunkingSize & ( MemoryConstants : : pageSize64k - 1 ) ) ;
chunkingParamRegion . param . data = chunkingSize ;
setparamRegion . base . next_extension = reinterpret_cast < uintptr_t > ( & chunkingParamRegion ) ;
2023-12-06 19:30:05 +00:00
if ( memPolicyMode ! = std : : nullopt ) {
chunkingParamRegion . base . next_extension = reinterpret_cast < uintptr_t > ( & memPolicy ) ;
}
2023-03-08 04:06:00 +00:00
} else {
2023-12-06 19:30:05 +00:00
auto * lastExtension = & ( setparamRegion . base ) ;
2023-03-08 04:06:00 +00:00
if ( vmId ! = std : : nullopt ) {
setparamRegion . base . next_extension = reinterpret_cast < uintptr_t > ( & vmPrivate ) ;
2023-12-06 19:30:05 +00:00
lastExtension = & ( vmPrivate . base ) ;
}
if ( pairHandle ! = - 1 ) {
lastExtension - > next_extension = reinterpret_cast < uintptr_t > ( & pairSetparamRegion ) ;
lastExtension = & ( pairSetparamRegion . base ) ;
}
if ( memPolicyMode ! = std : : nullopt ) {
lastExtension - > next_extension = reinterpret_cast < uintptr_t > ( & memPolicy ) ;
2023-03-08 04:06:00 +00:00
}
2022-04-27 11:21:53 +00:00
}
2021-12-08 10:10:27 +00:00
prelim_drm_i915_gem_create_ext createExt { } ;
createExt . size = allocSize ;
2023-12-06 19:30:05 +00:00
2021-12-08 10:10:27 +00:00
createExt . extensions = reinterpret_cast < uintptr_t > ( & setparamRegion ) ;
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) , stdout , " Performing GEM_CREATE_EXT with { size: %lu, param: 0x%llX " ,
2021-12-08 10:10:27 +00:00
allocSize , regionParam . param ) ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) ) {
2021-12-22 14:25:53 +00:00
for ( uint32_t i = 0 ; i < regionsSize ; i + + ) {
2021-12-28 13:19:45 +00:00
auto region = regions [ i ] ;
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) , stdout , " , memory class: %d, memory instance: %d " ,
2021-12-08 10:10:27 +00:00
region . memory_class , region . memory_instance ) ;
}
2023-12-06 19:30:05 +00:00
if ( memPolicyMode ! = std : : nullopt ) {
printDebugString ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) , stdout ,
" , memory policy:{ mode: %d, nodemask_max: 0x%d, nodemask_ptr: 0x%llX } " ,
memPolicy . mode ,
memPolicy . nodemask_max ,
memPolicy . nodemask_ptr ) ;
}
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) , stdout , " %s " , " } \n " ) ;
2021-12-08 10:10:27 +00:00
}
2023-12-06 19:30:05 +00:00
auto ret = ioctl ( DrmIoctl : : gemCreateExt , & createExt ) ;
2021-12-08 10:10:27 +00:00
2023-07-26 00:59:11 +00:00
if ( isChunked ) {
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOChunkingLogs . get ( ) , stdout ,
2023-07-26 00:59:11 +00:00
" GEM_CREATE_EXT BO-%d with BOChunkingSize %d, chunkingParamRegion.param.data %d, numOfChunks %d \n " ,
createExt . handle ,
chunkingSize ,
chunkingParamRegion . param . data ,
numOfChunks ) ;
}
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintBOCreateDestroyResult . get ( ) , stdout , " GEM_CREATE_EXT has returned: %d BO-%u with size: %lu \n " , ret , createExt . handle , createExt . size ) ;
2021-12-08 10:10:27 +00:00
handle = createExt . handle ;
return ret ;
}
2024-12-04 15:54:56 +00:00
CacheRegion IoctlHelperPrelim20 : : closAlloc ( CacheLevel cacheLevel ) {
2021-12-10 12:55:55 +00:00
struct prelim_drm_i915_gem_clos_reserve clos = { } ;
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemClosReserve , & clos ) ;
2021-12-10 12:55:55 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_CLOS_RESERVE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
2021-12-10 12:55:55 +00:00
DEBUG_BREAK_IF ( true ) ;
2023-12-05 12:06:54 +00:00
return CacheRegion : : none ;
2021-12-10 12:55:55 +00:00
}
return static_cast < CacheRegion > ( clos . clos_index ) ;
}
2022-06-29 16:49:29 +00:00
uint16_t IoctlHelperPrelim20 : : closAllocWays ( CacheRegion closIndex , uint16_t cacheLevel , uint16_t numWays ) {
2021-12-10 12:55:55 +00:00
struct prelim_drm_i915_gem_cache_reserve cache = { } ;
cache . clos_index = static_cast < uint16_t > ( closIndex ) ;
cache . cache_level = cacheLevel ;
cache . num_ways = numWays ;
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemCacheReserve , & cache ) ;
2021-12-10 12:55:55 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_CACHE_RESERVE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
2021-12-10 12:55:55 +00:00
return 0 ;
}
return cache . num_ways ;
}
2022-06-29 16:49:29 +00:00
CacheRegion IoctlHelperPrelim20 : : closFree ( CacheRegion closIndex ) {
2021-12-10 12:55:55 +00:00
struct prelim_drm_i915_gem_clos_free clos = { } ;
clos . clos_index = static_cast < uint16_t > ( closIndex ) ;
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemClosFree , & clos ) ;
2021-12-10 12:55:55 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2023-11-30 08:32:25 +00:00
printDebugString ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " ioctl(I915_GEM_CLOS_FREE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
2021-12-10 12:55:55 +00:00
DEBUG_BREAK_IF ( true ) ;
2023-12-05 12:06:54 +00:00
return CacheRegion : : none ;
2021-12-10 12:55:55 +00:00
}
return closIndex ;
}
2022-06-29 16:49:29 +00:00
int IoctlHelperPrelim20 : : waitUserFence ( uint32_t ctxId , uint64_t address ,
2024-04-25 17:45:21 +00:00
uint64_t value , uint32_t dataWidth , int64_t timeout , uint16_t flags ,
2024-05-07 11:47:34 +00:00
bool userInterrupt , uint32_t externalInterruptId , GraphicsAllocation * allocForInterruptWait ) {
2021-12-14 09:46:01 +00:00
prelim_drm_i915_gem_wait_user_fence wait = { } ;
wait . ctx_id = ctxId ;
wait . flags = flags ;
switch ( dataWidth ) {
case 3u :
wait . mask = PRELIM_I915_UFENCE_WAIT_U64 ;
break ;
case 2u :
wait . mask = PRELIM_I915_UFENCE_WAIT_U32 ;
break ;
case 1u :
wait . mask = PRELIM_I915_UFENCE_WAIT_U16 ;
break ;
default :
wait . mask = PRELIM_I915_UFENCE_WAIT_U8 ;
break ;
}
wait . op = PRELIM_I915_UFENCE_WAIT_GTE ;
wait . addr = address ;
wait . value = value ;
wait . timeout = timeout ;
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : gemWaitUserFence , & wait ) ;
2021-12-14 09:46:01 +00:00
}
2021-12-14 14:09:19 +00:00
uint32_t IoctlHelperPrelim20 : : getAtomicAdvise ( bool isNonAtomic ) {
return isNonAtomic ? PRELIM_I915_VM_ADVISE_ATOMIC_NONE : PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM ;
}
2023-09-20 22:34:19 +00:00
uint32_t IoctlHelperPrelim20 : : getAtomicAccess ( AtomicAccessMode mode ) {
uint32_t retVal = 0 ;
switch ( mode ) {
2023-12-05 12:06:54 +00:00
case AtomicAccessMode : : device :
2023-09-20 22:34:19 +00:00
retVal = PRELIM_I915_VM_ADVISE_ATOMIC_DEVICE ;
break ;
2023-12-05 12:06:54 +00:00
case AtomicAccessMode : : system :
2023-09-20 22:34:19 +00:00
retVal = PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM ;
break ;
2023-12-05 12:06:54 +00:00
case AtomicAccessMode : : none :
2023-09-20 22:34:19 +00:00
retVal = PRELIM_I915_VM_ADVISE_ATOMIC_NONE ;
break ;
2023-12-05 12:06:54 +00:00
case AtomicAccessMode : : host :
2023-09-20 22:34:19 +00:00
default :
break ;
}
return retVal ;
}
2021-12-14 14:09:19 +00:00
uint32_t IoctlHelperPrelim20 : : getPreferredLocationAdvise ( ) {
return PRELIM_I915_VM_ADVISE_PREFERRED_LOCATION ;
}
2023-04-21 00:36:45 +00:00
std : : optional < MemoryClassInstance > IoctlHelperPrelim20 : : getPreferredLocationRegion ( PreferredLocation memoryLocation , uint32_t memoryInstance ) {
2023-03-30 12:42:02 +00:00
MemoryClassInstance region { } ;
2023-11-30 08:32:25 +00:00
if ( NEO : : debugManager . flags . SetVmAdvisePreferredLocation . get ( ) ! = - 1 ) {
memoryLocation = static_cast < PreferredLocation > ( NEO : : debugManager . flags . SetVmAdvisePreferredLocation . get ( ) ) ;
2023-04-21 00:36:45 +00:00
}
switch ( memoryLocation ) {
2023-12-05 12:06:54 +00:00
case PreferredLocation : : clear :
2023-04-21 00:36:45 +00:00
region . memoryClass = - 1 ;
region . memoryInstance = 0 ;
break ;
2023-12-05 12:06:54 +00:00
case PreferredLocation : : system :
2023-12-13 09:05:31 +00:00
region . memoryClass = getDrmParamValue ( DrmParam : : memoryClassSystem ) ;
2023-03-30 12:42:02 +00:00
region . memoryInstance = 0 ;
break ;
2023-12-05 12:06:54 +00:00
case PreferredLocation : : device :
2023-03-30 12:42:02 +00:00
default :
2023-12-13 09:05:31 +00:00
region . memoryClass = getDrmParamValue ( DrmParam : : memoryClassDevice ) ;
2023-04-10 22:40:54 +00:00
region . memoryInstance = memoryInstance ;
2023-03-30 12:42:02 +00:00
break ;
2023-12-05 12:06:54 +00:00
case PreferredLocation : : none :
2023-03-30 12:42:02 +00:00
return std : : nullopt ;
}
return region ;
}
2023-03-08 04:06:00 +00:00
bool IoctlHelperPrelim20 : : setVmBoAdviseForChunking ( int32_t handle , uint64_t start , uint64_t length , uint32_t attribute , void * region ) {
prelim_drm_i915_gem_vm_advise vmAdvise { } ;
vmAdvise . handle = handle ;
vmAdvise . start = start ;
vmAdvise . length = length ;
vmAdvise . attribute = attribute ;
UNRECOVERABLE_IF ( region = = nullptr ) ;
vmAdvise . region = * reinterpret_cast < prelim_drm_i915_gem_memory_class_instance * > ( region ) ;
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemVmAdvise , & vmAdvise ) ;
2023-03-08 04:06:00 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2024-08-29 22:35:24 +00:00
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , str . get ( ) ) ;
2023-03-08 04:06:00 +00:00
DEBUG_BREAK_IF ( true ) ;
2024-08-29 22:35:24 +00:00
2023-03-08 04:06:00 +00:00
return false ;
}
return true ;
}
2022-06-29 16:49:29 +00:00
bool IoctlHelperPrelim20 : : setVmBoAdvise ( int32_t handle , uint32_t attribute , void * region ) {
2021-12-14 14:09:19 +00:00
prelim_drm_i915_gem_vm_advise vmAdvise { } ;
vmAdvise . handle = handle ;
vmAdvise . attribute = attribute ;
if ( region ! = nullptr ) {
vmAdvise . region = * reinterpret_cast < prelim_drm_i915_gem_memory_class_instance * > ( region ) ;
}
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemVmAdvise , & vmAdvise ) ;
2021-12-14 14:09:19 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2024-08-29 22:35:24 +00:00
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_I915_GEM_VM_ADVISE) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , str . get ( ) ) ;
2021-12-14 14:09:19 +00:00
DEBUG_BREAK_IF ( true ) ;
2024-08-29 22:35:24 +00:00
2021-12-14 14:09:19 +00:00
return false ;
}
return true ;
}
2022-11-15 12:15:28 +00:00
bool IoctlHelperPrelim20 : : setVmPrefetch ( uint64_t start , uint64_t length , uint32_t region , uint32_t vmId ) {
2022-03-02 13:38:28 +00:00
prelim_drm_i915_gem_vm_prefetch vmPrefetch { } ;
vmPrefetch . length = length ;
vmPrefetch . region = region ;
vmPrefetch . start = start ;
2022-12-02 09:14:03 +00:00
vmPrefetch . vm_id = vmId ;
2022-03-02 13:38:28 +00:00
2023-12-12 08:48:32 +00:00
int ret = IoctlHelper : : ioctl ( DrmIoctl : : gemVmPrefetch , & vmPrefetch ) ;
2022-03-02 13:38:28 +00:00
if ( ret ! = 0 ) {
int err = errno ;
2024-08-29 22:35:24 +00:00
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_I915_GEM_VM_PREFETCH) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , str . get ( ) ) ;
2022-03-02 13:38:28 +00:00
DEBUG_BREAK_IF ( true ) ;
2024-08-29 22:35:24 +00:00
2022-03-02 13:38:28 +00:00
return false ;
}
return true ;
}
2021-12-14 12:41:38 +00:00
uint32_t IoctlHelperPrelim20 : : getDirectSubmissionFlag ( ) {
2022-03-29 17:48:12 +00:00
return PRELIM_I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING ;
2021-12-14 12:41:38 +00:00
}
2022-02-11 15:03:58 +00:00
uint16_t IoctlHelperPrelim20 : : getWaitUserFenceSoftFlag ( ) {
return PRELIM_I915_UFENCE_WAIT_SOFT ;
} ;
2022-11-22 13:53:59 +00:00
int IoctlHelperPrelim20 : : execBuffer ( ExecBuffer * execBuffer , uint64_t completionGpuAddress , TaskCountType counterValue ) {
2022-02-16 09:42:58 +00:00
prelim_drm_i915_gem_execbuffer_ext_user_fence fenceObject = { } ;
if ( completionGpuAddress ! = 0 ) {
fenceObject . base . name = PRELIM_DRM_I915_GEM_EXECBUFFER_EXT_USER_FENCE ;
fenceObject . addr = completionGpuAddress ;
fenceObject . value = counterValue ;
2022-05-12 15:56:50 +00:00
auto & drmExecBuffer = * reinterpret_cast < drm_i915_gem_execbuffer2 * > ( execBuffer - > data ) ;
drmExecBuffer . flags | = I915_EXEC_USE_EXTENSIONS ;
drmExecBuffer . num_cliprects = 0 ;
drmExecBuffer . cliprects_ptr = castToUint64 ( & fenceObject ) ;
2022-10-11 12:36:19 +00:00
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . PrintCompletionFenceUsage . get ( ) ) {
2022-10-11 12:36:19 +00:00
std : : cout < < " Completion fence submitted. "
< < " GPU address: " < < std : : hex < < completionGpuAddress < < std : : dec
< < " , value: " < < counterValue < < std : : endl ;
}
2022-02-16 09:42:58 +00:00
}
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : gemExecbuffer2 , execBuffer ) ;
2022-02-16 09:42:58 +00:00
}
2022-05-27 11:01:46 +00:00
bool IoctlHelperPrelim20 : : completionFenceExtensionSupported ( const bool isVmBindAvailable ) {
return isVmBindAvailable ;
2022-02-16 09:42:58 +00:00
}
2025-01-06 22:12:14 +00:00
std : : unique_ptr < uint8_t [ ] > IoctlHelperPrelim20 : : prepareVmBindExt ( const StackVec < uint32_t , 2 > & bindExtHandles , uint64_t cookie ) {
2022-09-09 16:59:25 +00:00
static_assert ( std : : is_trivially_destructible_v < prelim_drm_i915_vm_bind_ext_uuid > ,
" Storage must be allowed to be reused without calling the destructor! " ) ;
static_assert ( alignof ( prelim_drm_i915_vm_bind_ext_uuid ) < = __STDCPP_DEFAULT_NEW_ALIGNMENT__ ,
" Alignment of a buffer returned via new[] operator must allow storing the required type! " ) ;
const auto bufferSize { sizeof ( prelim_drm_i915_vm_bind_ext_uuid ) * bindExtHandles . size ( ) } ;
2025-01-09 01:11:44 +01:00
std : : unique_ptr < uint8_t [ ] > extensionsBuffer { new uint8_t [ bufferSize ] } ;
2022-09-09 16:59:25 +00:00
auto extensions = new ( extensionsBuffer . get ( ) ) prelim_drm_i915_vm_bind_ext_uuid [ bindExtHandles . size ( ) ] ;
std : : memset ( extensionsBuffer . get ( ) , 0 , bufferSize ) ;
2022-02-14 19:34:50 +00:00
extensions [ 0 ] . uuid_handle = bindExtHandles [ 0 ] ;
extensions [ 0 ] . base . name = PRELIM_I915_VM_BIND_EXT_UUID ;
for ( size_t i = 1 ; i < bindExtHandles . size ( ) ; i + + ) {
extensions [ i - 1 ] . base . next_extension = reinterpret_cast < uint64_t > ( & extensions [ i ] ) ;
extensions [ i ] . uuid_handle = bindExtHandles [ i ] ;
extensions [ i ] . base . name = PRELIM_I915_VM_BIND_EXT_UUID ;
}
2022-09-09 16:59:25 +00:00
return extensionsBuffer ;
2022-02-14 19:34:50 +00:00
}
2024-03-28 08:06:58 +00:00
uint64_t IoctlHelperPrelim20 : : getFlagsForVmBind ( bool bindCapture , bool bindImmediate , bool bindMakeResident , bool bindLockedMemory , bool readOnlyResource ) {
2022-02-14 19:34:50 +00:00
uint64_t flags = 0u ;
if ( bindCapture ) {
flags | = PRELIM_I915_GEM_VM_BIND_CAPTURE ;
}
if ( bindImmediate ) {
flags | = PRELIM_I915_GEM_VM_BIND_IMMEDIATE ;
}
2024-03-28 08:06:58 +00:00
if ( bindMakeResident | | bindLockedMemory ) { // lockedMemory is equal to residency in i915_prelim
2022-02-14 19:34:50 +00:00
flags | = PRELIM_I915_GEM_VM_BIND_MAKE_RESIDENT ;
}
2024-03-27 12:52:30 +00:00
if ( readOnlyResource ) {
flags | = PRELIM_I915_GEM_VM_BIND_READONLY ;
}
2022-02-14 19:34:50 +00:00
return flags ;
}
2022-01-03 14:16:00 +00:00
prelim_drm_i915_query_distance_info translateToi915 ( const DistanceInfo & distanceInfo ) {
prelim_drm_i915_query_distance_info dist { } ;
dist . engine . engine_class = distanceInfo . engine . engineClass ;
dist . engine . engine_instance = distanceInfo . engine . engineInstance ;
dist . region . memory_class = distanceInfo . region . memoryClass ;
dist . region . memory_instance = distanceInfo . region . memoryInstance ;
return dist ;
}
2023-01-18 20:22:32 +00:00
int IoctlHelperPrelim20 : : queryDistances ( std : : vector < QueryItem > & queryItems , std : : vector < DistanceInfo > & distanceInfos ) {
2022-01-03 14:16:00 +00:00
std : : vector < prelim_drm_i915_query_distance_info > i915Distances ( distanceInfos . size ( ) ) ;
std : : transform ( distanceInfos . begin ( ) , distanceInfos . end ( ) , i915Distances . begin ( ) , translateToi915 ) ;
for ( auto i = 0u ; i < i915Distances . size ( ) ; i + + ) {
2022-05-17 21:40:34 +00:00
queryItems [ i ] . queryId = PRELIM_DRM_I915_QUERY_DISTANCE_INFO ;
2022-01-03 14:16:00 +00:00
queryItems [ i ] . length = sizeof ( prelim_drm_i915_query_distance_info ) ;
queryItems [ i ] . flags = 0u ;
2022-05-17 21:40:34 +00:00
queryItems [ i ] . dataPtr = reinterpret_cast < uint64_t > ( & i915Distances [ i ] ) ;
2022-01-03 14:16:00 +00:00
}
2022-05-24 16:13:02 +00:00
Query query { } ;
2022-07-18 12:53:55 +00:00
query . itemsPtr = reinterpret_cast < uint64_t > ( queryItems . data ( ) ) ;
2022-05-24 16:13:02 +00:00
query . numItems = static_cast < uint32_t > ( queryItems . size ( ) ) ;
2023-12-12 08:48:32 +00:00
auto ret = IoctlHelper : : ioctl ( DrmIoctl : : query , & query ) ;
2022-01-03 14:16:00 +00:00
for ( auto i = 0u ; i < i915Distances . size ( ) ; i + + ) {
2023-10-04 15:02:02 +00:00
queryItems [ i ] . dataPtr = 0u ;
2022-01-03 14:16:00 +00:00
distanceInfos [ i ] . distance = i915Distances [ i ] . distance ;
}
return ret ;
}
2024-08-13 11:27:54 +00:00
bool IoctlHelperPrelim20 : : isPageFaultSupported ( ) {
int pagefaultSupport { } ;
GetParam getParam { } ;
getParam . param = PRELIM_I915_PARAM_HAS_PAGE_FAULT ;
getParam . value = & pagefaultSupport ;
int retVal = ioctl ( DrmIoctl : : getparam , & getParam ) ;
if ( debugManager . flags . PrintIoctlEntries . get ( ) ) {
printf ( " DRM_IOCTL_I915_GETPARAM: param: PRELIM_I915_PARAM_HAS_PAGE_FAULT, output value: %d, retCode:% d \n " ,
* getParam . value ,
retVal ) ;
}
return ( retVal = = 0 ) & & ( pagefaultSupport > 0 ) ;
2022-02-10 16:16:37 +00:00
} ;
2022-02-28 13:56:41 +00:00
2024-07-11 07:18:02 +00:00
bool IoctlHelperPrelim20 : : isEuStallSupported ( ) {
return true ;
}
2025-01-31 15:18:39 +00:00
uint32_t IoctlHelperPrelim20 : : getEuStallFdParameter ( ) {
return PRELIM_I915_PERF_FLAG_FD_EU_STALL ;
}
bool IoctlHelperPrelim20 : : perfOpenEuStallStream ( uint32_t euStallFdParameter , uint32_t & samplingPeriodNs , uint64_t engineInstance , uint64_t notifyNReports , uint64_t gpuTimeStampfrequency , int32_t * stream ) {
static constexpr uint32_t maxDssBufferSize = 512 * MemoryConstants : : kiloByte ;
static constexpr uint32_t defaultPollPeriodNs = 10000000u ;
// Get sampling unit.
static constexpr uint32_t samplingClockGranularity = 251u ;
static constexpr uint32_t minSamplingUnit = 1u ;
static constexpr uint32_t maxSamplingUnit = 7u ;
uint64_t gpuClockPeriodNs = CommonConstants : : nsecPerSec / gpuTimeStampfrequency ;
uint64_t numberOfClocks = samplingPeriodNs / gpuClockPeriodNs ;
uint32_t samplingUnit = 0 ;
samplingUnit = std : : clamp ( static_cast < uint32_t > ( numberOfClocks / samplingClockGranularity ) , minSamplingUnit , maxSamplingUnit ) ;
samplingPeriodNs = samplingUnit * samplingClockGranularity * static_cast < uint32_t > ( gpuClockPeriodNs ) ;
// Populate the EU stall properties.
std : : array < uint64_t , 12u > properties ;
2022-07-18 12:53:55 +00:00
properties [ 0 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_BUF_SZ ;
2025-01-31 15:18:39 +00:00
properties [ 1 ] = maxDssBufferSize ;
2022-07-18 12:53:55 +00:00
properties [ 2 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_SAMPLE_RATE ;
2025-01-31 15:18:39 +00:00
properties [ 3 ] = samplingUnit ;
2022-07-18 12:53:55 +00:00
properties [ 4 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_POLL_PERIOD ;
2025-01-31 15:18:39 +00:00
properties [ 5 ] = defaultPollPeriodNs ;
2022-07-18 12:53:55 +00:00
properties [ 6 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_ENGINE_CLASS ;
properties [ 7 ] = prelim_drm_i915_gem_engine_class : : PRELIM_I915_ENGINE_CLASS_COMPUTE ;
properties [ 8 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_ENGINE_INSTANCE ;
2022-02-03 13:26:53 +00:00
properties [ 9 ] = engineInstance ;
2022-07-18 12:53:55 +00:00
properties [ 10 ] = prelim_drm_i915_eu_stall_property_id : : PRELIM_DRM_I915_EU_STALL_PROP_EVENT_REPORT_COUNT ;
2022-05-26 15:00:06 +00:00
properties [ 11 ] = notifyNReports ;
2022-02-03 13:26:53 +00:00
2025-01-31 15:18:39 +00:00
// Call perf open ioctl.
2024-03-15 13:41:38 +00:00
NEO : : PrelimI915 : : drm_i915_perf_open_param param = { } ;
param . flags = I915_PERF_FLAG_FD_CLOEXEC |
euStallFdParameter |
I915_PERF_FLAG_FD_NONBLOCK ;
param . num_properties = sizeof ( properties ) / 16 ;
param . properties_ptr = reinterpret_cast < uintptr_t > ( properties . data ( ) ) ;
2024-07-11 07:18:02 +00:00
* stream = ioctl ( DrmIoctl : : perfOpen , & param ) ;
2024-03-09 01:22:47 +00:00
if ( * stream < 0 ) {
PRINT_DEBUG_STRING ( NEO : : debugManager . flags . PrintDebugMessages . get ( ) & & ( * stream < 0 ) , stderr ,
" %s failed errno = %d | ret = %d \n " , " DRM_IOCTL_I915_PERF_OPEN " , errno , * stream ) ;
return false ;
}
auto ret = ioctl ( * stream , DrmIoctl : : perfEnable , 0 ) ;
PRINT_DEBUG_STRING ( NEO : : debugManager . flags . PrintDebugMessages . get ( ) & & ( ret < 0 ) , stderr ,
" %s failed errno = %d | ret = %d \n " , " I915_PERF_IOCTL_ENABLE " , errno , ret ) ;
return ( ret = = 0 ) ? true : false ;
}
bool IoctlHelperPrelim20 : : perfDisableEuStallStream ( int32_t * stream ) {
int disableStatus = ioctl ( * stream , DrmIoctl : : perfDisable , 0 ) ;
PRINT_DEBUG_STRING ( NEO : : debugManager . flags . PrintDebugMessages . get ( ) & & ( disableStatus < 0 ) , stderr ,
" I915_PERF_IOCTL_DISABLE failed errno = %d | ret = %d \n " , errno , disableStatus ) ;
int closeStatus = NEO : : SysCalls : : close ( * stream ) ;
PRINT_DEBUG_STRING ( NEO : : debugManager . flags . PrintDebugMessages . get ( ) & & ( closeStatus < 0 ) , stderr ,
" close() failed errno = %d | ret = %d \n " , errno , closeStatus ) ;
* stream = - 1 ;
return ( ( closeStatus = = 0 ) & & ( disableStatus = = 0 ) ) ? true : false ;
}
2022-02-15 16:46:35 +00:00
std : : unique_ptr < uint8_t [ ] > IoctlHelperPrelim20 : : createVmControlExtRegion ( const std : : optional < MemoryClassInstance > & regionInstanceClass ) {
if ( regionInstanceClass ) {
auto retVal = std : : make_unique < uint8_t [ ] > ( sizeof ( prelim_drm_i915_gem_vm_region_ext ) ) ;
auto regionExt = reinterpret_cast < prelim_drm_i915_gem_vm_region_ext * > ( retVal . get ( ) ) ;
* regionExt = { } ;
regionExt - > base . name = PRELIM_I915_GEM_VM_CONTROL_EXT_REGION ;
regionExt - > region . memory_class = regionInstanceClass . value ( ) . memoryClass ;
regionExt - > region . memory_instance = regionInstanceClass . value ( ) . memoryInstance ;
return retVal ;
}
return { } ;
}
2022-04-21 16:59:48 +00:00
uint32_t IoctlHelperPrelim20 : : getFlagsForVmCreate ( bool disableScratch , bool enablePageFault , bool useVmBind ) {
2022-02-15 16:46:35 +00:00
uint32_t flags = 0u ;
if ( disableScratch ) {
flags | = PRELIM_I915_VM_CREATE_FLAGS_DISABLE_SCRATCH ;
}
if ( enablePageFault ) {
flags | = PRELIM_I915_VM_CREATE_FLAGS_ENABLE_PAGE_FAULT ;
}
2022-04-21 16:59:48 +00:00
if ( useVmBind ) {
flags | = PRELIM_I915_VM_CREATE_FLAGS_USE_VM_BIND ;
}
2022-02-15 16:46:35 +00:00
return flags ;
}
2022-06-29 16:49:29 +00:00
uint32_t gemCreateContextExt ( IoctlHelper & ioctlHelper , GemContextCreateExt & gcc , GemContextCreateExtSetParam & extSetparam ) {
2022-02-14 16:26:25 +00:00
gcc . flags | = I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS ;
2022-05-23 15:05:47 +00:00
extSetparam . base . nextExtension = gcc . extensions ;
2022-02-14 16:26:25 +00:00
gcc . extensions = reinterpret_cast < uint64_t > ( & extSetparam ) ;
2023-12-12 08:48:32 +00:00
auto ioctlResult = ioctlHelper . ioctl ( DrmIoctl : : gemContextCreateExt , & gcc ) ;
2022-02-16 12:35:03 +00:00
UNRECOVERABLE_IF ( ioctlResult ! = 0 ) ;
2022-05-24 14:36:24 +00:00
return gcc . contextId ;
2022-02-14 16:26:25 +00:00
}
2022-06-29 16:49:29 +00:00
uint32_t gemCreateContextAcc ( IoctlHelper & ioctlHelper , GemContextCreateExt & gcc , uint16_t trigger , uint8_t granularity ) {
2022-02-14 16:26:25 +00:00
prelim_drm_i915_gem_context_param_acc paramAcc = { } ;
paramAcc . trigger = trigger ;
paramAcc . notify = 1 ;
paramAcc . granularity = granularity ;
2022-05-23 15:05:47 +00:00
DrmUserExtension userExt { } ;
2022-02-14 16:26:25 +00:00
userExt . name = I915_CONTEXT_CREATE_EXT_SETPARAM ;
2022-05-23 15:05:47 +00:00
GemContextParam ctxParam = { } ;
2022-02-14 16:26:25 +00:00
ctxParam . param = PRELIM_I915_CONTEXT_PARAM_ACC ;
2022-05-23 15:05:47 +00:00
ctxParam . contextId = 0 ;
2022-02-14 16:26:25 +00:00
ctxParam . size = sizeof ( paramAcc ) ;
ctxParam . value = reinterpret_cast < uint64_t > ( & paramAcc ) ;
2022-05-23 15:05:47 +00:00
GemContextCreateExtSetParam extSetparam { } ;
2022-02-14 16:26:25 +00:00
extSetparam . base = userExt ;
extSetparam . param = ctxParam ;
2022-06-29 16:49:29 +00:00
return gemCreateContextExt ( ioctlHelper , gcc , extSetparam ) ;
2022-02-14 16:26:25 +00:00
}
2022-06-29 16:49:29 +00:00
uint32_t IoctlHelperPrelim20 : : createContextWithAccessCounters ( GemContextCreateExt & gcc ) {
2022-02-14 16:26:25 +00:00
uint16_t trigger = 0 ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . AccessCountersTrigger . get ( ) ! = - 1 ) {
trigger = static_cast < uint16_t > ( debugManager . flags . AccessCountersTrigger . get ( ) ) ;
2022-02-14 16:26:25 +00:00
}
uint8_t granularity = PRELIM_I915_CONTEXT_ACG_2M ;
2023-11-30 08:32:25 +00:00
if ( debugManager . flags . AccessCountersGranularity . get ( ) ! = - 1 ) {
granularity = static_cast < uint8_t > ( debugManager . flags . AccessCountersGranularity . get ( ) ) ;
2022-02-14 16:26:25 +00:00
}
2022-06-29 16:49:29 +00:00
return gemCreateContextAcc ( * this , gcc , trigger , granularity ) ;
2022-02-14 16:26:25 +00:00
}
2022-06-29 16:49:29 +00:00
uint32_t IoctlHelperPrelim20 : : createCooperativeContext ( GemContextCreateExt & gcc ) {
2022-05-23 15:05:47 +00:00
GemContextCreateExtSetParam extSetparam { } ;
2022-02-14 16:26:25 +00:00
extSetparam . base . name = I915_CONTEXT_CREATE_EXT_SETPARAM ;
extSetparam . param . param = PRELIM_I915_CONTEXT_PARAM_RUNALONE ;
2022-06-29 16:49:29 +00:00
return gemCreateContextExt ( * this , gcc , extSetparam ) ;
2022-02-14 16:26:25 +00:00
}
2022-02-15 12:15:54 +00:00
2022-04-05 17:04:53 +02:00
static_assert ( sizeof ( VmBindExtSetPatT ) = = sizeof ( prelim_drm_i915_vm_bind_ext_set_pat ) , " Invalid size for VmBindExtSetPat " ) ;
2022-02-15 12:15:54 +00:00
2022-04-05 17:04:53 +02:00
void IoctlHelperPrelim20 : : fillVmBindExtSetPat ( VmBindExtSetPatT & vmBindExtSetPat , uint64_t patIndex , uint64_t nextExtension ) {
auto prelimVmBindExtSetPat = reinterpret_cast < prelim_drm_i915_vm_bind_ext_set_pat * > ( vmBindExtSetPat ) ;
2022-02-15 12:15:54 +00:00
UNRECOVERABLE_IF ( ! prelimVmBindExtSetPat ) ;
prelimVmBindExtSetPat - > base . name = PRELIM_I915_VM_BIND_EXT_SET_PAT ;
prelimVmBindExtSetPat - > pat_index = patIndex ;
prelimVmBindExtSetPat - > base . next_extension = nextExtension ;
}
2022-04-05 17:04:53 +02:00
static_assert ( sizeof ( VmBindExtUserFenceT ) = = sizeof ( prelim_drm_i915_vm_bind_ext_user_fence ) , " Invalid size for VmBindExtUserFence " ) ;
2022-02-15 12:15:54 +00:00
2022-04-05 17:04:53 +02:00
void IoctlHelperPrelim20 : : fillVmBindExtUserFence ( VmBindExtUserFenceT & vmBindExtUserFence , uint64_t fenceAddress , uint64_t fenceValue , uint64_t nextExtension ) {
auto prelimVmBindExtUserFence = reinterpret_cast < prelim_drm_i915_vm_bind_ext_user_fence * > ( vmBindExtUserFence ) ;
2022-03-29 17:48:12 +00:00
UNRECOVERABLE_IF ( ! prelimVmBindExtUserFence ) ;
prelimVmBindExtUserFence - > base . name = PRELIM_I915_VM_BIND_EXT_USER_FENCE ;
prelimVmBindExtUserFence - > base . next_extension = nextExtension ;
prelimVmBindExtUserFence - > addr = fenceAddress ;
prelimVmBindExtUserFence - > val = fenceValue ;
2022-02-15 12:15:54 +00:00
}
2024-02-26 22:40:34 +00:00
void IoctlHelperPrelim20 : : setVmBindUserFence ( VmBindParams & vmBind , VmBindExtUserFenceT vmBindUserFence ) {
vmBind . extensions = castToUint64 ( vmBindUserFence ) ;
return ;
}
2022-02-15 12:56:31 +00:00
2024-07-15 10:22:52 +00:00
EngineCapabilities : : Flags IoctlHelperPrelim20 : : getEngineCapabilitiesFlags ( uint64_t capabilities ) const {
EngineCapabilities : : Flags flags { } ;
flags . copyClassSaturateLink = isValueSet ( capabilities , PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK ) ;
flags . copyClassSaturatePCIE = isValueSet ( capabilities , PRELIM_I915_COPY_CLASS_CAP_SATURATE_PCIE ) ;
2022-02-15 12:56:31 +00:00
2024-07-15 10:22:52 +00:00
return flags ;
2022-02-15 12:56:31 +00:00
}
2024-08-13 11:27:54 +00:00
std : : optional < uint32_t > IoctlHelperPrelim20 : : getVmAdviseAtomicAttribute ( ) {
2023-11-30 08:32:25 +00:00
switch ( NEO : : debugManager . flags . SetVmAdviseAtomicAttribute . get ( ) ) {
2022-03-21 16:02:12 +00:00
case 0 :
return PRELIM_I915_VM_ADVISE_ATOMIC_NONE ;
case 1 :
return PRELIM_I915_VM_ADVISE_ATOMIC_DEVICE ;
default :
return PRELIM_I915_VM_ADVISE_ATOMIC_SYSTEM ;
}
}
2022-02-15 14:54:16 +00:00
prelim_drm_i915_gem_vm_bind translateVmBindParamsToPrelimStruct ( const VmBindParams & vmBindParams ) {
prelim_drm_i915_gem_vm_bind vmBind { } ;
vmBind . vm_id = vmBindParams . vmId ;
vmBind . handle = vmBindParams . handle ;
vmBind . start = vmBindParams . start ;
vmBind . offset = vmBindParams . offset ;
vmBind . length = vmBindParams . length ;
vmBind . flags = vmBindParams . flags ;
vmBind . extensions = vmBindParams . extensions ;
return vmBind ;
}
2022-06-29 16:49:29 +00:00
int IoctlHelperPrelim20 : : vmBind ( const VmBindParams & vmBindParams ) {
2022-02-15 14:54:16 +00:00
auto prelimVmBind = translateVmBindParamsToPrelimStruct ( vmBindParams ) ;
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : gemVmBind , & prelimVmBind ) ;
2022-02-15 14:54:16 +00:00
}
2022-06-29 16:49:29 +00:00
int IoctlHelperPrelim20 : : vmUnbind ( const VmBindParams & vmBindParams ) {
2022-02-15 14:54:16 +00:00
auto prelimVmBind = translateVmBindParamsToPrelimStruct ( vmBindParams ) ;
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : gemVmUnbind , & prelimVmBind ) ;
2022-02-15 14:54:16 +00:00
}
2022-02-28 13:56:41 +00:00
2024-02-26 07:57:36 +00:00
int IoctlHelperPrelim20 : : getResetStats ( ResetStats & resetStats , uint32_t * status , ResetStatsFault * resetStatsFault ) {
prelim_drm_i915_reset_stats prelimResetStats { } ;
prelimResetStats . ctx_id = resetStats . contextId ;
prelimResetStats . flags = resetStats . flags ;
const auto retVal = ioctl ( DrmIoctl : : getResetStatsPrelim , & prelimResetStats ) ;
if ( retVal ! = 0 ) {
return ioctl ( DrmIoctl : : getResetStats , & resetStats ) ;
}
resetStats . resetCount = prelimResetStats . reset_count ;
resetStats . batchActive = prelimResetStats . batch_active ;
resetStats . batchPending = prelimResetStats . batch_pending ;
if ( status ) {
* status = prelimResetStats . status ;
}
if ( resetStatsFault ) {
auto fault = reinterpret_cast < ResetStatsFault * > ( & ( prelimResetStats . fault ) ) ;
* resetStatsFault = * fault ;
}
return retVal ;
}
2022-06-29 16:49:29 +00:00
UuidRegisterResult IoctlHelperPrelim20 : : registerUuid ( const std : : string & uuid , uint32_t uuidClass , uint64_t ptr , uint64_t size ) {
2022-02-28 13:56:41 +00:00
prelim_drm_i915_uuid_control uuidControl = { } ;
memcpy_s ( uuidControl . uuid , sizeof ( uuidControl . uuid ) , uuid . c_str ( ) , uuid . size ( ) ) ;
uuidControl . uuid_class = uuidClass ;
uuidControl . ptr = ptr ;
uuidControl . size = size ;
2023-12-12 08:48:32 +00:00
const auto retVal = IoctlHelper : : ioctl ( DrmIoctl : : uuidRegister , & uuidControl ) ;
2022-02-28 13:56:41 +00:00
return {
retVal ,
uuidControl . handle ,
} ;
}
2022-06-29 16:49:29 +00:00
UuidRegisterResult IoctlHelperPrelim20 : : registerStringClassUuid ( const std : : string & uuid , uint64_t ptr , uint64_t size ) {
return registerUuid ( uuid , PRELIM_I915_UUID_CLASS_STRING , ptr , size ) ;
2022-02-28 13:56:41 +00:00
}
2022-06-29 16:49:29 +00:00
int IoctlHelperPrelim20 : : unregisterUuid ( uint32_t handle ) {
2022-02-28 13:56:41 +00:00
prelim_drm_i915_uuid_control uuidControl = { } ;
uuidControl . handle = handle ;
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : uuidUnregister , & uuidControl ) ;
2022-02-28 13:56:41 +00:00
}
2022-06-29 16:49:29 +00:00
bool IoctlHelperPrelim20 : : isContextDebugSupported ( ) {
2024-03-15 13:47:40 +00:00
GemContextParam ctxParam = { } ;
2022-02-28 13:56:41 +00:00
ctxParam . size = 0 ;
ctxParam . param = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAGS ;
2024-03-15 13:47:40 +00:00
ctxParam . contextId = 0 ;
2022-02-28 13:56:41 +00:00
ctxParam . value = 0 ;
2023-12-12 08:48:32 +00:00
const auto retVal = IoctlHelper : : ioctl ( DrmIoctl : : gemContextGetparam , & ctxParam ) ;
2022-02-28 13:56:41 +00:00
return retVal = = 0 & & ctxParam . value = = ( PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAG_SIP < < 32 ) ;
}
2022-06-29 16:49:29 +00:00
int IoctlHelperPrelim20 : : setContextDebugFlag ( uint32_t drmContextId ) {
2024-03-15 13:47:40 +00:00
GemContextParam ctxParam = { } ;
2022-02-28 13:56:41 +00:00
ctxParam . size = 0 ;
ctxParam . param = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAGS ;
2024-03-15 13:47:40 +00:00
ctxParam . contextId = drmContextId ;
2022-02-28 13:56:41 +00:00
ctxParam . value = PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAG_SIP < < 32 | PRELIM_I915_CONTEXT_PARAM_DEBUG_FLAG_SIP ;
2023-12-12 08:48:32 +00:00
return IoctlHelper : : ioctl ( DrmIoctl : : gemContextSetparam , & ctxParam ) ;
2022-02-28 13:56:41 +00:00
}
2022-03-25 18:51:25 +00:00
bool IoctlHelperPrelim20 : : isDebugAttachAvailable ( ) {
return true ;
}
2022-06-03 13:57:42 +00:00
unsigned int IoctlHelperPrelim20 : : getIoctlRequestValue ( DrmIoctl ioctlRequest ) const {
2022-05-25 17:05:52 +00:00
switch ( ioctlRequest ) {
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmBind :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_VM_BIND ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmUnbind :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_VM_UNBIND ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemWaitUserFence :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_WAIT_USER_FENCE ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemCreateExt :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_CREATE_EXT ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmAdvise :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_VM_ADVISE ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmPrefetch :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_VM_PREFETCH ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : uuidRegister :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_UUID_REGISTER ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : uuidUnregister :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : debuggerOpen :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_DEBUGGER_OPEN ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemClosReserve :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_CLOS_RESERVE ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemClosFree :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_CLOS_FREE ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemCacheReserve :
2022-05-25 17:05:52 +00:00
return PRELIM_DRM_IOCTL_I915_GEM_CACHE_RESERVE ;
2024-02-26 07:57:36 +00:00
case DrmIoctl : : getResetStatsPrelim :
return PRELIM_DRM_IOCTL_I915_GET_RESET_STATS ;
2022-05-25 17:05:52 +00:00
default :
2023-12-27 16:23:42 +00:00
return IoctlHelperI915 : : getIoctlRequestValue ( ioctlRequest ) ;
2022-05-25 17:05:52 +00:00
}
}
2022-06-01 13:04:38 +00:00
int IoctlHelperPrelim20 : : getDrmParamValue ( DrmParam drmParam ) const {
switch ( drmParam ) {
2023-12-13 09:05:31 +00:00
case DrmParam : : engineClassCompute :
2022-07-18 12:53:55 +00:00
return prelim_drm_i915_gem_engine_class : : PRELIM_I915_ENGINE_CLASS_COMPUTE ;
2023-12-13 09:05:31 +00:00
case DrmParam : : paramHasVmBind :
2022-06-06 15:48:31 +00:00
return PRELIM_I915_PARAM_HAS_VM_BIND ;
2023-12-13 09:05:31 +00:00
case DrmParam : : paramHasPageFault :
2022-06-06 15:48:31 +00:00
return PRELIM_I915_PARAM_HAS_PAGE_FAULT ;
2023-12-13 09:05:31 +00:00
case DrmParam : : queryHwconfigTable :
2022-06-01 16:03:01 +00:00
return PRELIM_DRM_I915_QUERY_HWCONFIG_TABLE ;
2023-12-13 09:05:31 +00:00
case DrmParam : : queryComputeSlices :
2022-10-31 14:51:26 +01:00
return PRELIM_DRM_I915_QUERY_COMPUTE_SUBSLICES ;
2022-06-01 13:04:38 +00:00
default :
2023-12-27 16:23:42 +00:00
return IoctlHelperI915 : : getDrmParamValueBase ( drmParam ) ;
2022-06-01 13:04:38 +00:00
}
}
2022-07-14 15:32:26 +00:00
std : : string IoctlHelperPrelim20 : : getDrmParamString ( DrmParam drmParam ) const {
switch ( drmParam ) {
2023-12-13 09:05:31 +00:00
case DrmParam : : paramHasVmBind :
2022-07-14 15:32:26 +00:00
return " PRELIM_I915_PARAM_HAS_VM_BIND " ;
2023-12-13 09:05:31 +00:00
case DrmParam : : paramHasPageFault :
2022-07-14 15:32:26 +00:00
return " PRELIM_I915_PARAM_HAS_PAGE_FAULT " ;
default :
2023-12-27 16:23:42 +00:00
return IoctlHelperI915 : : getDrmParamString ( drmParam ) ;
2022-07-14 15:32:26 +00:00
}
}
std : : string IoctlHelperPrelim20 : : getIoctlString ( DrmIoctl ioctlRequest ) const {
switch ( ioctlRequest ) {
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmBind :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_VM_BIND " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmUnbind :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_VM_UNBIND " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemWaitUserFence :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_WAIT_USER_FENCE " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemCreateExt :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_CREATE_EXT " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmAdvise :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_VM_ADVISE " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemVmPrefetch :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_VM_PREFETCH " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : uuidRegister :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_UUID_REGISTER " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : uuidUnregister :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : debuggerOpen :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_DEBUGGER_OPEN " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemClosReserve :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_CLOS_RESERVE " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemClosFree :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_CLOS_FREE " ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemCacheReserve :
2022-07-14 15:32:26 +00:00
return " PRELIM_DRM_IOCTL_I915_GEM_CACHE_RESERVE " ;
2024-02-26 07:57:36 +00:00
case DrmIoctl : : getResetStatsPrelim :
return " PRELIM_DRM_IOCTL_I915_GET_RESET_STATS " ;
2022-07-14 15:32:26 +00:00
default :
2023-12-27 16:23:42 +00:00
return IoctlHelperI915 : : getIoctlString ( ioctlRequest ) ;
2022-07-14 15:32:26 +00:00
}
}
2022-06-01 13:04:38 +00:00
2022-10-18 18:37:33 +00:00
bool IoctlHelperPrelim20 : : checkIfIoctlReinvokeRequired ( int error , DrmIoctl ioctlRequest ) const {
switch ( ioctlRequest ) {
2023-12-12 08:48:32 +00:00
case DrmIoctl : : debuggerOpen :
2022-10-18 18:37:33 +00:00
return ( error = = EINTR | | error = = EAGAIN ) ;
2023-12-12 08:48:32 +00:00
case DrmIoctl : : gemExecbuffer2 :
2022-10-28 09:25:16 +00:00
if ( handleExecBufferInNonBlockMode ) {
return ( error = = EINTR | | error = = EBUSY | | error = = - EBUSY ) ;
} else {
return IoctlHelper : : checkIfIoctlReinvokeRequired ( error , ioctlRequest ) ;
}
2022-10-18 18:37:33 +00:00
default :
break ;
}
return IoctlHelper : : checkIfIoctlReinvokeRequired ( error , ioctlRequest ) ;
}
2022-10-25 07:21:48 +00:00
bool IoctlHelperPrelim20 : : getFabricLatency ( uint32_t fabricId , uint32_t & latency , uint32_t & bandwidth ) {
2022-09-30 12:57:38 +00:00
Query query = { } ;
QueryItem queryItem = { } ;
PrelimI915 : : prelim_drm_i915_query_fabric_info info = { } ;
info . fabric_id = fabricId ;
queryItem . queryId = PRELIM_DRM_I915_QUERY_FABRIC_INFO ;
queryItem . length = static_cast < int32_t > ( sizeof ( info ) ) ;
queryItem . dataPtr = reinterpret_cast < uint64_t > ( & info ) ;
queryItem . flags = 0 ;
query . itemsPtr = reinterpret_cast < uint64_t > ( & queryItem ) ;
query . numItems = 1 ;
2023-12-12 08:48:32 +00:00
auto ret = IoctlHelper : : ioctl ( DrmIoctl : : query , & query ) ;
2022-09-30 12:57:38 +00:00
if ( ret ! = 0 ) {
return false ;
}
2022-10-25 07:21:48 +00:00
if ( info . latency < 10 | | info . bandwidth = = 0 ) {
2022-09-30 12:57:38 +00:00
return false ;
}
// Latency is in tenths of path length. 10 == 1 fabric link between src and dst
// 1 link = zero hops
latency = ( info . latency / 10 ) - 1 ;
2022-10-25 07:21:48 +00:00
bandwidth = info . bandwidth ;
2022-09-30 12:57:38 +00:00
return true ;
}
2023-03-17 13:00:44 +00:00
bool IoctlHelperPrelim20 : : isWaitBeforeBindRequired ( bool bind ) const {
2024-03-12 23:56:09 +00:00
bool userFenceOnUnbind = false ;
if ( debugManager . flags . EnableUserFenceUponUnbind . get ( ) ! = - 1 ) {
userFenceOnUnbind = ! ! debugManager . flags . EnableUserFenceUponUnbind . get ( ) ;
}
return ( bind | | userFenceOnUnbind ) ;
2023-03-17 13:00:44 +00:00
}
2023-04-24 09:02:15 +00:00
void * IoctlHelperPrelim20 : : pciBarrierMmap ( ) {
static constexpr uint64_t pciBarrierMmapOffset = 0x50 < < 12 ;
return SysCalls : : mmap ( NULL , MemoryConstants : : pageSize , PROT_WRITE , MAP_SHARED , drm . getFileDescriptor ( ) , pciBarrierMmapOffset ) ;
}
2022-10-31 13:57:24 +00:00
bool IoctlHelperPrelim20 : : queryHwIpVersion ( EngineClassInstance & engineInfo , HardwareIpVersion & ipVersion , int & ret ) {
QueryItem queryItem { } ;
queryItem . queryId = PRELIM_DRM_I915_QUERY_HW_IP_VERSION ;
Query query { } ;
query . itemsPtr = reinterpret_cast < uint64_t > ( & queryItem ) ;
query . numItems = 1u ;
2023-12-12 08:48:32 +00:00
ret = ioctl ( DrmIoctl : : query , & query ) ;
2022-10-31 13:57:24 +00:00
if ( ret ! = 0 ) {
return false ;
}
if ( queryItem . length ! = sizeof ( prelim_drm_i915_query_hw_ip_version ) ) {
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr , " %s \n " ,
2022-10-31 13:57:24 +00:00
" Size got from PRELIM_DRM_I915_QUERY_HW_IP_VERSION query does not match PrelimI915::prelim_drm_i915_query_hw_ip_version size " ) ;
return false ;
}
prelim_drm_i915_query_hw_ip_version queryHwIpVersion { } ;
queryHwIpVersion . engine . engine_class = engineInfo . engineClass ;
queryHwIpVersion . engine . engine_instance = engineInfo . engineInstance ;
queryItem . dataPtr = reinterpret_cast < uint64_t > ( & queryHwIpVersion ) ;
2023-12-12 08:48:32 +00:00
ret = ioctl ( DrmIoctl : : query , & query ) ;
2022-10-31 13:57:24 +00:00
if ( ret ! = 0 ) {
return false ;
}
ipVersion . architecture = queryHwIpVersion . arch ;
ipVersion . release = queryHwIpVersion . release ;
ipVersion . revision = queryHwIpVersion . stepping ;
return true ;
}
bool IoctlHelperPrelim20 : : initialize ( ) {
2023-09-18 10:49:16 +00:00
initializeGetGpuTimeFunction ( ) ;
2023-05-22 15:15:17 +00:00
return true ;
}
void IoctlHelperPrelim20 : : setupIpVersion ( ) {
auto & rootDeviceEnvironment = drm . getRootDeviceEnvironment ( ) ;
auto hwInfo = rootDeviceEnvironment . getMutableHardwareInfo ( ) ;
2023-06-12 13:02:20 +00:00
auto & productHelper = drm . getRootDeviceEnvironment ( ) . getHelper < ProductHelper > ( ) ;
2023-12-13 09:05:31 +00:00
EngineClassInstance engineInfo = { static_cast < uint16_t > ( getDrmParamValue ( DrmParam : : engineClassRender ) ) , 0 } ;
2022-10-31 13:57:24 +00:00
int ret = 0 ;
2023-01-02 11:52:22 +00:00
2023-06-12 13:02:20 +00:00
auto isPlatformQuerySupported = productHelper . isPlatformQuerySupported ( ) ;
bool result = false ;
if ( isPlatformQuerySupported ) {
result = queryHwIpVersion ( engineInfo , hwInfo - > ipVersion , ret ) ;
if ( result = = false & & ret ! = 0 ) {
int err = drm . getErrno ( ) ;
2023-11-30 08:32:25 +00:00
PRINT_DEBUG_STRING ( debugManager . flags . PrintDebugMessages . get ( ) , stderr ,
2023-06-12 13:02:20 +00:00
" ioctl(PRELIM_DRM_I915_QUERY_HW_IP_VERSION) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
}
2022-10-31 13:57:24 +00:00
}
2023-05-22 15:15:17 +00:00
if ( result = = false ) {
IoctlHelper : : setupIpVersion ( ) ;
}
2022-10-31 13:57:24 +00:00
}
2022-09-30 12:57:38 +00:00
2024-01-09 13:39:18 +00:00
bool IoctlHelperPrelim20 : : registerResourceClasses ( ) {
for ( auto & classNameUUID : classNamesToUuid ) {
auto className = classNameUUID . first ;
auto uuid = classNameUUID . second ;
const auto result = registerStringClassUuid ( uuid , ( uintptr_t ) className , strnlen_s ( className , 100 ) ) ;
if ( result . retVal ! = 0 ) {
return false ;
}
classHandles . push_back ( result . handle ) ;
}
return true ;
}
uint32_t IoctlHelperPrelim20 : : registerIsaCookie ( uint32_t isaHandle ) {
auto uuid = generateUUID ( ) ;
const auto result = registerUuid ( uuid , isaHandle , 0 , 0 ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_DRM_IOCTL_I915_UUID_REGISTER: isa handle = %lu, uuid = %s, data = %p, handle = %lu, ret = %d \n " , isaHandle , std : : string ( uuid , 36 ) . c_str ( ) , 0 , result . handle , result . retVal ) ;
2024-08-29 22:35:24 +00:00
if ( result . retVal ! = 0 ) {
int err = errno ;
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s) \n " , result . retVal , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
DEBUG_BREAK_IF ( true ) ;
}
2024-01-09 13:39:18 +00:00
return result . handle ;
}
void IoctlHelperPrelim20 : : unregisterResource ( uint32_t handle ) {
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER: handle = %lu \n " , handle ) ;
[[maybe_unused]] const auto ret = unregisterUuid ( handle ) ;
2024-08-29 22:35:24 +00:00
if ( ret ! = 0 ) {
int err = errno ;
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_IOCTL_I915_UUID_UNREGISTER) failed with %d. errno=%d(%s) \n " , ret , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
DEBUG_BREAK_IF ( true ) ;
}
2024-01-09 13:39:18 +00:00
}
std : : string IoctlHelperPrelim20 : : generateUUID ( ) {
const char uuidString [ ] = " 00000000-0000-0000-%04 " SCNx64 " -%012 " SCNx64 ;
char buffer [ 36 + 1 ] = " 00000000-0000-0000-0000-000000000000 " ;
uuid + + ;
UNRECOVERABLE_IF ( uuid = = 0xFFFFFFFFFFFFFFFF ) ;
uint64_t parts [ 2 ] = { 0 , 0 } ;
parts [ 0 ] = uuid & 0xFFFFFFFFFFFF ;
parts [ 1 ] = ( uuid & 0xFFFF000000000000 ) > > 48 ;
snprintf ( buffer , sizeof ( buffer ) , uuidString , parts [ 1 ] , parts [ 0 ] ) ;
return std : : string ( buffer , 36 ) ;
}
std : : string IoctlHelperPrelim20 : : generateElfUUID ( const void * data ) {
std : : string elfClassUuid = classNamesToUuid [ static_cast < uint32_t > ( DrmResourceClass : : elf ) ] . second ;
std : : string uuiD1st = elfClassUuid . substr ( 0 , 18 ) ;
const char uuidString [ ] = " %s-%04 " SCNx64 " -%012 " SCNx64 ;
char buffer [ 36 + 1 ] = " 00000000-0000-0000-0000-000000000000 " ;
uint64_t parts [ 2 ] = { 0 , 0 } ;
parts [ 0 ] = reinterpret_cast < uintptr_t > ( data ) & 0xFFFFFFFFFFFF ;
parts [ 1 ] = ( reinterpret_cast < uintptr_t > ( data ) & 0xFFFF000000000000 ) > > 48 ;
snprintf ( buffer , sizeof ( buffer ) , uuidString , uuiD1st . c_str ( ) , parts [ 1 ] , parts [ 0 ] ) ;
return std : : string ( buffer , 36 ) ;
}
uint32_t IoctlHelperPrelim20 : : registerResource ( DrmResourceClass classType , const void * data , size_t size ) {
const auto classIndex = static_cast < uint32_t > ( classType ) ;
if ( classHandles . size ( ) < = classIndex ) {
return 0 ;
}
std : : string uuid ;
if ( classType = = NEO : : DrmResourceClass : : elf ) {
uuid = generateElfUUID ( data ) ;
} else {
uuid = generateUUID ( ) ;
}
const auto uuidClass = classHandles [ classIndex ] ;
const auto ptr = size > 0 ? ( uintptr_t ) data : 0 ;
const auto result = registerUuid ( uuid , uuidClass , ptr , size ) ;
PRINT_DEBUGGER_INFO_LOG ( " PRELIM_DRM_IOCTL_I915_UUID_REGISTER: classType = %d, uuid = %s, data = %p, handle = %lu, ret = %d \n " , ( int ) classType , std : : string ( uuid , 36 ) . c_str ( ) , ptr , result . handle , result . retVal ) ;
2024-08-29 22:35:24 +00:00
if ( result . retVal ! = 0 ) {
int err = errno ;
CREATE_DEBUG_STRING ( str , " ioctl(PRELIM_DRM_IOCTL_I915_UUID_REGISTER) failed with %d. errno=%d(%s) \n " , result . retVal , err , strerror ( err ) ) ;
drm . getRootDeviceEnvironment ( ) . executionEnvironment . setErrorDescription ( std : : string ( str . get ( ) ) ) ;
DEBUG_BREAK_IF ( true ) ;
}
2024-01-09 13:39:18 +00:00
return result . handle ;
}
uint32_t IoctlHelperPrelim20 : : notifyFirstCommandQueueCreated ( const void * data , size_t size ) {
const auto result = registerStringClassUuid ( uuidL0CommandQueueHash , ( uintptr_t ) data , size ) ;
DEBUG_BREAK_IF ( result . retVal ) ;
return result . handle ;
}
void IoctlHelperPrelim20 : : notifyLastCommandQueueDestroyed ( uint32_t handle ) {
unregisterResource ( handle ) ;
}
2024-01-23 22:32:35 +00:00
int IoctlHelperPrelim20 : : getEuDebugSysFsEnable ( ) {
char enabledEuDebug = ' 0 ' ;
std : : string sysFsPciPath = drm . getSysFsPciPath ( ) ;
std : : string euDebugPath = sysFsPciPath + " /prelim_enable_eu_debug " ;
FILE * fileDescriptor = IoFunctions : : fopenPtr ( euDebugPath . c_str ( ) , " r " ) ;
if ( fileDescriptor ) {
[[maybe_unused]] auto bytesRead = IoFunctions : : freadPtr ( & enabledEuDebug , 1 , 1 , fileDescriptor ) ;
IoFunctions : : fclosePtr ( fileDescriptor ) ;
}
return enabledEuDebug - ' 0 ' ;
}
2024-02-26 07:57:36 +00:00
bool IoctlHelperPrelim20 : : validPageFault ( uint16_t flags ) {
if ( ( flags & I915_RESET_STATS_FAULT_VALID ) ! = 0 ) {
return true ;
}
return false ;
}
uint32_t IoctlHelperPrelim20 : : getStatusForResetStats ( bool banned ) {
uint32_t retVal = 0u ;
if ( banned ) {
retVal | = I915_RESET_STATS_BANNED ;
}
return retVal ;
}
2024-03-18 23:41:10 +00:00
void IoctlHelperPrelim20 : : registerBOBindHandle ( Drm * drm , DrmAllocation * drmAllocation ) {
DrmResourceClass resourceClass = DrmResourceClass : : maxSize ;
switch ( drmAllocation - > getAllocationType ( ) ) {
case AllocationType : : debugContextSaveArea :
resourceClass = DrmResourceClass : : contextSaveArea ;
break ;
case AllocationType : : debugSbaTrackingBuffer :
resourceClass = DrmResourceClass : : sbaTrackingBuffer ;
break ;
case AllocationType : : kernelIsa :
resourceClass = DrmResourceClass : : isa ;
break ;
case AllocationType : : debugModuleArea :
resourceClass = DrmResourceClass : : moduleHeapDebugArea ;
break ;
default :
break ;
}
if ( resourceClass ! = DrmResourceClass : : maxSize ) {
auto handle = 0 ;
if ( resourceClass = = DrmResourceClass : : isa ) {
auto deviceBitfiled = static_cast < uint32_t > ( drmAllocation - > storageInfo . subDeviceBitfield . to_ulong ( ) ) ;
handle = drm - > registerResource ( resourceClass , & deviceBitfiled , sizeof ( deviceBitfiled ) ) ;
} else {
uint64_t gpuAddress = drmAllocation - > getGpuAddress ( ) ;
handle = drm - > registerResource ( resourceClass , & gpuAddress , sizeof ( gpuAddress ) ) ;
}
drmAllocation - > addRegisteredBoBindHandle ( handle ) ;
auto & bos = drmAllocation - > getBOs ( ) ;
uint32_t boIndex = 0u ;
for ( auto bo : bos ) {
if ( bo ) {
bo - > addBindExtHandle ( handle ) ;
bo - > markForCapture ( ) ;
if ( resourceClass = = DrmResourceClass : : isa & & drmAllocation - > storageInfo . tileInstanced = = true ) {
auto cookieHandle = drm - > registerIsaCookie ( handle ) ;
bo - > addBindExtHandle ( cookieHandle ) ;
drmAllocation - > addRegisteredBoBindHandle ( cookieHandle ) ;
}
auto storageInfo = drmAllocation - > storageInfo ;
if ( resourceClass = = DrmResourceClass : : sbaTrackingBuffer & & drmAllocation - > getOsContext ( ) ) {
auto deviceIndex = [ = ] ( ) - > uint32_t {
if ( storageInfo . tileInstanced = = true ) {
return boIndex ;
}
auto deviceBitfield = storageInfo . subDeviceBitfield ;
return deviceBitfield . any ( ) ? static_cast < uint32_t > ( Math : : log2 ( static_cast < uint32_t > ( deviceBitfield . to_ulong ( ) ) ) ) : 0u ;
} ( ) ;
auto contextId = drmAllocation - > getOsContext ( ) - > getOfflineDumpContextId ( deviceIndex ) ;
auto externalHandle = drm - > registerResource ( resourceClass , & contextId , sizeof ( uint64_t ) ) ;
bo - > addBindExtHandle ( externalHandle ) ;
drmAllocation - > addRegisteredBoBindHandle ( externalHandle ) ;
}
bo - > requireImmediateBinding ( true ) ;
}
boIndex + + ;
}
}
}
2022-05-19 15:07:45 +00:00
static_assert ( sizeof ( MemoryClassInstance ) = = sizeof ( prelim_drm_i915_gem_memory_class_instance ) ) ;
static_assert ( offsetof ( MemoryClassInstance , memoryClass ) = = offsetof ( prelim_drm_i915_gem_memory_class_instance , memory_class ) ) ;
static_assert ( offsetof ( MemoryClassInstance , memoryInstance ) = = offsetof ( prelim_drm_i915_gem_memory_class_instance , memory_instance ) ) ;
2024-02-26 07:57:36 +00:00
static_assert ( sizeof ( ResetStatsFault ) = = sizeof ( prelim_drm_i915_reset_stats : : fault ) ) ;
2021-12-08 10:10:27 +00:00
} // namespace NEO