diff --git a/configuration/ibm/5000_power_vs.json b/configuration/ibm/5000_power_vs.json new file mode 100644 index 00000000..4c5703db --- /dev/null +++ b/configuration/ibm/5000_power_vs.json @@ -0,0 +1,27 @@ +{ + "/sys/bus/spi/drivers/at25/spi12.0/eeprom" : { + "VINI" : { + "PN": [49, 50, 51, 52, 53, 54] + } + }, + "/sys/bus/spi/drivers/at25/spi22.0/eeprom" : { + "VINI" : { + "PN": [49, 50, 51, 52, 53, 54, 55] + } + }, + "/sys/bus/spi/drivers/at25/spi32.0/eeprom" : { + "VINI" : { + "PN": [49, 50, 51, 52, 53, 54, 55, 56] + } + }, + "/sys/bus/spi/drivers/at25/spi42.0/eeprom" : { + "VINI" : { + "PN": [49, 50, 51, 52, 53, 54, 55, 56, 57] + } + }, + "/sys/bus/i2c/drivers/at24/8-0051/eeprom" : { + "VINI" : { + "PN": [49, 50, 51, 52, 53] + } + } +} \ No newline at end of file diff --git a/meson.build b/meson.build index fa9c9932..eb33f745 100644 --- a/meson.build +++ b/meson.build @@ -47,6 +47,7 @@ conf_data.set_quoted('JSON_ABSOLUTE_PATH_PREFIX', get_option('JSON_ABSOLUTE_PATH conf_data.set_quoted('SYSTEM_VPD_FILE_PATH', get_option('SYSTEM_VPD_FILE_PATH')) conf_data.set_quoted('VPD_SYMLIMK_PATH', get_option('VPD_SYMLIMK_PATH')) conf_data.set_quoted('PIM_PATH_PREFIX', get_option('PIM_PATH_PREFIX')) +conf_data.set_quoted('POWER_VS_JSON_5000', get_option('5000_POWER_VS_JSON')) configure_file(output: 'config.h', configuration : conf_data) diff --git a/meson_options.txt b/meson_options.txt index 72bd1d6d..51c7012f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,4 +10,5 @@ option('JSON_ABSOLUTE_PATH_PREFIX', type: 'string', value: '/usr/share/vpd/', d option('SYSTEM_VPD_FILE_PATH', type: 'string', value: '/sys/bus/i2c/drivers/at24/8-0050/eeprom', description: 'EEPROM path of system VPD.') option('VPD_SYMLIMK_PATH', type: 'string', value: '/var/lib/vpd', description: 'Symlink folder for VPD invnetory JSONs') option('PIM_PATH_PREFIX', type: 'string', value: '/xyz/openbmc_project/inventory', description: 'Prefix for PIM inventory paths.') -option('ibm_system', type: 'feature', value : 'enabled', description: 'Enable code specific to IBM systems.') \ No newline at end of file +option('ibm_system', type: 'feature', value : 'enabled', description: 'Enable code specific to IBM systems.') +option('POWER_VS_JSON_5000', type: 'string', value : '/usr/share/vpd/5000_power_vs.json', description: 'Json file that contains part number with respect to PowerVS system.') \ No newline at end of file diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp index 5faf8da8..ee9734a8 100644 --- a/vpd-manager/include/constants.hpp +++ b/vpd-manager/include/constants.hpp @@ -112,6 +112,8 @@ static constexpr auto SIZE_OF_8EQ_IN_PG = 24; // Zero based index position of first EQ in CP00's PG keyword static constexpr auto INDEX_OF_EQ0_IN_PG = 97; +static constexpr auto HEX_VALUE_5000 = 0x50; + constexpr auto systemInvPath = "/xyz/openbmc_project/inventory/system"; constexpr auto pimPath = "/xyz/openbmc_project/inventory"; constexpr auto pimIntf = "xyz.openbmc_project.Inventory.Manager"; @@ -120,9 +122,11 @@ constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI"; constexpr auto vsysInf = "com.ibm.ipzvpd.VSYS"; constexpr auto utilInf = "com.ibm.ipzvpd.UTIL"; constexpr auto vcenInf = "com.ibm.ipzvpd.VCEN"; +constexpr auto vsbpInf = "com.ibm.ipzvpd.VSBP"; constexpr auto kwdCCIN = "CC"; constexpr auto kwdRG = "RG"; constexpr auto kwdAMM = "D0"; +constexpr auto kwdIM = "IM"; constexpr auto kwdClearNVRAM_CreateLPAR = "D1"; constexpr auto kwdKeepAndClear = "D1"; constexpr auto kwdFC = "FC"; diff --git a/vpd-manager/include/manager.hpp b/vpd-manager/include/manager.hpp index cb64123b..0be493b0 100644 --- a/vpd-manager/include/manager.hpp +++ b/vpd-manager/include/manager.hpp @@ -271,6 +271,11 @@ class Manager */ void registerHostStateChangeCallback(); + /** + * @brief API to check for PowerVS configuration. + */ + void checkPowerVsConfiguration(); + /** * @brief API to process host state change callback. * diff --git a/vpd-manager/include/utility/vpd_specific_utility.hpp b/vpd-manager/include/utility/vpd_specific_utility.hpp index 601cbd31..1267a60d 100644 --- a/vpd-manager/include/utility/vpd_specific_utility.hpp +++ b/vpd-manager/include/utility/vpd_specific_utility.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -552,5 +553,42 @@ inline void resetDataUnderPIM(const std::string& i_objectPath, " with error: " + std::string(l_ex.what())); } } + +/** + * @brief API to read IM keyword value published over Dbus. + * + * @throw std::runtime_error. + * + * @param[in] i_sysConfigJson - System config JSON object. + * @return IM keywrod value read from DBus. Exception otherwise. + */ +inline types::BinaryVector readSystemIM(const nlohmann::json& i_sysConfigJson) +{ + if (i_sysConfigJson.empty()) + { + throw std::runtime_error("Invalid system config JSON."); + } + + const auto& l_inventoryPath = jsonUtility::getInventoryObjPathFromJson( + i_sysConfigJson, SYSTEM_VPD_FILE_PATH); + + if (l_inventoryPath.empty()) + { + throw std::runtime_error( + "Inventory path not found in Json for system VPD filepath."); + } + + const auto& l_retValue = dbusUtility::readDbusProperty( + constants::pimServiceName, l_inventoryPath, constants::vsbpInf, + constants::kwdIM); + + if (auto l_imValue = std::get_if(&l_retValue)) + { + return *l_imValue; + } + + throw std::runtime_error("Invalid type recieved for IM value."); +} + } // namespace vpdSpecificUtility } // namespace vpd diff --git a/vpd-manager/src/manager.cpp b/vpd-manager/src/manager.cpp index 7f9efd48..4e0d2f60 100644 --- a/vpd-manager/src/manager.cpp +++ b/vpd-manager/src/manager.cpp @@ -272,6 +272,7 @@ void Manager::SetTimerToDetectVpdCollectionStatus() { // cancel the timer l_timer.cancel(); + checkPowerVsConfiguration(); m_interface->set_property("CollectionStatus", std::string("Completed")); @@ -910,4 +911,87 @@ void Manager::performVpdRecollection() std::string(l_ex.what())); } } + +void Manager::checkPowerVsConfiguration() +{ + try + { + if (m_worker.get() != nullptr) + { + const auto& l_imValue = + vpdSpecificUtility::readSystemIM(m_worker->getSysCfgJsonObj()); + + // If the system is not a 5000 series system or image prefix is not + // MX. Abort process. + if ((l_imValue.at(0) != constants::HEX_VALUE_50)) /* && + (getImagePrefix() != "MX"))*/ + { + return; + } + + std::error_code l_ec; + if (!std::filesystem::exists(POWER_VS_JSON_5000, l_ec)) + { + std::string l_errMsg{ + "Call to filesystem exists failed for PowerVS JSON."}; + + if (l_ec) + { + l_errMsg += " with error code: " + l_ec.message(); + } + + throw std::runtime_error(l_errMsg); + } + + try + { + nlohmann::json l_parsedPwrVsJson = + jsonUtility::getParsedJson(POWER_VS_JSON_5000); + + for (const auto& [l_path, l_value] : l_parsedPwrVsJson.items()) + { + std::cout << "Path = " << l_path << std::endl; + if (!value.items().value().contains("PN")) + { + continue; + } + + types::BinaryVector l_kwdValue = + value.items().value()["PN"].get(); + + std::cout << "kwd value size = " << l_kwdValue.size() + << std::endl; + + /*updateKeyword( + l_path, + std::make_tuple(value.items().key(), + value.items().value().items().key(), + l_kwdValue));*/ + } + } + catch (const nlohmann::json::parse_error& l_ex) + { + throw(JsonException("Json parsing failed", POWER_VS_PN_JSON)); + } + } + + throw std::runtime_error("Failed to get worker instance."); + } + catch (const std::exception& l_ex) + { + types::ErrorType l_errTYype = types::ErrorType::InvalidSystem; + + if (typeid(ex) == std::type_index(typeid(JsonException))) + { + l_errTYype = types::ErrorType::JsonFailure; + } + + EventLogger::createSyncPel( + l_errTYype, types::SeverityType::Informational, __FILE__, + __FUNCTION__, 0, + "Failed to process powerVS configuration with error: " + + std::string(l_ex.what()), + std::nullopt, std::nullopt, std::nullopt, std::nullopt); + } +} } // namespace vpd