16f9e7a76SPrithvi Pai #include "firmware_inventory.hpp"
26f9e7a76SPrithvi Pai
36f9e7a76SPrithvi Pai #include "mdrv2.hpp"
46f9e7a76SPrithvi Pai
56f9e7a76SPrithvi Pai #include <boost/algorithm/string.hpp>
66f9e7a76SPrithvi Pai
76f9e7a76SPrithvi Pai #include <fstream>
86f9e7a76SPrithvi Pai #include <iomanip>
96f9e7a76SPrithvi Pai #include <iostream>
106f9e7a76SPrithvi Pai #include <regex>
116f9e7a76SPrithvi Pai #include <sstream>
126f9e7a76SPrithvi Pai
136f9e7a76SPrithvi Pai namespace phosphor
146f9e7a76SPrithvi Pai {
156f9e7a76SPrithvi Pai namespace smbios
166f9e7a76SPrithvi Pai {
176f9e7a76SPrithvi Pai namespace utils
186f9e7a76SPrithvi Pai {
getExistingVersionPaths(sdbusplus::bus_t & bus)196f9e7a76SPrithvi Pai std::vector<std::string> getExistingVersionPaths(sdbusplus::bus_t& bus)
206f9e7a76SPrithvi Pai {
216f9e7a76SPrithvi Pai std::vector<std::string> existingVersionPaths;
226f9e7a76SPrithvi Pai
236f9e7a76SPrithvi Pai auto getVersionPaths = bus.new_method_call(
246f9e7a76SPrithvi Pai phosphor::smbios::mapperBusName, phosphor::smbios::mapperPath,
256f9e7a76SPrithvi Pai phosphor::smbios::mapperInterface, "GetSubTreePaths");
266f9e7a76SPrithvi Pai getVersionPaths.append(firmwarePath);
276f9e7a76SPrithvi Pai getVersionPaths.append(0);
286f9e7a76SPrithvi Pai getVersionPaths.append(
296f9e7a76SPrithvi Pai std::array<std::string, 1>({phosphor::smbios::versionInterface}));
306f9e7a76SPrithvi Pai
316f9e7a76SPrithvi Pai try
326f9e7a76SPrithvi Pai {
336f9e7a76SPrithvi Pai auto reply = bus.call(getVersionPaths);
346f9e7a76SPrithvi Pai reply.read(existingVersionPaths);
356f9e7a76SPrithvi Pai }
366f9e7a76SPrithvi Pai catch (const sdbusplus::exception_t& e)
376f9e7a76SPrithvi Pai {
386f9e7a76SPrithvi Pai lg2::error("Failed to query version objects. ERROR={E}", "E", e.what());
396f9e7a76SPrithvi Pai existingVersionPaths.clear();
406f9e7a76SPrithvi Pai }
416f9e7a76SPrithvi Pai
426f9e7a76SPrithvi Pai return existingVersionPaths;
436f9e7a76SPrithvi Pai }
446f9e7a76SPrithvi Pai } // namespace utils
456f9e7a76SPrithvi Pai
getFirmwareInventoryData(uint8_t * & dataIn,int inventoryIndex)466f9e7a76SPrithvi Pai bool FirmwareInventory::getFirmwareInventoryData(uint8_t*& dataIn,
476f9e7a76SPrithvi Pai int inventoryIndex)
486f9e7a76SPrithvi Pai {
496f9e7a76SPrithvi Pai dataIn = getSMBIOSTypePtr(dataIn, firmwareInventoryInformationType);
506f9e7a76SPrithvi Pai if (dataIn == nullptr)
516f9e7a76SPrithvi Pai {
526f9e7a76SPrithvi Pai return false;
536f9e7a76SPrithvi Pai }
546f9e7a76SPrithvi Pai for (uint8_t index = 0; index < inventoryIndex; index++)
556f9e7a76SPrithvi Pai {
566f9e7a76SPrithvi Pai dataIn = smbiosNextPtr(dataIn);
576f9e7a76SPrithvi Pai if (dataIn == nullptr)
586f9e7a76SPrithvi Pai {
596f9e7a76SPrithvi Pai return false;
606f9e7a76SPrithvi Pai }
616f9e7a76SPrithvi Pai dataIn = getSMBIOSTypePtr(dataIn, firmwareInventoryInformationType);
626f9e7a76SPrithvi Pai if (dataIn == nullptr)
636f9e7a76SPrithvi Pai {
646f9e7a76SPrithvi Pai return false;
656f9e7a76SPrithvi Pai }
666f9e7a76SPrithvi Pai }
676f9e7a76SPrithvi Pai return true;
686f9e7a76SPrithvi Pai }
696f9e7a76SPrithvi Pai
firmwareInfoUpdate(uint8_t * smbiosTableStorage)706f9e7a76SPrithvi Pai void FirmwareInventory::firmwareInfoUpdate(uint8_t* smbiosTableStorage)
716f9e7a76SPrithvi Pai {
726f9e7a76SPrithvi Pai uint8_t* dataIn = smbiosTableStorage;
736f9e7a76SPrithvi Pai if (!getFirmwareInventoryData(dataIn, firmwareInventoryIndex))
746f9e7a76SPrithvi Pai {
756f9e7a76SPrithvi Pai lg2::info("Failed to get data for firmware inventory index {I}", "I",
766f9e7a76SPrithvi Pai firmwareInventoryIndex);
776f9e7a76SPrithvi Pai return;
786f9e7a76SPrithvi Pai }
796f9e7a76SPrithvi Pai
806f9e7a76SPrithvi Pai auto firmwareInfo = reinterpret_cast<struct FirmwareInfo*>(dataIn);
816f9e7a76SPrithvi Pai
826f9e7a76SPrithvi Pai firmwareComponentName(firmwareInfo->componentName, firmwareInfo->length,
836f9e7a76SPrithvi Pai dataIn);
846f9e7a76SPrithvi Pai firmwareVersion(firmwareInfo->version, firmwareInfo->length, dataIn);
856f9e7a76SPrithvi Pai firmwareId(firmwareInfo->id, firmwareInfo->length, dataIn);
866f9e7a76SPrithvi Pai firmwareReleaseDate(firmwareInfo->releaseDate, firmwareInfo->length,
876f9e7a76SPrithvi Pai dataIn);
886f9e7a76SPrithvi Pai firmwareManufacturer(firmwareInfo->manufacturer, firmwareInfo->length,
896f9e7a76SPrithvi Pai dataIn);
906f9e7a76SPrithvi Pai present(true);
916f9e7a76SPrithvi Pai purpose(softwareVersion::VersionPurpose::Other);
926f9e7a76SPrithvi Pai }
936f9e7a76SPrithvi Pai
946f9e7a76SPrithvi Pai std::string FirmwareInventory::checkAndCreateFirmwarePath(
956f9e7a76SPrithvi Pai uint8_t* dataIn, int inventoryIndex,
966f9e7a76SPrithvi Pai std::vector<std::string>& existingVersionPaths)
976f9e7a76SPrithvi Pai {
986f9e7a76SPrithvi Pai if (!getFirmwareInventoryData(dataIn, inventoryIndex))
checkAndCreateFirmwarePath(uint8_t * dataIn,int inventoryIndex,std::vector<std::string> & existingVersionPaths)996f9e7a76SPrithvi Pai {
1006f9e7a76SPrithvi Pai lg2::info("Failed to get data for firmware inventory index {I}", "I",
1016f9e7a76SPrithvi Pai inventoryIndex);
1026f9e7a76SPrithvi Pai return "";
1036f9e7a76SPrithvi Pai }
1046f9e7a76SPrithvi Pai auto firmwareInfo = reinterpret_cast<struct FirmwareInfo*>(dataIn);
1056f9e7a76SPrithvi Pai std::string firmwareId =
1066f9e7a76SPrithvi Pai positionToString(firmwareInfo->id, firmwareInfo->length, dataIn);
1076f9e7a76SPrithvi Pai auto firmwareName = positionToString(firmwareInfo->componentName,
1086f9e7a76SPrithvi Pai firmwareInfo->length, dataIn);
1096f9e7a76SPrithvi Pai std::string firmwareObjPath = "";
1106f9e7a76SPrithvi Pai #ifdef EXPOSE_FW_COMPONENT_NAME
1116f9e7a76SPrithvi Pai firmwareObjPath = firmwareName;
1126f9e7a76SPrithvi Pai #else
1136f9e7a76SPrithvi Pai firmwareObjPath = firmwareId;
1146f9e7a76SPrithvi Pai #endif
1156f9e7a76SPrithvi Pai if (firmwareInfo->numOfAssociatedComponents > 0)
1166f9e7a76SPrithvi Pai {
1176f9e7a76SPrithvi Pai for (int i = 0; i < firmwareInfo->numOfAssociatedComponents; i++)
1186f9e7a76SPrithvi Pai {
1196f9e7a76SPrithvi Pai auto component = smbiosHandlePtr(
1206f9e7a76SPrithvi Pai dataIn, firmwareInfo->associatedComponentHandles[i]);
1216f9e7a76SPrithvi Pai if (component == nullptr)
1226f9e7a76SPrithvi Pai {
1236f9e7a76SPrithvi Pai continue;
1246f9e7a76SPrithvi Pai }
1256f9e7a76SPrithvi Pai
1266f9e7a76SPrithvi Pai auto header = reinterpret_cast<struct StructureHeader*>(component);
1276f9e7a76SPrithvi Pai switch (header->type)
1286f9e7a76SPrithvi Pai {
1296f9e7a76SPrithvi Pai case processorsType:
1306f9e7a76SPrithvi Pai case systemSlots:
1316f9e7a76SPrithvi Pai case onboardDevicesExtended:
1326f9e7a76SPrithvi Pai {
1336f9e7a76SPrithvi Pai auto designation = positionToString(
1346f9e7a76SPrithvi Pai component[4], header->length, component);
1356f9e7a76SPrithvi Pai if (!designation.empty())
1366f9e7a76SPrithvi Pai {
1376f9e7a76SPrithvi Pai firmwareObjPath.append("_").append(designation);
1386f9e7a76SPrithvi Pai }
1396f9e7a76SPrithvi Pai break;
1406f9e7a76SPrithvi Pai }
1416f9e7a76SPrithvi Pai case systemPowerSupply:
1426f9e7a76SPrithvi Pai {
1436f9e7a76SPrithvi Pai auto location = positionToString(component[5],
1446f9e7a76SPrithvi Pai header->length, component);
1456f9e7a76SPrithvi Pai if (!location.empty())
1466f9e7a76SPrithvi Pai {
1476f9e7a76SPrithvi Pai firmwareObjPath.append("_").append(location);
1486f9e7a76SPrithvi Pai }
1496f9e7a76SPrithvi Pai break;
1506f9e7a76SPrithvi Pai }
1516f9e7a76SPrithvi Pai default:
1526f9e7a76SPrithvi Pai break;
1536f9e7a76SPrithvi Pai }
1546f9e7a76SPrithvi Pai }
1556f9e7a76SPrithvi Pai }
1566f9e7a76SPrithvi Pai if (firmwareObjPath.empty())
1576f9e7a76SPrithvi Pai {
1586f9e7a76SPrithvi Pai firmwareObjPath = "firmware" + std::to_string(inventoryIndex);
1596f9e7a76SPrithvi Pai }
1606f9e7a76SPrithvi Pai boost::algorithm::trim_right(firmwareObjPath);
1616f9e7a76SPrithvi Pai firmwareObjPath =
1626f9e7a76SPrithvi Pai std::regex_replace(firmwareObjPath, std::regex("[^a-zA-Z0-9_/]+"), "_");
1636f9e7a76SPrithvi Pai
1646f9e7a76SPrithvi Pai auto eqObjName = [firmwareObjPath](std::string s) {
1656f9e7a76SPrithvi Pai std::filesystem::path p(s);
1666f9e7a76SPrithvi Pai return p.filename().compare(firmwareObjPath) == 0;
1676f9e7a76SPrithvi Pai };
1686f9e7a76SPrithvi Pai if (std::find_if(existingVersionPaths.begin(), existingVersionPaths.end(),
__anonf8ba24900102(std::string s) 1696f9e7a76SPrithvi Pai std::move(eqObjName)) != existingVersionPaths.end())
1706f9e7a76SPrithvi Pai {
1716f9e7a76SPrithvi Pai return "";
1726f9e7a76SPrithvi Pai }
1736f9e7a76SPrithvi Pai std::string path = firmwarePath;
1746f9e7a76SPrithvi Pai path.append("/").append(firmwareObjPath);
1756f9e7a76SPrithvi Pai return path;
1766f9e7a76SPrithvi Pai }
1776f9e7a76SPrithvi Pai
1786f9e7a76SPrithvi Pai void FirmwareInventory::firmwareComponentName(
1796f9e7a76SPrithvi Pai const uint8_t positionNum, const uint8_t structLen, uint8_t* dataIn)
1806f9e7a76SPrithvi Pai {
1816f9e7a76SPrithvi Pai std::string result = positionToString(positionNum, structLen, dataIn);
1826f9e7a76SPrithvi Pai prettyName(result);
firmwareComponentName(const uint8_t positionNum,const uint8_t structLen,uint8_t * dataIn)1836f9e7a76SPrithvi Pai }
1846f9e7a76SPrithvi Pai
1856f9e7a76SPrithvi Pai void FirmwareInventory::firmwareVersion(
1866f9e7a76SPrithvi Pai const uint8_t positionNum, const uint8_t structLen, uint8_t* dataIn)
1876f9e7a76SPrithvi Pai {
1886f9e7a76SPrithvi Pai std::string result = positionToString(positionNum, structLen, dataIn);
1896f9e7a76SPrithvi Pai version(result);
1906f9e7a76SPrithvi Pai }
1916f9e7a76SPrithvi Pai
1926f9e7a76SPrithvi Pai void FirmwareInventory::firmwareId(const uint8_t positionNum,
1936f9e7a76SPrithvi Pai const uint8_t structLen, uint8_t* dataIn)
1946f9e7a76SPrithvi Pai {
1956f9e7a76SPrithvi Pai std::string result = positionToString(positionNum, structLen, dataIn);
1966f9e7a76SPrithvi Pai extendedVersion(result);
firmwareId(const uint8_t positionNum,const uint8_t structLen,uint8_t * dataIn)1976f9e7a76SPrithvi Pai }
1986f9e7a76SPrithvi Pai
1996f9e7a76SPrithvi Pai void FirmwareInventory::firmwareReleaseDate(
2006f9e7a76SPrithvi Pai const uint8_t positionNum, const uint8_t structLen, uint8_t* dataIn)
2016f9e7a76SPrithvi Pai {
2026f9e7a76SPrithvi Pai std::string result = positionToString(positionNum, structLen, dataIn);
203*ac4cb328SPrithvi Pai releaseDate(result);
2046f9e7a76SPrithvi Pai }
2056f9e7a76SPrithvi Pai
2066f9e7a76SPrithvi Pai void FirmwareInventory::firmwareManufacturer(
2076f9e7a76SPrithvi Pai const uint8_t positionNum, const uint8_t structLen, uint8_t* dataIn)
2086f9e7a76SPrithvi Pai {
2096f9e7a76SPrithvi Pai std::string result = positionToString(positionNum, structLen, dataIn);
2106f9e7a76SPrithvi Pai manufacturer(result);
firmwareManufacturer(const uint8_t positionNum,const uint8_t structLen,uint8_t * dataIn)2116f9e7a76SPrithvi Pai }
2126f9e7a76SPrithvi Pai } // namespace smbios
2136f9e7a76SPrithvi Pai } // namespace phosphor
214