feature(sysman): Added support for PCI APIs

Added support for PCI APIs in the new sysman design
Added ULTs for the PCI APIs in the new sysman design

Related-To: LOCI-4319

Signed-off-by: Bari, Pratik <pratik.bari@intel.com>
This commit is contained in:
Bari, Pratik
2023-05-03 18:54:20 +00:00
committed by Compute-Runtime-Automation
parent 7b27d7cf41
commit f9703f25b0
20 changed files with 1646 additions and 4 deletions

View File

@@ -0,0 +1,16 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/pci.h
${CMAKE_CURRENT_SOURCE_DIR}/pci_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pci_imp.h
${CMAKE_CURRENT_SOURCE_DIR}/os_pci.h
)
add_subdirectories()

View File

@@ -0,0 +1,14 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/os_pci_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_pci_imp.h
)
endif()

View File

@@ -0,0 +1,311 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/pci/linux/os_pci_imp.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/utilities/directory.h"
#include "level_zero/sysman/source/pci/pci_imp.h"
#include "level_zero/sysman/source/sysman_const.h"
#include <linux/pci_regs.h>
namespace L0 {
namespace Sysman {
const std::string LinuxPciImp::deviceDir("device");
const std::string LinuxPciImp::resourceFile("device/resource");
ze_result_t LinuxPciImp::getProperties(zes_pci_properties_t *properties) {
properties->haveBandwidthCounters = false;
properties->havePacketCounters = false;
properties->haveReplayCounters = false;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxPciImp::getPciBdf(zes_pci_properties_t &pciProperties) {
std::string bdfDir;
ze_result_t result = pSysfsAccess->readSymLink(deviceDir, bdfDir);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): readSymLink() failed to retrive BDF from %s and returning error:0x%x \n", __FUNCTION__, deviceDir.c_str(), result);
return result;
}
const auto loc = bdfDir.find_last_of('/');
std::string bdf = bdfDir.substr(loc + 1);
uint16_t domain = 0;
uint8_t bus = 0, device = 0, function = 0;
NEO::parseBdfString(bdf.c_str(), domain, bus, device, function);
pciProperties.address.domain = static_cast<uint32_t>(domain);
pciProperties.address.bus = static_cast<uint32_t>(bus);
pciProperties.address.device = static_cast<uint32_t>(device);
pciProperties.address.function = static_cast<uint32_t>(function);
return ZE_RESULT_SUCCESS;
}
void LinuxPciImp::getMaxLinkCaps(double &maxLinkSpeed, int32_t &maxLinkWidth) {
uint16_t linkCaps = 0;
auto linkCapPos = getLinkCapabilityPos();
if (!linkCapPos) {
maxLinkSpeed = 0;
maxLinkWidth = -1;
return;
}
linkCaps = getWordFromConfig(linkCapPos, (!(isIntegratedDevice)) ? uspConfigMemory.get() : configMemory.get());
maxLinkSpeed = convertPciGenToLinkSpeed(BITS(linkCaps, 0, 4));
maxLinkWidth = BITS(linkCaps, 4, 6);
return;
}
void getBarBaseAndSize(std::string readBytes, uint64_t &baseAddr, uint64_t &barSize, uint64_t &barFlags) {
unsigned long long start, end, flags;
std::stringstream sStreamReadBytes;
sStreamReadBytes << readBytes;
sStreamReadBytes >> std::hex >> start;
sStreamReadBytes >> end;
sStreamReadBytes >> flags;
flags &= 0xf;
barFlags = flags;
baseAddr = start;
barSize = end - start + 1;
}
ze_result_t LinuxPciImp::initializeBarProperties(std::vector<zes_pci_bar_properties_t *> &pBarProperties) {
std::vector<std::string> readBytes;
ze_result_t result = pSysfsAccess->read(resourceFile, readBytes);
if (result != ZE_RESULT_SUCCESS) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): read() failed to read %s and returning error:0x%x \n", __FUNCTION__, resourceFile.c_str(), result);
return result;
}
for (uint32_t i = 0; i <= maxPciBars; i++) {
uint64_t baseAddr, barSize, barFlags;
getBarBaseAndSize(readBytes[i], baseAddr, barSize, barFlags);
if (baseAddr && !(barFlags & 0x1)) { // we do not update for I/O ports
zes_pci_bar_properties_t *pBarProp = new zes_pci_bar_properties_t;
memset(pBarProp, 0, sizeof(zes_pci_bar_properties_t));
pBarProp->index = i;
pBarProp->base = baseAddr;
pBarProp->size = barSize;
// Bar Flags Desc.
// Bit-0 - Value 0x0 -> MMIO type BAR
// Bit-0 - Value 0x1 -> I/O type BAR
if (i == 0) { // GRaphics MMIO is at BAR0, and is a 64-bit
pBarProp->type = ZES_PCI_BAR_TYPE_MMIO;
}
if (i == 2) {
pBarProp->type = ZES_PCI_BAR_TYPE_MEM; // device memory is always at BAR2
}
if (i == 6) { // the 7th entry of resource file is expected to be ROM BAR
pBarProp->type = ZES_PCI_BAR_TYPE_ROM;
}
pBarProperties.push_back(pBarProp);
}
}
if (pBarProperties.size() == 0) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): BarProperties = %d and returning error:0x%x \n", __FUNCTION__, pBarProperties.size(), result);
result = ZE_RESULT_ERROR_UNKNOWN;
}
return result;
}
uint32_t LinuxPciImp::getRebarCapabilityPos() {
uint32_t pos = PCI_CFG_SPACE_SIZE;
uint32_t header = 0;
if (!configMemory) {
return 0;
}
// Minimum 8 bytes per capability. Hence maximum capabilities that
// could be present in PCI extended configuration space are
// represented by loopCount.
auto loopCount = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
header = getDwordFromConfig(pos);
if (!header) {
return 0;
}
while (loopCount-- > 0) {
if (PCI_EXT_CAP_ID(header) == PCI_EXT_CAP_ID_REBAR) {
return pos;
}
pos = PCI_EXT_CAP_NEXT(header);
if (pos < PCI_CFG_SPACE_SIZE) {
return 0;
}
header = getDwordFromConfig(pos);
}
return 0;
}
uint16_t LinuxPciImp::getLinkCapabilityPos() {
uint16_t pos = PCI_CAPABILITY_LIST;
uint8_t id, type = 0;
uint16_t capRegister = 0;
uint8_t *configMem = (!(isIntegratedDevice)) ? uspConfigMemory.get() : configMemory.get();
if ((!configMem) || (!(getByteFromConfig(PCI_STATUS, configMem) & PCI_STATUS_CAP_LIST))) {
return 0;
}
// Minimum 8 bytes per capability. Hence maximum capabilities that
// could be present in PCI configuration space are
// represented by loopCount.
auto loopCount = (PCI_CFG_SPACE_SIZE) / 8;
// Bottom two bits of capability pointer register are reserved and
// software should mask these bits to get pointer to capability list.
pos = getByteFromConfig(pos, configMem) & 0xfc;
while (loopCount-- > 0) {
id = getByteFromConfig(pos + PCI_CAP_LIST_ID, configMem);
if (id == PCI_CAP_ID_EXP) {
capRegister = getWordFromConfig(pos + PCI_CAP_FLAGS, configMem);
type = BITS(capRegister, 4, 4);
// Root Complex Integrated end point and
// Root Complex Event collector will not implement link capabilities
if ((type != PCI_EXP_TYPE_RC_END) && (type != PCI_EXP_TYPE_RC_EC)) {
return pos + PCI_EXP_LNKCAP;
}
}
pos = getByteFromConfig(pos + PCI_CAP_LIST_NEXT, configMem) & 0xfc;
if (!pos) {
break;
}
}
return 0;
}
// Parse PCIe configuration space to see if resizable Bar is supported
bool LinuxPciImp::resizableBarSupported() {
return (getRebarCapabilityPos() > 0);
}
bool LinuxPciImp::resizableBarEnabled(uint32_t barIndex) {
bool isBarResizable = false;
uint32_t capabilityRegister = 0, controlRegister = 0;
uint32_t nBars = 1;
auto rebarCapabilityPos = getRebarCapabilityPos();
// If resizable Bar is not supported then return false.
if (!rebarCapabilityPos) {
return false;
}
// As per PCI spec, resizable BAR's capability structure's 52 byte length could be represented as:
// --------------------------------------------------------------
// | byte offset | Description of register |
// -------------------------------------------------------------|
// | +000h | PCI Express Extended Capability Header |
// -------------------------------------------------------------|
// | +004h | Resizable BAR Capability Register (0) |
// -------------------------------------------------------------|
// | +008h | Resizable BAR Control Register (0) |
// -------------------------------------------------------------|
// | +00Ch | Resizable BAR Capability Register (1) |
// -------------------------------------------------------------|
// | +010h | Resizable BAR Control Register (1) |
// -------------------------------------------------------------|
// | +014h | --- |
// -------------------------------------------------------------|
// Only first Control register(at offset 008h, as shown above), could tell about number of resizable Bars
controlRegister = getDwordFromConfig(rebarCapabilityPos + PCI_REBAR_CTRL);
nBars = BITS(controlRegister, 5, 3); // control register's bits 5,6 and 7 contain number of resizable bars information
for (auto barNumber = 0u; barNumber < nBars; barNumber++) {
uint32_t barId = 0;
controlRegister = getDwordFromConfig(rebarCapabilityPos + PCI_REBAR_CTRL);
barId = BITS(controlRegister, 0, 3); // Control register's bit 0,1,2 tells the index of bar
if (barId == barIndex) {
isBarResizable = true;
break;
}
rebarCapabilityPos += 8;
}
if (isBarResizable == false) {
return false;
}
capabilityRegister = getDwordFromConfig(rebarCapabilityPos + PCI_REBAR_CAP);
// Capability register's bit 4 to 31 indicates supported Bar sizes.
// In possibleBarSizes, position of each set bit indicates supported bar size. Example, if set bit
// position of possibleBarSizes is from 0 to n, then this indicates BAR size from 2^0 MB to 2^n MB
auto possibleBarSizes = (capabilityRegister & PCI_REBAR_CAP_SIZES) >> 4; // First 4 bits are reserved
uint32_t largestPossibleBarSize = 0;
while (possibleBarSizes >>= 1) { // most significant set bit position of possibleBarSizes would tell larget possible bar size
largestPossibleBarSize++;
}
// Control register's bit 8 to 13 indicates current BAR size in encoded form.
// Example, real value of current size could be 2^currentSize MB
auto currentSize = BITS(controlRegister, 8, 6);
// If current size is equal to larget possible BAR size, it indicates resizable BAR is enabled.
return (currentSize == largestPossibleBarSize);
}
ze_result_t LinuxPciImp::getState(zes_pci_state_t *state) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s() returning UNSUPPORTED_FEATURE \n", __FUNCTION__);
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
void LinuxPciImp::pciExtendedConfigRead() {
std::string pciConfigNode;
pSysfsAccess->getRealPath("device/config", pciConfigNode);
int fdConfig = -1;
fdConfig = this->openFunction(pciConfigNode.c_str(), O_RDONLY);
if (fdConfig < 0) {
return;
}
configMemory = std::make_unique<uint8_t[]>(PCI_CFG_SPACE_EXP_SIZE);
memset(configMemory.get(), 0, PCI_CFG_SPACE_EXP_SIZE);
this->preadFunction(fdConfig, configMemory.get(), PCI_CFG_SPACE_EXP_SIZE, 0);
this->closeFunction(fdConfig);
}
void LinuxPciImp::pciCardBusConfigRead() {
std::string pciConfigNode;
std::string rootPortPath;
pSysfsAccess->getRealPath(deviceDir, pciConfigNode);
rootPortPath = pLinuxSysmanImp->getPciCardBusDirectoryPath(pciConfigNode);
pciConfigNode = rootPortPath + "/config";
int fdConfig = -1;
fdConfig = this->openFunction(pciConfigNode.c_str(), O_RDONLY);
if (fdConfig < 0) {
return;
}
uspConfigMemory = std::make_unique<uint8_t[]>(PCI_CFG_SPACE_SIZE);
memset(uspConfigMemory.get(), 0, PCI_CFG_SPACE_SIZE);
this->preadFunction(fdConfig, uspConfigMemory.get(), PCI_CFG_SPACE_SIZE, 0);
this->closeFunction(fdConfig);
}
LinuxPciImp::LinuxPciImp(OsSysman *pOsSysman) {
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
isIntegratedDevice = pLinuxSysmanImp->getSysmanDeviceImp()->getRootDeviceEnvironment().getHardwareInfo()->capabilityTable.isIntegratedDevice;
if (pSysfsAccess->isRootUser()) {
pciExtendedConfigRead();
pciCardBusConfigRead();
}
}
OsPci *OsPci::create(OsSysman *pOsSysman) {
LinuxPciImp *pLinuxPciImp = new LinuxPciImp(pOsSysman);
return static_cast<OsPci *>(pLinuxPciImp);
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "level_zero/sysman/source/linux/fs_access.h"
#include "level_zero/sysman/source/linux/os_sysman_imp.h"
#include "level_zero/sysman/source/pci/os_pci.h"
#include <fcntl.h>
namespace L0 {
namespace Sysman {
class LinuxPciImp : public OsPci, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getPciBdf(zes_pci_properties_t &pciProperties) override;
void getMaxLinkCaps(double &maxLinkSpeed, int32_t &maxLinkWidth) override;
ze_result_t getState(zes_pci_state_t *state) override;
ze_result_t getProperties(zes_pci_properties_t *properties) override;
bool resizableBarSupported() override;
bool resizableBarEnabled(uint32_t barIndex) override;
ze_result_t initializeBarProperties(std::vector<zes_pci_bar_properties_t *> &pBarProperties) override;
LinuxPciImp() = default;
LinuxPciImp(OsSysman *pOsSysman);
~LinuxPciImp() override = default;
protected:
L0::Sysman::SysfsAccess *pSysfsAccess = nullptr;
L0::Sysman::LinuxSysmanImp *pLinuxSysmanImp = nullptr;
std::unique_ptr<uint8_t[]> configMemory;
std::unique_ptr<uint8_t[]> uspConfigMemory;
void pciExtendedConfigRead();
void pciCardBusConfigRead();
decltype(&NEO::SysCalls::open) openFunction = NEO::SysCalls::open;
decltype(&NEO::SysCalls::close) closeFunction = NEO::SysCalls::close;
decltype(&NEO::SysCalls::pread) preadFunction = NEO::SysCalls::pread;
private:
static const std::string deviceDir;
static const std::string resourceFile;
static const std::string maxLinkSpeedFile;
static const std::string maxLinkWidthFile;
bool isIntegratedDevice = false;
uint32_t getDwordFromConfig(uint32_t pos) {
return configMemory[pos] | (configMemory[pos + 1] << 8) |
(configMemory[pos + 2] << 16) | (configMemory[pos + 3] << 24);
}
uint16_t getWordFromConfig(uint32_t pos, uint8_t *configMem) {
return configMem[pos] | (configMem[pos + 1] << 8);
}
uint8_t getByteFromConfig(uint32_t pos, uint8_t *configMem) {
return configMem[pos];
}
uint32_t getRebarCapabilityPos();
uint16_t getLinkCapabilityPos();
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/sysman/source/os_sysman.h"
#include <vector>
namespace L0 {
namespace Sysman {
int64_t convertPcieSpeedFromGTsToBs(double maxLinkSpeedInGt);
int32_t convertLinkSpeedToPciGen(double speed);
double convertPciGenToLinkSpeed(uint32_t gen);
class OsPci {
public:
virtual ze_result_t getPciBdf(zes_pci_properties_t &pciProperties) = 0;
virtual void getMaxLinkCaps(double &maxLinkSpeed, int32_t &maxLinkWidth) = 0;
virtual ze_result_t getState(zes_pci_state_t *state) = 0;
virtual ze_result_t getProperties(zes_pci_properties_t *properties) = 0;
virtual bool resizableBarSupported() = 0;
virtual bool resizableBarEnabled(uint32_t barIndex) = 0;
virtual ze_result_t initializeBarProperties(std::vector<zes_pci_bar_properties_t *> &pBarProperties) = 0;
static OsPci *create(OsSysman *pOsSysman);
virtual ~OsPci() = default;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <level_zero/zes_api.h>
namespace L0 {
namespace Sysman {
class Pci {
public:
virtual ~Pci(){};
virtual ze_result_t pciStaticProperties(zes_pci_properties_t *pProperties) = 0;
virtual ze_result_t pciGetInitializedBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) = 0;
virtual ze_result_t pciGetState(zes_pci_state_t *pState) = 0;
virtual void init() = 0;
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,173 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/pci/pci_imp.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/string.h"
#include "shared/source/utilities/directory.h"
#include "level_zero/sysman/source/sysman_const.h"
namespace L0 {
namespace Sysman {
//
// While computing the PCIe bandwidth, also consider that due to 8b/10b encoding
// in PCIe gen1 and gen2 real bandwidth will be reduced by 20%,
// And in case of gen3 and above due to 128b/130b encoding real bandwidth is
// reduced by approx 1.54% as compared to theoretical bandwidth.
// In below method, get real PCIe speed in pcieSpeedWithEnc in Mega bits per second
// pcieSpeedWithEnc = maxLinkSpeedInGt * (Gigabit to Megabit) * Encoding =
// maxLinkSpeedInGt * 1000 * Encoding
//
int64_t convertPcieSpeedFromGTsToBs(double maxLinkSpeedInGt) {
double pcieSpeedWithEnc;
if ((maxLinkSpeedInGt == PciLinkSpeeds::Pci32_0GigatransfersPerSecond) || (maxLinkSpeedInGt == PciLinkSpeeds::Pci16_0GigatransfersPerSecond) || (maxLinkSpeedInGt == PciLinkSpeeds::Pci8_0GigatransfersPerSecond)) {
pcieSpeedWithEnc = maxLinkSpeedInGt * 1000 * 128 / 130;
} else if ((maxLinkSpeedInGt == PciLinkSpeeds::Pci5_0GigatransfersPerSecond) || (maxLinkSpeedInGt == PciLinkSpeeds::Pci2_5GigatransfersPerSecond)) {
pcieSpeedWithEnc = maxLinkSpeedInGt * 1000 * 8 / 10;
} else {
pcieSpeedWithEnc = 0;
}
//
// PCIE speed we got above is in Mega bits per second
// Convert that speed in bytes/second.
// Now, because 1Mb/s = (1000*1000)/8 bytes/second = 125000 bytes/second
//
pcieSpeedWithEnc = pcieSpeedWithEnc * 125000;
return static_cast<int64_t>(pcieSpeedWithEnc);
}
double convertPciGenToLinkSpeed(uint32_t gen) {
switch (gen) {
case PciGenerations::PciGen1: {
return PciLinkSpeeds::Pci2_5GigatransfersPerSecond;
} break;
case PciGenerations::PciGen2: {
return PciLinkSpeeds::Pci5_0GigatransfersPerSecond;
} break;
case PciGenerations::PciGen3: {
return PciLinkSpeeds::Pci8_0GigatransfersPerSecond;
} break;
case PciGenerations::PciGen4: {
return PciLinkSpeeds::Pci16_0GigatransfersPerSecond;
} break;
case PciGenerations::PciGen5: {
return PciLinkSpeeds::Pci32_0GigatransfersPerSecond;
} break;
default: {
return 0.0;
} break;
}
}
int32_t convertLinkSpeedToPciGen(double speed) {
if (speed == PciLinkSpeeds::Pci2_5GigatransfersPerSecond) {
return PciGenerations::PciGen1;
} else if (speed == PciLinkSpeeds::Pci5_0GigatransfersPerSecond) {
return PciGenerations::PciGen2;
} else if (speed == PciLinkSpeeds::Pci8_0GigatransfersPerSecond) {
return PciGenerations::PciGen3;
} else if (speed == PciLinkSpeeds::Pci16_0GigatransfersPerSecond) {
return PciGenerations::PciGen4;
} else if (speed == PciLinkSpeeds::Pci32_0GigatransfersPerSecond) {
return PciGenerations::PciGen5;
} else {
return -1;
}
}
ze_result_t PciImp::pciStaticProperties(zes_pci_properties_t *pProperties) {
initPci();
*pProperties = pciProperties;
return ZE_RESULT_SUCCESS;
}
ze_result_t PciImp::pciGetInitializedBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) {
initPci();
uint32_t pciBarPropertiesSize = static_cast<uint32_t>(pciBarProperties.size());
uint32_t numToCopy = std::min(*pCount, pciBarPropertiesSize);
if (0 == *pCount || *pCount > pciBarPropertiesSize) {
*pCount = pciBarPropertiesSize;
}
if (nullptr != pProperties) {
for (uint32_t i = 0; i < numToCopy; i++) {
pProperties[i].base = pciBarProperties[i]->base;
pProperties[i].index = pciBarProperties[i]->index;
pProperties[i].size = pciBarProperties[i]->size;
pProperties[i].type = pciBarProperties[i]->type;
if (pProperties[i].pNext != nullptr) {
zes_pci_bar_properties_1_2_t *pBarPropsExt = static_cast<zes_pci_bar_properties_1_2_t *>(pProperties[i].pNext);
if (pBarPropsExt->stype == zes_structure_type_t::ZES_STRUCTURE_TYPE_PCI_BAR_PROPERTIES_1_2) {
// base, index, size and type are the same as the non 1.2 struct.
pBarPropsExt->base = pciBarProperties[i]->base;
pBarPropsExt->index = pciBarProperties[i]->index;
pBarPropsExt->size = pciBarProperties[i]->size;
pBarPropsExt->type = pciBarProperties[i]->type;
pBarPropsExt->resizableBarSupported = static_cast<ze_bool_t>(resizableBarSupported);
pBarPropsExt->resizableBarEnabled = static_cast<ze_bool_t>(pOsPci->resizableBarEnabled(pBarPropsExt->index));
}
}
}
}
return ZE_RESULT_SUCCESS;
}
ze_result_t PciImp::pciGetState(zes_pci_state_t *pState) {
initPci();
return pOsPci->getState(pState);
}
void PciImp::pciGetStaticFields() {
pOsPci->getProperties(&pciProperties);
resizableBarSupported = pOsPci->resizableBarSupported();
std::string bdf;
pOsPci->getPciBdf(pciProperties);
int32_t maxLinkWidth = -1;
int64_t maxBandWidth = -1;
double maxLinkSpeed = 0;
pOsPci->getMaxLinkCaps(maxLinkSpeed, maxLinkWidth);
maxBandWidth = maxLinkWidth * convertPcieSpeedFromGTsToBs(maxLinkSpeed);
if (maxBandWidth == 0) {
pciProperties.maxSpeed.maxBandwidth = -1;
} else {
pciProperties.maxSpeed.maxBandwidth = maxBandWidth;
}
pciProperties.maxSpeed.width = maxLinkWidth;
pciProperties.maxSpeed.gen = convertLinkSpeedToPciGen(maxLinkSpeed);
pOsPci->initializeBarProperties(pciBarProperties);
}
void PciImp::initPci() {
std::call_once(initPciOnce, [this]() {
this->init();
});
}
void PciImp::init() {
if (pOsPci == nullptr) {
pOsPci = OsPci::create(pOsSysman);
}
UNRECOVERABLE_IF(nullptr == pOsPci);
pciGetStaticFields();
}
PciImp::~PciImp() {
for (zes_pci_bar_properties_t *pProperties : pciBarProperties) {
delete pProperties;
pProperties = nullptr;
}
if (nullptr != pOsPci) {
delete pOsPci;
pOsPci = nullptr;
}
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "level_zero/sysman/source/pci/os_pci.h"
#include "level_zero/sysman/source/pci/pci.h"
#include <mutex>
#include <vector>
namespace L0 {
namespace Sysman {
class PciImp : public L0::Sysman::Pci, NEO::NonCopyableOrMovableClass {
public:
void init() override;
ze_result_t pciStaticProperties(zes_pci_properties_t *pProperties) override;
ze_result_t pciGetInitializedBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) override;
ze_result_t pciGetState(zes_pci_state_t *pState) override;
void pciGetStaticFields();
PciImp() = default;
PciImp(L0::Sysman::OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
~PciImp() override;
L0::Sysman::OsPci *pOsPci = nullptr;
private:
L0::Sysman::OsSysman *pOsSysman = nullptr;
bool resizableBarSupported = false;
zes_pci_properties_t pciProperties = {};
std::vector<zes_pci_bar_properties_t *> pciBarProperties = {};
std::once_flag initPciOnce;
void initPci();
};
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,14 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(WIN32)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/os_pci_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_pci_imp.h
)
endif()

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/sysman/source/pci/windows/os_pci_imp.h"
namespace L0 {
namespace Sysman {
ze_result_t WddmPciImp::getProperties(zes_pci_properties_t *properties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmPciImp::getPciBdf(zes_pci_properties_t &pciProperties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
void WddmPciImp::getMaxLinkCaps(double &maxLinkSpeed, int32_t &maxLinkWidth) {}
ze_result_t WddmPciImp::getState(zes_pci_state_t *state) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
bool WddmPciImp::resizableBarSupported() {
return false;
}
bool WddmPciImp::resizableBarEnabled(uint32_t barIndex) {
return false;
}
ze_result_t WddmPciImp::initializeBarProperties(std::vector<zes_pci_bar_properties_t *> &pBarProperties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
WddmPciImp::WddmPciImp(OsSysman *pOsSysman) {}
OsPci *OsPci::create(OsSysman *pOsSysman) {
WddmPciImp *pWddmPciImp = new WddmPciImp(pOsSysman);
return static_cast<OsPci *>(pWddmPciImp);
}
} // namespace Sysman
} // namespace L0

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "level_zero/sysman/source/pci/os_pci.h"
#include "level_zero/sysman/source/windows/os_sysman_imp.h"
namespace L0 {
namespace Sysman {
class KmdSysManager;
class WddmPciImp : public OsPci, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getPciBdf(zes_pci_properties_t &pciProperties) override;
void getMaxLinkCaps(double &maxLinkSpeed, int32_t &maxLinkWidth) override;
ze_result_t getState(zes_pci_state_t *state) override;
ze_result_t getProperties(zes_pci_properties_t *properties) override;
bool resizableBarSupported() override;
bool resizableBarEnabled(uint32_t barIndex) override;
ze_result_t initializeBarProperties(std::vector<zes_pci_bar_properties_t *> &pBarProperties) override;
WddmPciImp(OsSysman *pOsSysman);
WddmPciImp() = default;
~WddmPciImp() override = default;
};
} // namespace Sysman
} // namespace L0

View File

@@ -129,5 +129,25 @@ ze_result_t SysmanDevice::performanceGet(zes_device_handle_t hDevice, uint32_t *
return pSysmanDevice->performanceGet(pCount, phPerformance);
}
ze_result_t SysmanDevice::pciGetProperties(zes_device_handle_t hDevice, zes_pci_properties_t *pProperties) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->pciGetProperties(pProperties);
}
ze_result_t SysmanDevice::pciGetState(zes_device_handle_t hDevice, zes_pci_state_t *pState) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->pciGetState(pState);
}
ze_result_t SysmanDevice::pciGetBars(zes_device_handle_t hDevice, uint32_t *pCount, zes_pci_bar_properties_t *pProperties) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->pciGetBars(pCount, pProperties);
}
ze_result_t SysmanDevice::pciGetStats(zes_device_handle_t hDevice, zes_pci_stats_t *pStats) {
auto pSysmanDevice = L0::Sysman::SysmanDevice::fromHandle(hDevice);
return pSysmanDevice->pciGetStats(pStats);
}
} // namespace Sysman
} // namespace L0

View File

@@ -17,6 +17,7 @@
#include "level_zero/sysman/source/frequency/frequency.h"
#include "level_zero/sysman/source/global_operations/global_operations.h"
#include "level_zero/sysman/source/memory/memory.h"
#include "level_zero/sysman/source/pci/pci.h"
#include "level_zero/sysman/source/performance/performance.h"
#include "level_zero/sysman/source/power/power.h"
#include "level_zero/sysman/source/ras/ras.h"
@@ -98,6 +99,18 @@ struct SysmanDevice : _ze_device_handle_t {
static ze_result_t performanceGet(zes_device_handle_t hDevice, uint32_t *pCount, zes_perf_handle_t *phPerformance);
virtual ze_result_t performanceGet(uint32_t *pCount, zes_perf_handle_t *phPerformance) = 0;
static ze_result_t pciGetProperties(zes_device_handle_t hDevice, zes_pci_properties_t *pProperties);
virtual ze_result_t pciGetProperties(zes_pci_properties_t *pProperties) = 0;
static ze_result_t pciGetState(zes_device_handle_t hDevice, zes_pci_state_t *pState);
virtual ze_result_t pciGetState(zes_pci_state_t *pState) = 0;
static ze_result_t pciGetBars(zes_device_handle_t hDevice, uint32_t *pCount, zes_pci_bar_properties_t *pProperties);
virtual ze_result_t pciGetBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) = 0;
static ze_result_t pciGetStats(zes_device_handle_t hDevice, zes_pci_stats_t *pStats);
virtual ze_result_t pciGetStats(zes_pci_stats_t *pStats) = 0;
};
} // namespace Sysman

View File

@@ -12,6 +12,7 @@
#include "level_zero/sysman/source/ecc/ecc_imp.h"
#include "level_zero/sysman/source/global_operations/global_operations_imp.h"
#include "level_zero/sysman/source/os_sysman.h"
#include "level_zero/sysman/source/pci/pci_imp.h"
#include <vector>
@@ -37,6 +38,7 @@ SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment
pPerformanceHandleContext = new PerformanceHandleContext(pOsSysman);
pEcc = new EccImp(pOsSysman);
pTempHandleContext = new TemperatureHandleContext(pOsSysman);
pPci = new PciImp(pOsSysman);
}
SysmanDeviceImp::~SysmanDeviceImp() {
@@ -54,6 +56,7 @@ SysmanDeviceImp::~SysmanDeviceImp() {
freeResource(pPerformanceHandleContext);
freeResource(pEcc);
freeResource(pTempHandleContext);
freeResource(pPci);
freeResource(pOsSysman);
executionEnvironment->decRefInternal();
}
@@ -150,5 +153,21 @@ ze_result_t SysmanDeviceImp::performanceGet(uint32_t *pCount, zes_perf_handle_t
return pPerformanceHandleContext->performanceGet(pCount, phPerformance);
}
ze_result_t SysmanDeviceImp::pciGetProperties(zes_pci_properties_t *pProperties) {
return pPci->pciStaticProperties(pProperties);
}
ze_result_t SysmanDeviceImp::pciGetState(zes_pci_state_t *pState) {
return pPci->pciGetState(pState);
}
ze_result_t SysmanDeviceImp::pciGetBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) {
return pPci->pciGetInitializedBars(pCount, pProperties);
}
ze_result_t SysmanDeviceImp::pciGetStats(zes_pci_stats_t *pStats) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
} // namespace Sysman
} // namespace L0

View File

@@ -51,6 +51,7 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
PerformanceHandleContext *pPerformanceHandleContext = nullptr;
Ecc *pEcc = nullptr;
TemperatureHandleContext *pTempHandleContext = nullptr;
Pci *pPci = nullptr;
ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) override;
ze_result_t powerGetCardDomain(zes_pwr_handle_t *phPower) override;
@@ -73,6 +74,10 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
ze_result_t deviceSetEccState(const zes_device_ecc_desc_t *newState, zes_device_ecc_properties_t *pState) override;
ze_result_t temperatureGet(uint32_t *pCount, zes_temp_handle_t *phTemperature) override;
ze_result_t performanceGet(uint32_t *pCount, zes_perf_handle_t *phPerformance) override;
ze_result_t pciGetProperties(zes_pci_properties_t *pProperties) override;
ze_result_t pciGetState(zes_pci_state_t *pState) override;
ze_result_t pciGetBars(uint32_t *pCount, zes_pci_bar_properties_t *pProperties) override;
ze_result_t pciGetStats(zes_pci_stats_t *pStats) override;
private:
NEO::ExecutionEnvironment *executionEnvironment = nullptr;