PEL: Added phal specific service action support
This commits enables the basic infrastructure to add service
actions(guard/deconfigure) supports for "phal" feature enabled
systems. Also enabled "guard" related service , which includes
creating guard D-Bus object using hardware isolation D-Bus api's
To enable this support, PEL users has to include the array of
JSON callouts, which includes the below required informations.
"EntityPath": entity path of the hardware from the PHAL device tree.
"GuardType": Guard type string defined libekb_p10.
"Guarded": boolean, true to create guard records.
Tested: created guard records and verified
root@xxxx:~# guard -l
ID | ERROR | Type | Path
00000001 | 50000684 | fatal | physical:sys-0/node-0/proc-0
00000002 | 50000685 | fatal | physical:sys-0/node-0/proc-1
00000003 | 50000686 | fatal | physical:sys-0/node-0/proc-2
00000004 | 50000687 | fatal | physical:sys-0/node-0/proc-3
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
Change-Id: Ibc57ae0363cd5fb9facd2ed7049a70806a5b891e
diff --git a/extensions/openpower-pels/meson.build b/extensions/openpower-pels/meson.build
index b78ccf0..4659945 100644
--- a/extensions/openpower-pels/meson.build
+++ b/extensions/openpower-pels/meson.build
@@ -39,6 +39,7 @@
extra_sources += [
'sbe_ffdc_handler.cpp',
'fapi_data_process.cpp',
+ 'phal_service_actions.cpp',
]
extra_dependencies += [
dependency('libdt-api'),
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 8f397cd..30fbf51 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "config.h"
+
#include "pel.hpp"
#include "bcd_time.hpp"
@@ -29,6 +31,7 @@
#include "user_data_formats.hpp"
#ifdef PEL_ENABLE_PHAL
+#include "phal_service_actions.hpp"
#include "sbe_ffdc_handler.hpp"
#endif
@@ -154,6 +157,11 @@
addUserDataSection(std::move(ud));
}
+#ifdef PEL_ENABLE_PHAL
+ auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID);
+ openpower::pels::phal::createServiceActions(callouts, path, dataIface);
+#endif
+
// Store in the PEL any important debug data created while
// building the PEL sections.
if (!debugData.empty())
diff --git a/extensions/openpower-pels/phal_service_actions.cpp b/extensions/openpower-pels/phal_service_actions.cpp
new file mode 100644
index 0000000..a534ddf
--- /dev/null
+++ b/extensions/openpower-pels/phal_service_actions.cpp
@@ -0,0 +1,151 @@
+#include "phal_service_actions.hpp"
+
+#include <attributes_info.H>
+#include <fmt/format.h>
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+namespace phal
+{
+using namespace phosphor::logging;
+
+/**
+ * @brief Helper function to get EntrySeverity based on
+ * the given GardType
+ *
+ * @param[in] guardType openpower gard type
+ *
+ * @return EntrySeverity on success
+ * Empty optional on failure
+ */
+std::optional<EntrySeverity> getEntrySeverityType(const std::string& guardType)
+{
+ if ((guardType == "GARD_Unrecoverable") || (guardType == "GARD_Fatal"))
+ {
+ return EntrySeverity::Critical;
+ }
+ else if (guardType == "GARD_User_Manual")
+ {
+ return EntrySeverity::Manual;
+ }
+ else if (guardType == "GARD_Predictive")
+ {
+ return EntrySeverity::Warning;
+ }
+ else
+ {
+ log<level::ERR>(
+ fmt::format("GUARD: Unsupported GardType [{}] was given ",
+ "to get the hardware isolation entry severity type",
+ guardType.c_str())
+ .c_str());
+ }
+ 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] path - The BMC error log object path
+ * @param[in] dataIface - The DataInterface object
+ */
+void createGuardRecords(const nlohmann::json& jsonCallouts,
+ const std::string& path,
+ const DataInterfaceBase& dataIface)
+{
+ if (jsonCallouts.empty())
+ {
+ return;
+ }
+
+ if (!jsonCallouts.is_array())
+ {
+ log<level::ERR>("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<bool>())
+ {
+ continue;
+ }
+ // Get Entity path required for guard D-bus method
+ // "CreateWithEntityPath"
+ if (!_callout.contains("EntityPath"))
+ {
+ log<level::ERR>(
+ "GUARD: Callout data, missing EntityPath information");
+ continue;
+ }
+ using EntityPath = std::vector<uint8_t>;
+
+ 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::string s = ss.str();
+ log<level::INFO>(fmt::format("GUARD :({})", s).c_str());
+
+ // Get Guard type
+ auto severity = EntrySeverity::Warning;
+ if (!_callout.contains("GuardType"))
+ {
+ log<level::ERR>(
+ "GUARD: doesn't have Severity, setting to warning");
+ }
+ 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();
+ }
+ }
+ // Create guard record
+ auto type = sdbusplus::xyz::openbmc_project::HardwareIsolation::
+ server::convertForMessage(severity);
+ dataIface.createGuardRecord(entityPath, type, path);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::INFO>(
+ fmt::format("GUARD: Failed entry creation exception:({})",
+ e.what())
+ .c_str());
+ }
+ }
+}
+
+void createServiceActions(const nlohmann::json& jsonCallouts,
+ const std::string& path,
+ const DataInterfaceBase& dataIface)
+{
+ // Create Guard records.
+ createGuardRecords(jsonCallouts, path, dataIface);
+}
+} // namespace phal
+} // namespace pels
+} // namespace openpower
diff --git a/extensions/openpower-pels/phal_service_actions.hpp b/extensions/openpower-pels/phal_service_actions.hpp
new file mode 100644
index 0000000..84a700e
--- /dev/null
+++ b/extensions/openpower-pels/phal_service_actions.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "data_interface.hpp"
+
+#include <nlohmann/json.hpp>
+#include <xyz/openbmc_project/HardwareIsolation/Entry/server.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+namespace phal
+{
+
+using EntrySeverity =
+ sdbusplus::xyz::openbmc_project::HardwareIsolation::server::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
+ */
+void createServiceActions(const nlohmann::json& jsonCallouts,
+ const std::string& path,
+ const DataInterfaceBase& dataIface);
+} // namespace phal
+} // namespace pels
+} // namespace openpower