openpower-pels: Create guard using libguard
Replace CreateWithEntityPath D-Bus method with guard library calls for
creating guard entries, as CreateWithEntityPath is not an approved dbus
method.
Tested and the guard record is created with the corresponding PEL id
```
before injecting the error
root@p10bmc:~# guard -l
No unresolved records to display
After injecting error, the guard is created using the PEL ID
root@p10bmc:~# guard -l
ID | ERROR | Type | Path
0x00000001 | 0x5000592b | unrecoverable | physical:sys-0/node-0/proc-0/eq-1/fc-0/core-0
root@p10bmc:~# peltool -l
{
"0x5000592B": {
"SRC": "BD13E510",
"Message": "Error Signature: 0x20DA0020 0x00000001 0x4D740407",
"PLID": "0x5000592B",
"CreatorID": "BMC",
"Subsystem": "Processor Unit (CPU)",
"Commit Time": "10/17/2024 09:54:22",
"Sev": "Unrecoverable Error",
"CompID": "bmc hw diags"
}
}
```
Change-Id: I7531bce403206beaa119aea0a621e6b47d28ffd0
Signed-off-by: deepakala-k <deepakala.karthikeyan@ibm.com>
diff --git a/extensions/openpower-pels/data_interface.cpp b/extensions/openpower-pels/data_interface.cpp
index 84645b7..599b63f 100644
--- a/extensions/openpower-pels/data_interface.cpp
+++ b/extensions/openpower-pels/data_interface.cpp
@@ -95,7 +95,6 @@
"xyz.openbmc_project.State.Decorator.OperationalStatus";
constexpr auto logSetting = "xyz.openbmc_project.Logging.Settings";
constexpr auto associationDef = "xyz.openbmc_project.Association.Definitions";
-constexpr auto hwIsolationCreate = "org.open_power.HardwareIsolation.Create";
constexpr auto hwIsolationEntry = "xyz.openbmc_project.HardwareIsolation.Entry";
constexpr auto association = "xyz.openbmc_project.Association";
constexpr auto biosConfigMgr = "xyz.openbmc_project.BIOSConfig.Manager";
@@ -235,6 +234,15 @@
{
#ifdef PEL_ENABLE_PHAL
initPHAL();
+ try
+ {
+ libguard::libguard_init(false);
+ }
+ catch (libguard::exception::GuardException& e)
+ {
+ lg2::error("Exception to init the guard {ERROR}", "ERROR",
+ e.what());
+ }
#endif
}
else
@@ -687,38 +695,20 @@
return ret;
}
+#ifdef PEL_ENABLE_PHAL
void DataInterface::createGuardRecord(const std::vector<uint8_t>& binPath,
- const std::string& type,
- const std::string& logPath) const
+ GardType eGardType, uint32_t plid) const
{
try
{
- auto method = _bus.new_method_call(
- service_name::hwIsolation, object_path::hwIsolation,
- interface::hwIsolationCreate, "CreateWithEntityPath");
- method.append(binPath, type, sdbusplus::message::object_path(logPath));
- // Note: hw isolation "CreateWithEntityPath" got dependency on logging
- // api's. Making d-bus call no reply type to avoid cyclic dependency.
- // Added minimal timeout to catch initial failures.
- // Need to revisit this design later to avoid cyclic dependency.
- constexpr auto hwIsolationTimeout = 100000; // in micro seconds
- _bus.call_noreply(method, hwIsolationTimeout);
+ libguard::create(binPath, plid, eGardType);
}
-
- catch (const sdbusplus::exception_t& e)
+ catch (libguard::exception::GuardException& e)
{
- std::string errName = e.name();
- // SD_BUS_ERROR_TIMEOUT error is expected, due to PEL api dependency
- // mentioned above. Ignoring the error.
- if (errName != SD_BUS_ERROR_TIMEOUT)
- {
- lg2::error("GUARD D-Bus call exception. Path={PATH}, "
- "interface = {IFACE}, exception = {ERROR}",
- "PATH", object_path::hwIsolation, "IFACE",
- interface::hwIsolationCreate, "ERROR", e);
- }
+ lg2::error("Exception to create the guard {ERROR}", "ERROR", e.what());
}
}
+#endif
void DataInterface::createProgressSRC(
const uint64_t& priSRC, const std::vector<uint8_t>& srcStruct) const
diff --git a/extensions/openpower-pels/data_interface.hpp b/extensions/openpower-pels/data_interface.hpp
index 93a0e47..bdf93c1 100644
--- a/extensions/openpower-pels/data_interface.hpp
+++ b/extensions/openpower-pels/data_interface.hpp
@@ -3,6 +3,11 @@
#include "dbus_types.hpp"
#include "dbus_watcher.hpp"
+#ifdef PEL_ENABLE_PHAL
+#include <libguard/guard_interface.hpp>
+#include <libguard/include/guard_record.hpp>
+#endif
+
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
@@ -12,6 +17,11 @@
#include <fstream>
#include <unordered_map>
+#ifdef PEL_ENABLE_PHAL
+using GardType = openpower::guard::GardType;
+namespace libguard = openpower::guard;
+#endif
+
namespace openpower
{
namespace pels
@@ -443,16 +453,17 @@
static std::pair<std::string, std::string>
extractConnectorFromLocCode(const std::string& locationCode);
+#ifdef PEL_ENABLE_PHAL
/**
* @brief Create guard record
*
* @param[in] binPath: phal devtree binary path used as key
- * @param[in] type: Guard type
- * @param[in] logPath: error log entry object path
+ * @param[in] eGardType: Guard type enum value
+ * @param[in] plid: Pel ID
*/
virtual void createGuardRecord(const std::vector<uint8_t>& binPath,
- const std::string& type,
- const std::string& logPath) const = 0;
+ GardType eGardType, uint32_t plid) const = 0;
+#endif
/**
* @brief Create Progress SRC property on the boot progress
@@ -856,16 +867,17 @@
*/
bool getQuiesceOnError() const override;
+#ifdef PEL_ENABLE_PHAL
/**
* @brief Create guard record
*
* @param[in] binPath: phal devtree binary path used as key
- * @param[in] type: Guard type
- * @param[in] logPath: error log entry object path
+ * @param[in] eGardType: Guard type enum value
+ * @param[in] plid: pel id to be associated to the guard record
*/
void createGuardRecord(const std::vector<uint8_t>& binPath,
- const std::string& type,
- const std::string& logPath) const override;
+ GardType eGardType, uint32_t plid) const override;
+#endif
/**
* @brief Create Progress SRC property on the boot progress
diff --git a/extensions/openpower-pels/meson.build b/extensions/openpower-pels/meson.build
index db57568..cff4e68 100644
--- a/extensions/openpower-pels/meson.build
+++ b/extensions/openpower-pels/meson.build
@@ -32,6 +32,7 @@
cpp.find_library('pdbg'),
cpp.find_library('ekb'),
cpp.find_library('phal'),
+ cpp.find_library('libguard'),
]
extra_args += [
'-DPEL_ENABLE_PHAL',
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 8b635e5..9f09a01 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -34,6 +34,11 @@
#ifdef PEL_ENABLE_PHAL
#include "phal_service_actions.hpp"
#include "sbe_ffdc_handler.hpp"
+
+#include <libguard/guard_interface.hpp>
+#include <libguard/include/guard_record.hpp>
+
+namespace libguard = openpower::guard;
#endif
#include <sys/stat.h>
@@ -175,8 +180,7 @@
#ifdef PEL_ENABLE_PHAL
auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID);
- openpower::pels::phal::createServiceActions(callouts, path, dataIface,
- plid());
+ openpower::pels::phal::createServiceActions(callouts, dataIface, plid());
#endif
// Store in the PEL any important debug data created while
diff --git a/extensions/openpower-pels/phal_service_actions.cpp b/extensions/openpower-pels/phal_service_actions.cpp
index f40821e..f0a60e9 100644
--- a/extensions/openpower-pels/phal_service_actions.cpp
+++ b/extensions/openpower-pels/phal_service_actions.cpp
@@ -3,10 +3,14 @@
#include <attributes_info.H>
#include <libphal.H>
+#include <libguard/guard_interface.hpp>
+#include <libguard/include/guard_record.hpp>
#include <phosphor-logging/lg2.hpp>
#include <format>
+using GardType = openpower::guard::GardType;
+
namespace openpower
{
namespace pels
@@ -15,34 +19,32 @@
{
/**
- * @brief Helper function to get EntrySeverity based on
- * the given GardType
+ * @brief Helper function to get gard type based on
+ * the given GardType string
*
- * @param[in] guardType openpower gard type
+ * @param[in] guardTypeStr guard type enum value as a string
*
- * @return EntrySeverity on success
+ * @return GardType on success
* Empty optional on failure
*/
-std::optional<EntrySeverity> getEntrySeverityType(const std::string& guardType)
+std::optional<GardType> getGardType(const std::string& guardTypeStr)
{
- if ((guardType == "GARD_Unrecoverable") || (guardType == "GARD_Fatal"))
+ const std::unordered_map<std::string, GardType> 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 EntrySeverity::Critical;
- }
- else if (guardType == "GARD_User_Manual")
- {
- return EntrySeverity::Manual;
- }
- else if (guardType == "GARD_Predictive")
- {
- return EntrySeverity::Warning;
+ return it->second;
}
else
{
- lg2::error(
- "GUARD: Unsupported GuardType [{GUARD_TYPE}] was given to get the "
- "hardware isolation entry severity type",
- "GUARD_TYPE", guardType);
+ lg2::error("Invalid GardType ({GUARDTYPE})", "GUARDTYPE", guardTypeStr);
}
return std::nullopt;
}
@@ -57,11 +59,10 @@
* "Guarded": boolean, true to create gurad records.
*
* @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
- * @param[in] path - The BMC error log object path
+ * @param[in] plid - The PEL ID to be associated with the guard
* @param[in] dataIface - The DataInterface object
*/
-void createGuardRecords(const nlohmann::json& jsonCallouts,
- const std::string& path,
+void createGuardRecords(const nlohmann::json& jsonCallouts, uint32_t plid,
const DataInterfaceBase& dataIface)
{
if (jsonCallouts.empty())
@@ -100,33 +101,28 @@
auto entityPath = _callout.at("EntityPath").get<EntityPath>();
std::stringstream ss;
- for (uint32_t a = 0; a < sizeof(ATTR_PHYS_BIN_PATH_Type); a++)
- {
- ss << " 0x" << std::hex << static_cast<int>(entityPath[a]);
- }
+ 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
- auto severity = EntrySeverity::Warning;
+ std::string guardTypeStr = "GARD_Predictive";
if (!_callout.contains("GuardType"))
{
- lg2::error("GUARD: doesn't have Severity, setting to warning");
+ lg2::error(
+ "GUARD: doesn't have Severity, setting to GARD_Predictive");
}
else
{
- auto guardType = _callout.at("GuardType").get<std::string>();
- // convert GuardType to severity type.
- auto sType = getEntrySeverityType(guardType);
- if (sType.has_value())
- {
- severity = sType.value();
- }
+ guardTypeStr = _callout.at("GuardType").get<std::string>();
}
- // Create guard record
- auto type = sdbusplus::xyz::openbmc_project::HardwareIsolation::
- server::convertForMessage(severity);
- dataIface.createGuardRecord(entityPath, type, path);
+
+ GardType eGuardType =
+ getGardType(guardTypeStr).value_or(GardType::GARD_Predictive);
+ dataIface.createGuardRecord(entityPath, eGuardType, plid);
}
catch (const std::exception& e)
{
@@ -149,8 +145,7 @@
* @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
* @param[in] plid - PLID value
*/
-void createDeconfigRecords(const nlohmann::json& jsonCallouts,
- const uint32_t plid)
+void createDeconfigRecords(const nlohmann::json& jsonCallouts, uint32_t plid)
{
using namespace openpower::phal::pdbg;
@@ -204,12 +199,10 @@
}
void createServiceActions(const nlohmann::json& jsonCallouts,
- const std::string& path,
- const DataInterfaceBase& dataIface,
- const uint32_t plid)
+ const DataInterfaceBase& dataIface, uint32_t plid)
{
// Create Guard records.
- createGuardRecords(jsonCallouts, path, dataIface);
+ createGuardRecords(jsonCallouts, plid, dataIface);
// Create Deconfigure records.
createDeconfigRecords(jsonCallouts, plid);
}
diff --git a/extensions/openpower-pels/phal_service_actions.hpp b/extensions/openpower-pels/phal_service_actions.hpp
index 8032663..0dcd1ff 100644
--- a/extensions/openpower-pels/phal_service_actions.hpp
+++ b/extensions/openpower-pels/phal_service_actions.hpp
@@ -12,21 +12,15 @@
namespace phal
{
-using EntrySeverity =
- sdbusplus::server::xyz::openbmc_project::hardware_isolation::Entry::Type;
-
/**
* @brief Helper function to create service actions in the PEL
*
* @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
- * @param[in] path - The BMC error log object path
* @param[in] dataIface - The DataInterface object
* @param[in] plid - the PLID
*/
void createServiceActions(const nlohmann::json& jsonCallouts,
- const std::string& path,
- const DataInterfaceBase& dataIface,
- const uint32_t plid);
+ const DataInterfaceBase& dataIface, uint32_t plid);
} // namespace phal
} // namespace pels
} // namespace openpower