compute-runtime/shared/test/common/libult/linux/drm_mock.cpp

372 lines
16 KiB
C++

/*
* Copyright (C) 2019-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/common/libult/linux/drm_mock.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/helpers/hw_info.h"
#include "gtest/gtest.h"
#include <cstring>
const int DrmMock::mockFd;
const uint32_t DrmMockResources::registerResourceReturnHandle = 3;
int DrmMock::ioctl(unsigned long request, void *arg) {
ioctlCallsCount++;
ioctlCount.total++;
if ((request == DRM_IOCTL_I915_GETPARAM) && (arg != nullptr)) {
ioctlCount.contextGetParam++;
auto gp = static_cast<GetParam *>(arg);
if (gp->param == I915_PARAM_EU_TOTAL) {
if (0 == this->storedRetValForEUVal) {
*gp->value = this->storedEUVal;
}
return this->storedRetValForEUVal;
}
if (gp->param == I915_PARAM_SUBSLICE_TOTAL) {
if (0 == this->storedRetValForSSVal) {
*gp->value = this->storedSSVal;
}
return this->storedRetValForSSVal;
}
if (gp->param == I915_PARAM_CHIPSET_ID) {
if (0 == this->storedRetValForDeviceID) {
*gp->value = this->storedDeviceID;
}
return this->storedRetValForDeviceID;
}
if (gp->param == I915_PARAM_REVISION) {
if (0 == this->storedRetValForDeviceRevID) {
*gp->value = this->storedDeviceRevID;
}
return this->storedRetValForDeviceRevID;
}
if (gp->param == I915_PARAM_HAS_POOLED_EU) {
if (0 == this->storedRetValForPooledEU) {
*gp->value = this->storedHasPooledEU;
}
return this->storedRetValForPooledEU;
}
if (gp->param == I915_PARAM_MIN_EU_IN_POOL) {
if (0 == this->storedRetValForMinEUinPool) {
*gp->value = this->storedMinEUinPool;
}
return this->storedRetValForMinEUinPool;
}
if (gp->param == I915_PARAM_HAS_SCHEDULER) {
*gp->value = this->storedPreemptionSupport;
return this->storedRetVal;
}
if (gp->param == I915_PARAM_HAS_EXEC_SOFTPIN) {
*gp->value = this->storedExecSoftPin;
return this->storedRetVal;
}
if (gp->param == I915_PARAM_CS_TIMESTAMP_FREQUENCY) {
*gp->value = this->storedCsTimestampFrequency;
return this->storedRetVal;
}
}
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT) && (arg != nullptr)) {
ioctlCount.contextCreate++;
auto create = static_cast<GemContextCreateExt *>(arg);
create->contextId = this->storedDrmContextId;
this->receivedContextCreateFlags = create->flags;
if (create->extensions == 0) {
return this->storedRetVal;
}
receivedContextCreateSetParam = *reinterpret_cast<GemContextCreateExtSetParam *>(create->extensions);
if (receivedContextCreateSetParam.base.name == I915_CONTEXT_CREATE_EXT_SETPARAM) {
receivedContextParamRequestCount++;
receivedContextParamRequest = *reinterpret_cast<GemContextParam *>(&receivedContextCreateSetParam.param);
if (receivedContextCreateSetParam.param.param == I915_CONTEXT_PARAM_VM) {
return this->storedRetVal;
}
}
}
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_DESTROY) && (arg != nullptr)) {
ioctlCount.contextDestroy++;
auto destroy = static_cast<GemContextDestroy *>(arg);
this->receivedDestroyContextId = destroy->contextId;
return this->storedRetVal;
}
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM) && (arg != nullptr)) {
ioctlCount.contextSetParam++;
receivedContextParamRequestCount++;
receivedContextParamRequest = *static_cast<GemContextParam *>(arg);
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PRIORITY) {
return this->storedRetVal;
}
if ((receivedContextParamRequest.param == I915_CONTEXT_PRIVATE_PARAM_BOOST) && (receivedContextParamRequest.value == 1)) {
return this->storedRetVal;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_SSEU) {
if (storedRetValForSetSSEU == 0) {
storedParamSseu = (*static_cast<GemContextParamSseu *>(reinterpret_cast<void *>(receivedContextParamRequest.value))).sliceMask;
}
return this->storedRetValForSetSSEU;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
return this->storedRetValForPersistant;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_VM) {
return this->storedRetVal;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_RECOVERABLE) {
receivedRecoverableContextValue = receivedContextParamRequest.value;
return this->storedRetVal;
}
}
if ((request == DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM) && (arg != nullptr)) {
ioctlCount.contextGetParam++;
receivedContextParamRequestCount++;
receivedContextParamRequest = *static_cast<GemContextParam *>(arg);
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_GTT_SIZE) {
static_cast<GemContextParam *>(arg)->value = this->storedGTTSize;
return this->storedRetValForGetGttSize;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_SSEU) {
if (storedRetValForGetSSEU == 0) {
(*static_cast<GemContextParamSseu *>(reinterpret_cast<void *>(receivedContextParamRequest.value))).sliceMask = storedParamSseu;
}
return this->storedRetValForGetSSEU;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
static_cast<GemContextParam *>(arg)->value = this->storedPersistentContextsSupport;
return this->storedRetValForPersistant;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_VM) {
static_cast<GemContextParam *>(arg)->value = this->storedRetValForVmId;
return 0u;
}
}
if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) {
ioctlCount.execbuffer2++;
auto execbuf = static_cast<NEO::MockExecBuffer *>(arg);
auto execObjects = reinterpret_cast<const MockExecObject *>(execbuf->getBuffersPtr());
this->execBuffers.push_back(*execbuf);
for (uint32_t i = 0; i < execbuf->getBufferCount(); i++) {
this->receivedBos.push_back(execObjects[i]);
}
return 0;
}
if (request == DRM_IOCTL_I915_GEM_USERPTR) {
ioctlCount.gemUserptr++;
auto userPtrParams = static_cast<NEO::GemUserPtr *>(arg);
userPtrParams->handle = returnHandle;
returnHandle++;
return 0;
}
if (request == DRM_IOCTL_I915_GEM_CREATE) {
ioctlCount.gemCreate++;
auto createParams = static_cast<NEO::GemCreate *>(arg);
this->createParamsSize = createParams->size;
this->createParamsHandle = createParams->handle = 1u;
if (0 == this->createParamsSize) {
return EINVAL;
}
return 0;
}
if (request == DRM_IOCTL_I915_GEM_SET_TILING) {
ioctlCount.gemSetTiling++;
auto setTilingParams = static_cast<NEO::GemSetTiling *>(arg);
setTilingMode = setTilingParams->tilingMode;
setTilingHandle = setTilingParams->handle;
setTilingStride = setTilingParams->stride;
return 0;
}
if (request == DRM_IOCTL_PRIME_FD_TO_HANDLE) {
ioctlCount.primeFdToHandle++;
auto primeToHandleParams = static_cast<PrimeHandle *>(arg);
//return BO
primeToHandleParams->handle = outputHandle;
inputFd = primeToHandleParams->fileDescriptor;
return fdToHandleRetVal;
}
if (request == DRM_IOCTL_PRIME_HANDLE_TO_FD) {
ioctlCount.handleToPrimeFd++;
auto primeToFdParams = static_cast<PrimeHandle *>(arg);
primeToFdParams->fileDescriptor = outputFd;
return 0;
}
if (request == DRM_IOCTL_I915_GEM_GET_APERTURE) {
ioctlCount.gemGetAperture++;
auto aperture = static_cast<drm_i915_gem_get_aperture *>(arg);
aperture->aper_available_size = gpuMemSize;
aperture->aper_size = gpuMemSize;
return 0;
}
if (request == DRM_IOCTL_I915_GEM_MMAP) {
ioctlCount.gemMmap++;
auto mmapArg = static_cast<GemMmap *>(arg);
mmapArg->addrPtr = reinterpret_cast<uint64_t>(lockedPtr);
return 0;
}
if (request == DRM_IOCTL_I915_GEM_WAIT) {
ioctlCount.gemWait++;
receivedGemWait = *static_cast<GemWait *>(arg);
return 0;
}
if (request == DRM_IOCTL_GEM_CLOSE) {
ioctlCount.gemClose++;
return storedRetValForGemClose;
}
if (request == DRM_IOCTL_I915_GET_RESET_STATS && arg != nullptr) {
ioctlCount.gemResetStats++;
auto outResetStats = static_cast<ResetStats *>(arg);
for (const auto &resetStats : resetStatsToReturn) {
if (resetStats.contextId == outResetStats->contextId) {
*outResetStats = resetStats;
return 0;
}
}
return -1;
}
if (request == DRM_IOCTL_I915_QUERY && arg != nullptr) {
ioctlCount.query++;
auto queryArg = static_cast<Query *>(arg);
auto queryItemArg = reinterpret_cast<QueryItem *>(queryArg->itemsPtr);
storedQueryItem = *queryItemArg;
auto realEuCount = rootDeviceEnvironment.getHardwareInfo()->gtSystemInfo.EUCount;
auto dataSize = static_cast<size_t>(std::ceil(realEuCount / 8.0));
if (queryItemArg->length == 0) {
if (queryItemArg->queryId == DRM_I915_QUERY_TOPOLOGY_INFO) {
queryItemArg->length = static_cast<int32_t>(sizeof(QueryTopologyInfo) + dataSize);
return 0;
}
} else {
if (queryItemArg->queryId == DRM_I915_QUERY_TOPOLOGY_INFO) {
auto topologyArg = reinterpret_cast<QueryTopologyInfo *>(queryItemArg->dataPtr);
if (this->failRetTopology) {
return -1;
}
topologyArg->maxSlices = this->storedSVal;
topologyArg->maxSubslices = this->storedSVal ? (this->storedSSVal / this->storedSVal) : 0;
topologyArg->maxEusPerSubslice = this->storedSSVal ? (this->storedEUVal / this->storedSSVal) : 0;
if (this->disableSomeTopology) {
memset(topologyArg->data, 0xCA, dataSize);
} else {
memset(topologyArg->data, 0xFF, dataSize);
}
return 0;
}
}
}
return handleRemainingRequests(request, arg);
}
int DrmMock::waitUserFence(uint32_t ctxIdx, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags) {
waitUserFenceParams.push_back({ctxIdx, address, value, dataWidth, timeout, flags});
return Drm::waitUserFence(ctxIdx, address, value, dataWidth, timeout, flags);
}
int DrmMockEngine::handleRemainingRequests(unsigned long request, void *arg) {
if ((request == DRM_IOCTL_I915_QUERY) && (arg != nullptr)) {
if (i915QuerySuccessCount == 0) {
return EINVAL;
}
i915QuerySuccessCount--;
auto query = static_cast<Query *>(arg);
if (query->itemsPtr == 0) {
return EINVAL;
}
for (auto i = 0u; i < query->numItems; i++) {
handleQueryItem(reinterpret_cast<QueryItem *>(query->itemsPtr) + i);
}
return 0;
}
return -1;
}
std::map<unsigned long, const char *> ioctlCodeStringMap = {
{DRM_IOCTL_I915_INIT, "DRM_IOCTL_I915_INIT"},
{DRM_IOCTL_I915_FLUSH, "DRM_IOCTL_I915_FLUSH"},
{DRM_IOCTL_I915_FLIP, "DRM_IOCTL_I915_FLIP"},
{DRM_IOCTL_GEM_CLOSE, "DRM_IOCTL_GEM_CLOSE"},
{DRM_IOCTL_I915_BATCHBUFFER, "DRM_IOCTL_I915_BATCHBUFFER"},
{DRM_IOCTL_I915_IRQ_EMIT, "DRM_IOCTL_I915_IRQ_EMIT"},
{DRM_IOCTL_I915_IRQ_WAIT, "DRM_IOCTL_I915_IRQ_WAIT"},
{DRM_IOCTL_I915_GETPARAM, "DRM_IOCTL_I915_GETPARAM"},
{DRM_IOCTL_I915_SETPARAM, "DRM_IOCTL_I915_SETPARAM"},
{DRM_IOCTL_I915_ALLOC, "DRM_IOCTL_I915_ALLOC"},
{DRM_IOCTL_I915_FREE, "DRM_IOCTL_I915_FREE"},
{DRM_IOCTL_I915_INIT_HEAP, "DRM_IOCTL_I915_INIT_HEAP"},
{DRM_IOCTL_I915_CMDBUFFER, "DRM_IOCTL_I915_CMDBUFFER"},
{DRM_IOCTL_I915_DESTROY_HEAP, "DRM_IOCTL_I915_DESTROY_HEAP"},
{DRM_IOCTL_I915_SET_VBLANK_PIPE, "DRM_IOCTL_I915_SET_VBLANK_PIPE"},
{DRM_IOCTL_I915_GET_VBLANK_PIPE, "DRM_IOCTL_I915_GET_VBLANK_PIPE"},
{DRM_IOCTL_I915_VBLANK_SWAP, "DRM_IOCTL_I915_VBLANK_SWAP"},
{DRM_IOCTL_I915_HWS_ADDR, "DRM_IOCTL_I915_HWS_ADDR"},
{DRM_IOCTL_I915_GEM_INIT, "DRM_IOCTL_I915_GEM_INIT"},
{DRM_IOCTL_I915_GEM_EXECBUFFER, "DRM_IOCTL_I915_GEM_EXECBUFFER"},
{DRM_IOCTL_I915_GEM_EXECBUFFER2, "DRM_IOCTL_I915_GEM_EXECBUFFER2"},
{DRM_IOCTL_I915_GEM_EXECBUFFER2_WR, "DRM_IOCTL_I915_GEM_EXECBUFFER2_WR"},
{DRM_IOCTL_I915_GEM_PIN, "DRM_IOCTL_I915_GEM_PIN"},
{DRM_IOCTL_I915_GEM_UNPIN, "DRM_IOCTL_I915_GEM_UNPIN"},
{DRM_IOCTL_I915_GEM_BUSY, "DRM_IOCTL_I915_GEM_BUSY"},
{DRM_IOCTL_I915_GEM_SET_CACHING, "DRM_IOCTL_I915_GEM_SET_CACHING"},
{DRM_IOCTL_I915_GEM_GET_CACHING, "DRM_IOCTL_I915_GEM_GET_CACHING"},
{DRM_IOCTL_I915_GEM_THROTTLE, "DRM_IOCTL_I915_GEM_THROTTLE"},
{DRM_IOCTL_I915_GEM_ENTERVT, "DRM_IOCTL_I915_GEM_ENTERVT"},
{DRM_IOCTL_I915_GEM_LEAVEVT, "DRM_IOCTL_I915_GEM_LEAVEVT"},
{DRM_IOCTL_I915_GEM_CREATE, "DRM_IOCTL_I915_GEM_CREATE"},
{DRM_IOCTL_I915_GEM_PREAD, "DRM_IOCTL_I915_GEM_PREAD"},
{DRM_IOCTL_I915_GEM_PWRITE, "DRM_IOCTL_I915_GEM_PWRITE"},
{DRM_IOCTL_I915_GEM_SET_DOMAIN, "DRM_IOCTL_I915_GEM_SET_DOMAIN"},
{DRM_IOCTL_I915_GEM_SW_FINISH, "DRM_IOCTL_I915_GEM_SW_FINISH"},
{DRM_IOCTL_I915_GEM_SET_TILING, "DRM_IOCTL_I915_GEM_SET_TILING"},
{DRM_IOCTL_I915_GEM_GET_TILING, "DRM_IOCTL_I915_GEM_GET_TILING"},
{DRM_IOCTL_I915_GEM_GET_APERTURE, "DRM_IOCTL_I915_GEM_GET_APERTURE"},
{DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, "DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID"},
{DRM_IOCTL_I915_GEM_MADVISE, "DRM_IOCTL_I915_GEM_MADVISE"},
{DRM_IOCTL_I915_OVERLAY_PUT_IMAGE, "DRM_IOCTL_I915_OVERLAY_PUT_IMAGE"},
{DRM_IOCTL_I915_OVERLAY_ATTRS, "DRM_IOCTL_I915_OVERLAY_ATTRS"},
{DRM_IOCTL_I915_SET_SPRITE_COLORKEY, "DRM_IOCTL_I915_SET_SPRITE_COLORKEY"},
{DRM_IOCTL_I915_GET_SPRITE_COLORKEY, "DRM_IOCTL_I915_GET_SPRITE_COLORKEY"},
{DRM_IOCTL_I915_GEM_WAIT, "DRM_IOCTL_I915_GEM_WAIT"},
{DRM_IOCTL_I915_GEM_CONTEXT_CREATE, "DRM_IOCTL_I915_GEM_CONTEXT_CREATE"},
{DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, "DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT"},
{DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY"},
{DRM_IOCTL_I915_REG_READ, "DRM_IOCTL_I915_REG_READ"},
{DRM_IOCTL_I915_GET_RESET_STATS, "DRM_IOCTL_I915_GET_RESET_STATS"},
{DRM_IOCTL_I915_GEM_USERPTR, "DRM_IOCTL_I915_GEM_USERPTR"},
{DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, "DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM"},
{DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, "DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM"},
{DRM_IOCTL_I915_PERF_OPEN, "DRM_IOCTL_I915_PERF_OPEN"},
{DRM_IOCTL_I915_PERF_ADD_CONFIG, "DRM_IOCTL_I915_PERF_ADD_CONFIG"},
{DRM_IOCTL_I915_PERF_REMOVE_CONFIG, "DRM_IOCTL_I915_PERF_REMOVE_CONFIG"},
{DRM_IOCTL_I915_QUERY, "DRM_IOCTL_I915_QUERY"},
{DRM_IOCTL_I915_GEM_MMAP, "DRM_IOCTL_I915_GEM_MMAP"},
{DRM_IOCTL_PRIME_FD_TO_HANDLE, "DRM_IOCTL_PRIME_FD_TO_HANDLE"},
{DRM_IOCTL_PRIME_HANDLE_TO_FD, "DRM_IOCTL_PRIME_HANDLE_TO_FD"},
{static_cast<unsigned long>(101010101), "101010101"}};
std::map<int, const char *> ioctlParamCodeStringMap = {
{I915_PARAM_CHIPSET_ID, "I915_PARAM_CHIPSET_ID"},
{I915_PARAM_REVISION, "I915_PARAM_REVISION"},
{I915_PARAM_HAS_EXEC_SOFTPIN, "I915_PARAM_HAS_EXEC_SOFTPIN"},
{I915_PARAM_HAS_POOLED_EU, "I915_PARAM_HAS_POOLED_EU"},
{I915_PARAM_HAS_SCHEDULER, "I915_PARAM_HAS_SCHEDULER"},
{I915_PARAM_EU_TOTAL, "I915_PARAM_EU_TOTAL"},
{I915_PARAM_SUBSLICE_TOTAL, "I915_PARAM_SUBSLICE_TOTAL"},
{I915_PARAM_MIN_EU_IN_POOL, "I915_PARAM_MIN_EU_IN_POOL"},
{I915_PARAM_CS_TIMESTAMP_FREQUENCY, "I915_PARAM_CS_TIMESTAMP_FREQUENCY"},
{static_cast<int>(101010101), "101010101"}};