#include "phal_service_actions.hpp" #include #include #include #include #include #include using GardType = openpower::guard::GardType; namespace openpower { namespace pels { namespace phal { /** * @brief Helper function to get gard type based on * the given GardType string * * @param[in] guardTypeStr guard type enum value as a string * * @return GardType on success * Empty optional on failure */ std::optional getGardType(const std::string& guardTypeStr) { const std::unordered_map gardTypeMap = { {"GARD_Fatal", GardType::GARD_Fatal}, {"GARD_User_Manual", GardType::GARD_User_Manual}, {"GARD_Predictive", GardType::GARD_Predictive}, {"GARD_Spare", GardType::GARD_Spare}, {"GARD_Unrecoverable", GardType::GARD_Unrecoverable}, }; auto it = gardTypeMap.find(guardTypeStr); if (it != gardTypeMap.end()) { return it->second; } else { lg2::error("Invalid GardType ({GUARDTYPE})", "GUARDTYPE", guardTypeStr); } return std::nullopt; } /** * @brief Helper function to create guard records. * * User need to fill the JSON callouts array with below keywords/data * "Entitypath": entity path of the hardware from the PHAL device tree. * "Guardtype": The hardware isolation severity which is defined in * xyz.openbmc_project.HardwareIsolation.Entry * "Guarded": boolean, true to create gurad records. * * @param[in] jsonCallouts - The array of JSON callouts, or an empty object. * @param[in] plid - The PEL ID to be associated with the guard * @param[in] dataIface - The DataInterface object */ void createGuardRecords(const nlohmann::json& jsonCallouts, uint32_t plid, const DataInterfaceBase& dataIface) { if (jsonCallouts.empty()) { return; } if (!jsonCallouts.is_array()) { lg2::error("GUARD: Callout JSON isn't an array"); return; } for (const auto& _callout : jsonCallouts) { try { // Check Callout data conatains Guarded requests. if (!_callout.contains("Guarded")) { continue; } if (!_callout.at("Guarded").get()) { continue; } // Get Entity path required for guard D-bus method // "CreateWithEntityPath" if (!_callout.contains("EntityPath")) { lg2::error( "GUARD: Callout data, missing EntityPath information"); continue; } using EntityPath = std::vector; auto entityPath = _callout.at("EntityPath").get(); std::stringstream ss; std::ranges::for_each(entityPath, [&ss](const auto& ele) { ss << std::format("{:02x} ", ele); }); std::string s = ss.str(); lg2::info("GUARD: ({GUARD_TARGET})", "GUARD_TARGET", s); // Get Guard type std::string guardTypeStr = "GARD_Predictive"; if (!_callout.contains("GuardType")) { lg2::error( "GUARD: doesn't have Severity, setting to GARD_Predictive"); } else { guardTypeStr = _callout.at("GuardType").get(); } GardType eGuardType = getGardType(guardTypeStr).value_or(GardType::GARD_Predictive); dataIface.createGuardRecord(entityPath, eGuardType, plid); } catch (const std::exception& e) { lg2::info("GUARD: Failed entry creation exception:({EXCEPTION})", "EXCEPTION", e); } } } /** * @brief Helper function to create deconfig records. * * User need to fill the JSON callouts array with below keywords/data * "EntityPath": entity path of the hardware from the PHAL device tree. * "Deconfigured": boolean, true to create deconfigure records. * * libphal api is used for creating deconfigure records, which includes * update HWAS_STATE attribute to non functional with PLID information. * * @param[in] jsonCallouts - The array of JSON callouts, or an empty object. * @param[in] plid - PLID value */ void createDeconfigRecords(const nlohmann::json& jsonCallouts, uint32_t plid) { using namespace openpower::phal::pdbg; if (jsonCallouts.empty()) { return; } if (!jsonCallouts.is_array()) { lg2::error("Deconfig: Callout JSON isn't an array"); return; } for (const auto& _callout : jsonCallouts) { try { // Check Callout data conatains Guarded requests. if (!_callout.contains("Deconfigured")) { continue; } if (!_callout.at("Deconfigured").get()) { continue; } if (!_callout.contains("EntityPath")) { lg2::error( "Deconfig: Callout data missing EntityPath information"); continue; } using EntityPath = std::vector; auto entityPath = _callout.at("EntityPath").get(); lg2::info("Deconfig: adding deconfigure record"); // convert to libphal required format. ATTR_PHYS_BIN_PATH_Type physBinPath; std::copy(entityPath.begin(), entityPath.end(), physBinPath); // libphal api to deconfigure the target openpower::phal::pdbg::deconfigureTgt(physBinPath, plid); } catch (const std::exception& e) { lg2::info( "Deconfig: Failed to create records, exception:({EXCEPTION})", "EXCEPTION", e); } } } void createServiceActions(const nlohmann::json& jsonCallouts, const DataInterfaceBase& dataIface, uint32_t plid) { // Create Guard records. createGuardRecords(jsonCallouts, plid, dataIface); // Create Deconfigure records. createDeconfigRecords(jsonCallouts, plid); } } // namespace phal } // namespace pels } // namespace openpower