2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2020-01-02 20:20:18 +08:00
|
|
|
* Copyright (C) 2017-2020 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "drm_neo.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
2020-03-17 14:26:46 +08:00
|
|
|
#include "shared/source/execution_environment/execution_environment.h"
|
2020-07-07 15:34:31 +08:00
|
|
|
#include "shared/source/execution_environment/root_device_environment.h"
|
2020-04-02 17:28:38 +08:00
|
|
|
#include "shared/source/helpers/constants.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
2020-07-07 15:34:31 +08:00
|
|
|
#include "shared/source/helpers/hw_helper.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/hw_info.h"
|
2020-06-09 21:51:26 +08:00
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/linux/hw_device_id.h"
|
|
|
|
#include "shared/source/os_interface/linux/os_inc.h"
|
|
|
|
#include "shared/source/os_interface/linux/sys_calls.h"
|
2020-03-17 14:26:46 +08:00
|
|
|
#include "shared/source/os_interface/os_environment.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/os_interface/os_interface.h"
|
|
|
|
#include "shared/source/utilities/directory.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-11-19 19:04:17 +08:00
|
|
|
#include "drm_query_flags.h"
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
2020-02-07 21:32:02 +08:00
|
|
|
#include <linux/limits.h>
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-31 23:10:03 +08:00
|
|
|
namespace IoctlHelper {
|
|
|
|
constexpr const char *getIoctlParamString(int param) {
|
|
|
|
switch (param) {
|
|
|
|
case I915_PARAM_CHIPSET_ID:
|
|
|
|
return "I915_PARAM_CHIPSET_ID";
|
|
|
|
case I915_PARAM_REVISION:
|
|
|
|
return "I915_PARAM_REVISION";
|
|
|
|
case I915_PARAM_HAS_EXEC_SOFTPIN:
|
|
|
|
return "I915_PARAM_HAS_EXEC_SOFTPIN";
|
|
|
|
case I915_PARAM_HAS_POOLED_EU:
|
|
|
|
return "I915_PARAM_HAS_POOLED_EU";
|
|
|
|
case I915_PARAM_HAS_SCHEDULER:
|
|
|
|
return "I915_PARAM_HAS_SCHEDULER";
|
|
|
|
case I915_PARAM_EU_TOTAL:
|
|
|
|
return "I915_PARAM_EU_TOTAL";
|
|
|
|
case I915_PARAM_SUBSLICE_TOTAL:
|
|
|
|
return "I915_PARAM_SUBSLICE_TOTAL";
|
|
|
|
case I915_PARAM_MIN_EU_IN_POOL:
|
|
|
|
return "I915_PARAM_MIN_EU_IN_POOL";
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return "UNKNOWN";
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace IoctlHelper
|
|
|
|
|
2020-07-15 14:07:53 +08:00
|
|
|
Drm::Drm(std::unique_ptr<HwDeviceId> hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment) : hwDeviceId(std::move(hwDeviceIdIn)), rootDeviceEnvironment(rootDeviceEnvironment) {
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
int Drm::ioctl(unsigned long request, void *arg) {
|
|
|
|
int ret;
|
|
|
|
SYSTEM_ENTER();
|
|
|
|
do {
|
2020-02-13 20:26:40 +08:00
|
|
|
ret = SysCalls::ioctl(getFileDescriptor(), request, arg);
|
2020-07-28 16:25:04 +08:00
|
|
|
} while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EBUSY));
|
2017-12-21 07:45:38 +08:00
|
|
|
SYSTEM_LEAVE(request);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-03-12 19:03:20 +08:00
|
|
|
int Drm::getParamIoctl(int param, int *dstValue) {
|
|
|
|
drm_i915_getparam_t getParam = {};
|
|
|
|
getParam.param = param;
|
|
|
|
getParam.value = dstValue;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-31 23:10:03 +08:00
|
|
|
int retVal = ioctl(DRM_IOCTL_I915_GETPARAM, &getParam);
|
|
|
|
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stdout,
|
|
|
|
"\nDRM_IOCTL_I915_GETPARAM: param: %s, output value: %d, retCode: %d\n",
|
|
|
|
IoctlHelper::getIoctlParamString(param), *getParam.value, retVal);
|
2020-01-31 23:10:03 +08:00
|
|
|
|
|
|
|
return retVal;
|
2018-03-12 19:03:20 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-03-12 19:03:20 +08:00
|
|
|
int Drm::getDeviceID(int &devId) {
|
|
|
|
return getParamIoctl(I915_PARAM_CHIPSET_ID, &devId);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getDeviceRevID(int &revId) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_REVISION, &revId);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getExecSoftPin(int &execSoftPin) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_HAS_EXEC_SOFTPIN, &execSoftPin);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::enableTurboBoost() {
|
2018-03-20 17:49:09 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
contextParam.param = I915_CONTEXT_PRIVATE_PARAM_BOOST;
|
|
|
|
contextParam.value = 1;
|
2018-03-20 17:49:09 +08:00
|
|
|
return ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getEnabledPooledEu(int &enabled) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_HAS_POOLED_EU, &enabled);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-04-09 00:14:19 +08:00
|
|
|
std::string Drm::getSysFsPciPath() {
|
|
|
|
std::string path = std::string(Os::sysFsPciPathPrefix) + hwDeviceId->getPciPath() + "/drm";
|
|
|
|
std::string expectedFilePrefix = path + "/card";
|
|
|
|
auto files = Directory::getFiles(path.c_str());
|
|
|
|
for (auto &file : files) {
|
|
|
|
if (file.find(expectedFilePrefix.c_str()) != std::string::npos) {
|
|
|
|
return file;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
2020-04-09 00:14:19 +08:00
|
|
|
return {};
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-12-17 22:17:52 +08:00
|
|
|
int Drm::queryGttSize(uint64_t >tSizeOutput) {
|
2019-04-23 21:42:33 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {0};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_GTT_SIZE;
|
|
|
|
|
2019-12-17 22:17:52 +08:00
|
|
|
int ret = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
2019-04-23 21:42:33 +08:00
|
|
|
if (ret == 0) {
|
2019-12-17 22:17:52 +08:00
|
|
|
gttSizeOutput = contextParam.value;
|
2019-04-23 21:42:33 +08:00
|
|
|
}
|
2019-12-17 22:17:52 +08:00
|
|
|
|
|
|
|
return ret;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-07 22:03:23 +08:00
|
|
|
void Drm::checkPreemptionSupport() {
|
2017-12-21 07:45:38 +08:00
|
|
|
int value = 0;
|
2019-03-22 13:21:52 +08:00
|
|
|
auto ret = getParamIoctl(I915_PARAM_HAS_SCHEDULER, &value);
|
|
|
|
preemptionSupported = ((0 == ret) && (value & I915_SCHEDULER_CAP_PREEMPTION));
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2019-08-21 18:50:47 +08:00
|
|
|
void Drm::checkQueueSliceSupport() {
|
|
|
|
sliceCountChangeSupported = getQueueSliceCount(&sseu) == 0 ? true : false;
|
|
|
|
}
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
void Drm::setLowPriorityContextParam(uint32_t drmContextId) {
|
2018-12-07 22:03:23 +08:00
|
|
|
drm_i915_gem_context_param gcp = {};
|
2018-12-11 15:21:56 +08:00
|
|
|
gcp.ctx_id = drmContextId;
|
2017-12-21 07:45:38 +08:00
|
|
|
gcp.param = I915_CONTEXT_PARAM_PRIORITY;
|
|
|
|
gcp.value = -1023;
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &gcp);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
}
|
|
|
|
|
2019-08-21 18:50:47 +08:00
|
|
|
int Drm::getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu) {
|
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_SSEU;
|
|
|
|
sseu->engine.engine_class = I915_ENGINE_CLASS_RENDER;
|
|
|
|
sseu->engine.engine_instance = I915_EXEC_DEFAULT;
|
|
|
|
contextParam.value = reinterpret_cast<uint64_t>(sseu);
|
|
|
|
contextParam.size = sizeof(struct drm_i915_gem_context_param_sseu);
|
|
|
|
|
|
|
|
return ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Drm::getSliceMask(uint64_t sliceCount) {
|
2019-11-28 01:00:52 +08:00
|
|
|
return maxNBitValue(sliceCount);
|
2019-08-21 18:50:47 +08:00
|
|
|
}
|
|
|
|
bool Drm::setQueueSliceCount(uint64_t sliceCount) {
|
|
|
|
if (sliceCountChangeSupported) {
|
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
sseu.slice_mask = getSliceMask(sliceCount);
|
|
|
|
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_SSEU;
|
|
|
|
contextParam.ctx_id = 0;
|
|
|
|
contextParam.value = reinterpret_cast<uint64_t>(&sseu);
|
|
|
|
contextParam.size = sizeof(struct drm_i915_gem_context_param_sseu);
|
|
|
|
int retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
|
|
|
if (retVal == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-11 00:05:32 +08:00
|
|
|
void Drm::checkNonPersistentContextsSupport() {
|
2019-12-19 02:38:22 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
2020-02-11 00:05:32 +08:00
|
|
|
|
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);
|
|
|
|
if (retVal == 0 && contextParam.value == 1) {
|
|
|
|
nonPersistentContextsSupported = true;
|
|
|
|
} else {
|
|
|
|
nonPersistentContextsSupported = false;
|
|
|
|
}
|
2019-12-19 02:38:22 +08:00
|
|
|
}
|
|
|
|
|
2019-12-24 19:20:23 +08:00
|
|
|
void Drm::setNonPersistentContext(uint32_t drmContextId) {
|
2019-12-19 02:38:22 +08:00
|
|
|
drm_i915_gem_context_param contextParam = {};
|
|
|
|
contextParam.ctx_id = drmContextId;
|
|
|
|
contextParam.param = I915_CONTEXT_PARAM_PERSISTENCE;
|
|
|
|
|
2020-02-11 00:05:32 +08:00
|
|
|
ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
|
2019-12-19 02:38:22 +08:00
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
uint32_t Drm::createDrmContext(uint32_t drmVmId) {
|
2018-12-11 15:21:56 +08:00
|
|
|
drm_i915_gem_context_create gcc = {};
|
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc);
|
2018-12-07 22:03:23 +08:00
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
2018-12-11 15:21:56 +08:00
|
|
|
|
2020-08-04 16:23:54 +08:00
|
|
|
if (drmVmId > 0) {
|
|
|
|
drm_i915_gem_context_param param{};
|
|
|
|
param.ctx_id = gcc.ctx_id;
|
|
|
|
param.value = drmVmId;
|
|
|
|
param.param = I915_CONTEXT_PARAM_VM;
|
|
|
|
retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, ¶m);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
|
|
|
}
|
2020-07-23 16:50:19 +08:00
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
return gcc.ctx_id;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-11 15:21:56 +08:00
|
|
|
void Drm::destroyDrmContext(uint32_t drmContextId) {
|
2018-03-20 17:49:09 +08:00
|
|
|
drm_i915_gem_context_destroy destroy = {};
|
2018-12-11 15:21:56 +08:00
|
|
|
destroy.ctx_id = drmContextId;
|
2018-12-07 22:03:23 +08:00
|
|
|
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy);
|
|
|
|
UNRECOVERABLE_IF(retVal != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-07-14 10:36:16 +08:00
|
|
|
int Drm::createDrmVirtualMemory(uint32_t &drmVmId) {
|
2020-07-07 15:34:31 +08:00
|
|
|
drm_i915_gem_vm_control ctl = {};
|
|
|
|
auto ret = SysCalls::ioctl(getFileDescriptor(), DRM_IOCTL_I915_GEM_VM_CREATE, &ctl);
|
2020-07-14 10:36:16 +08:00
|
|
|
if (ret == 0) {
|
|
|
|
drmVmId = ctl.vm_id;
|
|
|
|
}
|
|
|
|
return ret;
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Drm::destroyDrmVirtualMemory(uint32_t drmVmId) {
|
|
|
|
drm_i915_gem_vm_control ctl = {};
|
|
|
|
ctl.vm_id = drmVmId;
|
|
|
|
auto ret = SysCalls::ioctl(getFileDescriptor(), DRM_IOCTL_I915_GEM_VM_DESTROY, &ctl);
|
|
|
|
UNRECOVERABLE_IF(ret != 0);
|
|
|
|
}
|
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
int Drm::queryVmId(uint32_t drmContextId, uint32_t &vmId) {
|
2020-08-17 18:07:39 +08:00
|
|
|
drm_i915_gem_context_param param{};
|
|
|
|
param.ctx_id = drmContextId;
|
|
|
|
param.value = 0;
|
|
|
|
param.param = I915_CONTEXT_PARAM_VM;
|
|
|
|
auto retVal = this->ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, ¶m);
|
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
vmId = static_cast<uint32_t>(param.value);
|
2020-08-17 18:07:39 +08:00
|
|
|
|
2020-08-31 13:04:58 +08:00
|
|
|
return retVal;
|
2020-08-17 18:07:39 +08:00
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
int Drm::getEuTotal(int &euTotal) {
|
2019-07-23 17:45:10 +08:00
|
|
|
return getParamIoctl(I915_PARAM_EU_TOTAL, &euTotal);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getSubsliceTotal(int &subsliceTotal) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_SUBSLICE_TOTAL, &subsliceTotal);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int Drm::getMinEuInPool(int &minEUinPool) {
|
2018-03-12 19:03:20 +08:00
|
|
|
return getParamIoctl(I915_PARAM_MIN_EU_IN_POOL, &minEUinPool);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-02-28 19:09:48 +08:00
|
|
|
int Drm::getErrno() {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
2019-10-18 16:15:09 +08:00
|
|
|
int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWorkaroundTable) {
|
|
|
|
HardwareInfo *hwInfo = const_cast<HardwareInfo *>(device->pHwInfo);
|
|
|
|
int ret;
|
2020-06-09 21:51:26 +08:00
|
|
|
int sliceTotal;
|
|
|
|
int subSliceTotal;
|
2019-10-18 16:15:09 +08:00
|
|
|
int euTotal;
|
|
|
|
|
2020-06-09 21:51:26 +08:00
|
|
|
bool status = queryTopology(sliceTotal, subSliceTotal, euTotal);
|
|
|
|
|
|
|
|
if (!status) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "WARNING: Topology query failed!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
|
|
|
|
sliceTotal = hwInfo->gtSystemInfo.SliceCount;
|
|
|
|
|
|
|
|
ret = getEuTotal(euTotal);
|
|
|
|
if (ret != 0) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query EU total parameter!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2019-10-18 16:15:09 +08:00
|
|
|
|
2020-06-09 21:51:26 +08:00
|
|
|
ret = getSubsliceTotal(subSliceTotal);
|
|
|
|
if (ret != 0) {
|
2020-09-25 17:24:15 +08:00
|
|
|
PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s", "FATAL: Cannot query subslice total parameter!\n");
|
2020-06-09 21:51:26 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2019-10-18 16:15:09 +08:00
|
|
|
}
|
|
|
|
|
2020-06-09 21:51:26 +08:00
|
|
|
hwInfo->gtSystemInfo.SliceCount = static_cast<uint32_t>(sliceTotal);
|
|
|
|
hwInfo->gtSystemInfo.SubSliceCount = static_cast<uint32_t>(subSliceTotal);
|
2019-10-18 16:15:09 +08:00
|
|
|
hwInfo->gtSystemInfo.EUCount = static_cast<uint32_t>(euTotal);
|
|
|
|
device->setupHardwareInfo(hwInfo, setupFeatureTableAndWorkaroundTable);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-09 00:14:19 +08:00
|
|
|
void appendHwDeviceId(std::vector<std::unique_ptr<HwDeviceId>> &hwDeviceIds, int fileDescriptor, const char *pciPath) {
|
2020-04-08 17:27:04 +08:00
|
|
|
if (fileDescriptor >= 0) {
|
|
|
|
if (Drm::isi915Version(fileDescriptor)) {
|
2020-04-09 00:14:19 +08:00
|
|
|
hwDeviceIds.push_back(std::make_unique<HwDeviceId>(fileDescriptor, pciPath));
|
2020-04-08 17:27:04 +08:00
|
|
|
} else {
|
|
|
|
SysCalls::close(fileDescriptor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-17 14:26:46 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> OSInterface::discoverDevices(ExecutionEnvironment &executionEnvironment) {
|
2020-02-17 23:14:22 +08:00
|
|
|
std::vector<std::unique_ptr<HwDeviceId>> hwDeviceIds;
|
2020-03-17 14:26:46 +08:00
|
|
|
executionEnvironment.osEnvironment = std::make_unique<OsEnvironment>();
|
2020-04-08 17:27:04 +08:00
|
|
|
std::string devicePrefix = std::string(Os::pciDevicesDirectory) + "/pci-0000:";
|
|
|
|
const char *renderDeviceSuffix = "-render";
|
|
|
|
size_t numRootDevices = 0u;
|
2020-02-17 23:14:22 +08:00
|
|
|
if (DebugManager.flags.CreateMultipleRootDevices.get()) {
|
|
|
|
numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get();
|
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
|
|
|
|
std::vector<std::string> files = Directory::getFiles(Os::pciDevicesDirectory);
|
|
|
|
|
|
|
|
if (files.size() == 0) {
|
|
|
|
const char *pathPrefix = "/dev/dri/renderD";
|
|
|
|
const unsigned int maxDrmDevices = 64;
|
|
|
|
unsigned int startNum = 128;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < maxDrmDevices; i++) {
|
|
|
|
std::string path = std::string(pathPrefix) + std::to_string(i + startNum);
|
|
|
|
int fileDescriptor = SysCalls::open(path.c_str(), O_RDWR);
|
2020-04-09 00:14:19 +08:00
|
|
|
appendHwDeviceId(hwDeviceIds, fileDescriptor, "00:02.0");
|
2020-05-21 19:01:07 +08:00
|
|
|
if (!hwDeviceIds.empty() && hwDeviceIds.size() == numRootDevices) {
|
|
|
|
break;
|
|
|
|
}
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2020-02-17 23:14:22 +08:00
|
|
|
return hwDeviceIds;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
|
|
|
|
2020-04-08 17:27:04 +08:00
|
|
|
do {
|
|
|
|
for (std::vector<std::string>::iterator file = files.begin(); file != files.end(); ++file) {
|
|
|
|
if (file->find(renderDeviceSuffix) == std::string::npos) {
|
|
|
|
continue;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
std::string pciPath = file->substr(devicePrefix.size(), file->size() - devicePrefix.size() - strlen(renderDeviceSuffix));
|
|
|
|
|
|
|
|
if (DebugManager.flags.ForceDeviceId.get() != "unk") {
|
|
|
|
if (file->find(DebugManager.flags.ForceDeviceId.get().c_str()) == std::string::npos) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int fileDescriptor = SysCalls::open(file->c_str(), O_RDWR);
|
2020-04-09 00:14:19 +08:00
|
|
|
appendHwDeviceId(hwDeviceIds, fileDescriptor, pciPath.c_str());
|
2020-05-21 19:01:07 +08:00
|
|
|
if (!hwDeviceIds.empty() && hwDeviceIds.size() == numRootDevices) {
|
|
|
|
break;
|
|
|
|
}
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
2020-04-08 17:27:04 +08:00
|
|
|
if (hwDeviceIds.empty()) {
|
|
|
|
return hwDeviceIds;
|
|
|
|
}
|
|
|
|
} while (hwDeviceIds.size() < numRootDevices);
|
2020-02-17 23:14:22 +08:00
|
|
|
return hwDeviceIds;
|
2020-02-07 21:32:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::isi915Version(int fileDescriptor) {
|
|
|
|
drm_version_t version = {};
|
|
|
|
char name[5] = {};
|
|
|
|
version.name = name;
|
|
|
|
version.name_len = 5;
|
|
|
|
|
2020-02-13 20:26:40 +08:00
|
|
|
int ret = SysCalls::ioctl(fileDescriptor, DRM_IOCTL_VERSION, &version);
|
2020-02-07 21:32:02 +08:00
|
|
|
if (ret) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
name[4] = '\0';
|
|
|
|
return strcmp(name, "i915") == 0;
|
|
|
|
}
|
|
|
|
|
2020-11-19 19:04:17 +08:00
|
|
|
std::unique_ptr<uint8_t[]> Drm::query(uint32_t queryId, uint32_t queryItemFlags, int32_t &length) {
|
2020-06-09 21:51:26 +08:00
|
|
|
drm_i915_query query{};
|
|
|
|
drm_i915_query_item queryItem{};
|
|
|
|
queryItem.query_id = queryId;
|
|
|
|
queryItem.length = 0; // query length first
|
2020-11-19 19:04:17 +08:00
|
|
|
queryItem.flags = queryItemFlags;
|
2020-06-09 21:51:26 +08:00
|
|
|
query.items_ptr = reinterpret_cast<__u64>(&queryItem);
|
|
|
|
query.num_items = 1;
|
|
|
|
length = 0;
|
|
|
|
|
|
|
|
auto ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
|
|
|
|
if (ret != 0 || queryItem.length <= 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto data = std::make_unique<uint8_t[]>(queryItem.length);
|
|
|
|
memset(data.get(), 0, queryItem.length);
|
|
|
|
queryItem.data_ptr = castToUint64(data.get());
|
|
|
|
|
|
|
|
ret = this->ioctl(DRM_IOCTL_I915_QUERY, &query);
|
|
|
|
if (ret != 0 || queryItem.length <= 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
length = queryItem.length;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Drm::queryTopology(int &sliceCount, int &subSliceCount, int &euCount) {
|
|
|
|
int32_t length;
|
2020-11-19 19:04:17 +08:00
|
|
|
auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, DrmQueryItemFlags::topology, length);
|
2020-06-09 21:51:26 +08:00
|
|
|
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.get());
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
sliceCount = 0;
|
|
|
|
subSliceCount = 0;
|
|
|
|
euCount = 0;
|
|
|
|
|
|
|
|
for (int x = 0; x < data->max_slices; x++) {
|
|
|
|
bool isSliceEnable = (data->data[x / 8] >> (x % 8)) & 1;
|
|
|
|
if (!isSliceEnable) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sliceCount++;
|
|
|
|
for (int y = 0; y < data->max_subslices; y++) {
|
|
|
|
bool isSubSliceEnabled = (data->data[data->subslice_offset + x * data->subslice_stride + y / 8] >> (y % 8)) & 1;
|
|
|
|
if (!isSubSliceEnabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
subSliceCount++;
|
|
|
|
for (int z = 0; z < data->max_eus_per_subslice; z++) {
|
|
|
|
bool isEUEnabled = (data->data[data->eu_offset + (x * data->max_subslices + y) * data->eu_stride + z / 8] >> (z % 8)) & 1;
|
|
|
|
if (!isEUEnabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
euCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-16 16:12:15 +08:00
|
|
|
return (sliceCount && subSliceCount && euCount);
|
2020-06-09 21:51:26 +08:00
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
bool Drm::createVirtualMemoryAddressSpace(uint32_t vmCount) {
|
|
|
|
for (auto i = 0u; i < vmCount; i++) {
|
2020-07-14 10:36:16 +08:00
|
|
|
uint32_t id = 0;
|
|
|
|
if (0 != createDrmVirtualMemory(id)) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-07-07 15:34:31 +08:00
|
|
|
virtualMemoryIds.push_back(id);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Drm::destroyVirtualMemoryAddressSpace() {
|
|
|
|
for (auto id : virtualMemoryIds) {
|
|
|
|
destroyDrmVirtualMemory(id);
|
|
|
|
}
|
2020-08-04 16:23:54 +08:00
|
|
|
virtualMemoryIds.clear();
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Drm::getVirtualMemoryAddressSpace(uint32_t vmId) {
|
2020-07-14 10:36:16 +08:00
|
|
|
if (vmId < virtualMemoryIds.size()) {
|
|
|
|
return virtualMemoryIds[vmId];
|
|
|
|
}
|
|
|
|
return 0;
|
2020-07-07 15:34:31 +08:00
|
|
|
}
|
|
|
|
|
2020-09-08 23:33:33 +08:00
|
|
|
std::string Drm::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;
|
2020-09-10 23:47:22 +08:00
|
|
|
snprintf(buffer, sizeof(buffer), uuidString, parts[1], parts[0]);
|
2020-09-08 23:33:33 +08:00
|
|
|
|
|
|
|
return std::string(buffer, 36);
|
|
|
|
}
|
|
|
|
|
2020-07-07 15:34:31 +08:00
|
|
|
Drm::~Drm() {
|
|
|
|
destroyVirtualMemoryAddressSpace();
|
|
|
|
}
|
2020-02-13 22:04:21 +08:00
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|