1 /* 2 * Copyright (C) 2020-2021 Intel Corporation 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 */ 7 8 #include "level_zero/tools/source/sysman/linux/os_sysman_imp.h" 9 10 #include "level_zero/tools/source/sysman/linux/fs_access.h" 11 12 #include "sysman/linux/firmware_util/firmware_util.h" 13 14 namespace L0 { 15 init()16ze_result_t LinuxSysmanImp::init() { 17 pFsAccess = FsAccess::create(); 18 DEBUG_BREAK_IF(nullptr == pFsAccess); 19 20 if (pProcfsAccess == nullptr) { 21 pProcfsAccess = ProcfsAccess::create(); 22 } 23 DEBUG_BREAK_IF(nullptr == pProcfsAccess); 24 25 auto result = initLocalDeviceAndDrmHandles(); 26 if (ZE_RESULT_SUCCESS != result) { 27 return result; 28 } 29 int myDeviceFd = pDrm->getFileDescriptor(); 30 std::string myDeviceName; 31 result = pProcfsAccess->getFileName(pProcfsAccess->myProcessId(), myDeviceFd, myDeviceName); 32 if (ZE_RESULT_SUCCESS != result) { 33 return result; 34 } 35 36 if (pSysfsAccess == nullptr) { 37 pSysfsAccess = SysfsAccess::create(myDeviceName); 38 } 39 DEBUG_BREAK_IF(nullptr == pSysfsAccess); 40 41 #ifdef __linux__ 42 pPmuInterface = PmuInterface::create(this); 43 44 DEBUG_BREAK_IF(nullptr == pPmuInterface); 45 #endif 46 47 return createPmtHandles(); 48 } 49 createFwUtilInterface()50void LinuxSysmanImp::createFwUtilInterface() { 51 std::string realRootPath; 52 auto result = pSysfsAccess->getRealPath("device", realRootPath); 53 if (ZE_RESULT_SUCCESS != result) { 54 return; 55 } 56 auto rootPciPathOfGpuDevice = getPciRootPortDirectoryPath(realRootPath); 57 auto loc = realRootPath.find_last_of('/'); 58 pFwUtilInterface = FirmwareUtil::create(realRootPath.substr(loc + 1, std::string::npos)); 59 } 60 createPmtHandles()61ze_result_t LinuxSysmanImp::createPmtHandles() { 62 std::string realRootPath; 63 auto result = pSysfsAccess->getRealPath("device", realRootPath); 64 if (ZE_RESULT_SUCCESS != result) { 65 return result; 66 } 67 auto rootPciPathOfGpuDevice = getPciRootPortDirectoryPath(realRootPath); 68 PlatformMonitoringTech::create(pParentSysmanDeviceImp->deviceHandles, pFsAccess, rootPciPathOfGpuDevice, mapOfSubDeviceIdToPmtObject); 69 return result; 70 } 71 getPmuInterface()72PmuInterface *LinuxSysmanImp::getPmuInterface() { 73 return pPmuInterface; 74 } 75 getFwUtilInterface()76FirmwareUtil *LinuxSysmanImp::getFwUtilInterface() { 77 if (pFwUtilInterface == nullptr) { 78 createFwUtilInterface(); 79 } 80 return pFwUtilInterface; 81 } 82 getProductFamily()83PRODUCT_FAMILY LinuxSysmanImp::getProductFamily() { 84 return pDevice->getNEODevice()->getHardwareInfo().platform.eProductFamily; 85 } 86 getFsAccess()87FsAccess &LinuxSysmanImp::getFsAccess() { 88 UNRECOVERABLE_IF(nullptr == pFsAccess); 89 return *pFsAccess; 90 } 91 getProcfsAccess()92ProcfsAccess &LinuxSysmanImp::getProcfsAccess() { 93 UNRECOVERABLE_IF(nullptr == pProcfsAccess); 94 return *pProcfsAccess; 95 } 96 getSysfsAccess()97SysfsAccess &LinuxSysmanImp::getSysfsAccess() { 98 UNRECOVERABLE_IF(nullptr == pSysfsAccess); 99 return *pSysfsAccess; 100 } 101 initLocalDeviceAndDrmHandles()102ze_result_t LinuxSysmanImp::initLocalDeviceAndDrmHandles() { 103 pDevice = Device::fromHandle(pParentSysmanDeviceImp->hCoreDevice); 104 DEBUG_BREAK_IF(nullptr == pDevice); 105 NEO::OSInterface &OsInterface = pDevice->getOsInterface(); 106 if (OsInterface.getDriverModel()->getDriverModelType() != NEO::DriverModelType::DRM) { 107 return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; 108 } 109 pDrm = OsInterface.getDriverModel()->as<NEO::Drm>(); 110 return ZE_RESULT_SUCCESS; 111 } 112 getDrm()113NEO::Drm &LinuxSysmanImp::getDrm() { 114 if (pDrm == nullptr) { 115 initLocalDeviceAndDrmHandles(); 116 } 117 UNRECOVERABLE_IF(nullptr == pDrm); 118 return *pDrm; 119 } 120 releaseLocalDrmHandle()121void LinuxSysmanImp::releaseLocalDrmHandle() { 122 pDrm = nullptr; 123 } 124 getDeviceHandle()125Device *LinuxSysmanImp::getDeviceHandle() { 126 return pDevice; 127 } 128 getSysmanDeviceImp()129SysmanDeviceImp *LinuxSysmanImp::getSysmanDeviceImp() { 130 return pParentSysmanDeviceImp; 131 } 132 getPciRootPortDirectoryPath(std::string realPciPath)133std::string LinuxSysmanImp::getPciRootPortDirectoryPath(std::string realPciPath) { 134 size_t loc; 135 // we need to change the absolute path to two levels up to get 136 // the Discrete card's root port. 137 // the root port is always at a fixed distance as defined in HW 138 uint8_t nLevel = 2; 139 while (nLevel > 0) { 140 loc = realPciPath.find_last_of('/'); 141 if (loc == std::string::npos) { 142 break; 143 } 144 realPciPath = realPciPath.substr(0, loc); 145 nLevel--; 146 } 147 return realPciPath; 148 } 149 getPlatformMonitoringTechAccess(uint32_t subDeviceId)150PlatformMonitoringTech *LinuxSysmanImp::getPlatformMonitoringTechAccess(uint32_t subDeviceId) { 151 auto subDeviceIdToPmtEntry = mapOfSubDeviceIdToPmtObject.find(subDeviceId); 152 if (subDeviceIdToPmtEntry == mapOfSubDeviceIdToPmtObject.end()) { 153 return nullptr; 154 } 155 return subDeviceIdToPmtEntry->second; 156 } 157 LinuxSysmanImp(SysmanDeviceImp * pParentSysmanDeviceImp)158LinuxSysmanImp::LinuxSysmanImp(SysmanDeviceImp *pParentSysmanDeviceImp) { 159 this->pParentSysmanDeviceImp = pParentSysmanDeviceImp; 160 } 161 releasePmtObject()162void LinuxSysmanImp::releasePmtObject() { 163 for (auto &subDeviceIdToPmtEntry : mapOfSubDeviceIdToPmtObject) { 164 if (subDeviceIdToPmtEntry.second) { 165 delete subDeviceIdToPmtEntry.second; 166 subDeviceIdToPmtEntry.second = nullptr; 167 } 168 } 169 mapOfSubDeviceIdToPmtObject.clear(); 170 } releaseFwUtilInterface()171void LinuxSysmanImp::releaseFwUtilInterface() { 172 if (nullptr != pFwUtilInterface) { 173 delete pFwUtilInterface; 174 pFwUtilInterface = nullptr; 175 } 176 } 177 ~LinuxSysmanImp()178LinuxSysmanImp::~LinuxSysmanImp() { 179 if (nullptr != pSysfsAccess) { 180 delete pSysfsAccess; 181 pSysfsAccess = nullptr; 182 } 183 if (nullptr != pProcfsAccess) { 184 delete pProcfsAccess; 185 pProcfsAccess = nullptr; 186 } 187 if (nullptr != pFsAccess) { 188 delete pFsAccess; 189 pFsAccess = nullptr; 190 } 191 if (nullptr != pPmuInterface) { 192 delete pPmuInterface; 193 pPmuInterface = nullptr; 194 } 195 releaseFwUtilInterface(); 196 releasePmtObject(); 197 } 198 create(SysmanDeviceImp * pParentSysmanDeviceImp)199OsSysman *OsSysman::create(SysmanDeviceImp *pParentSysmanDeviceImp) { 200 LinuxSysmanImp *pLinuxSysmanImp = new LinuxSysmanImp(pParentSysmanDeviceImp); 201 return static_cast<OsSysman *>(pLinuxSysmanImp); 202 } 203 204 } // namespace L0 205