PHAL: Log Informational error for PEL created during poweroff

1)Log informational PELS in case system state is transitioning to
power-off for IPL procedures/hardware access failures

2) Don't add callouts to PEL's created during transition to
power-off as the CEC will not be in expected state.

Tested: transition to poweroff
root@xxxbmc:/usr# peltool -lfh
{
    "0x50003BEB": {
        "SRC":                  "BD503001",
        "Message":              "Failure occurred during boot process",
        "PLID":                 "0x50003BEB",
        "CreatorID":            "BMC",
        "Subsystem":            "CEC Hardware",
        "Commit Time":          "05/23/2022 13:57:53",
        "Sev":                  "Informational Event",
        "CompID":               "0x3000"
    }
}

root@xxxbmc:~# peltool -i 0x50003be0
{
"Private Header": {
    "Section Version":          "1",
    "Sub-section type":         "0",
    "Created by":               "0x3000",
    "Created at":               "05/23/2022 13:48:12",
    "Committed at":             "05/23/2022 13:48:12",
    "Creator Subsystem":        "BMC",
    "CSSVER":                   "",
    "Platform Log Id":          "0x50003BE0",
    "Entry Id":                 "0x50003BE0",
    "BMC Event Log Id":         "510"
},
"User Header": {
    "Section Version":          "1",
    "Sub-section type":         "0",
    "Log Committed by":         "0x2000",
    "Subsystem":                "CEC Hardware",
    "Event Scope":              "Entire Platform",
    "Event Severity":           "Informational Event",
    "Event Type":               "Miscellaneous, Informational Only",
    "Action Flags": [
                                "Event not customer viewable",
                                "Report Externally"
    ],
    "Host Transmission":        "Not Sent",
    "HMC Transmission":         "Not Sent"
},

.
.
.
Tested: transition to running
root@ever8bmc:/tmp# peltool -i 0x50003CF9
{
"Private Header": {
    "Section Version":          "1",
    "Sub-section type":         "0",
    "Created by":               "0x3000",
},
"User Header": {
    "Section Version":          "1",
    "Sub-section type":         "0",
    "Log Committed by":         "0x2000",
    "Subsystem":                "CEC Hardware",
    "Event Scope":              "Entire Platform",
    "Event Severity":           "Unrecoverable Error",
},

"User Data 0": {
    "Created by": "0x2000",
    "BMCState": "Ready",
    "BootState": "Unspecified",
    "ChassisState": "On",
    "FW Version ID": "fw1020.00-57.7-2-gd86188a773",
    "HostState": "TransitioningToRunning",
    "Process Name": "/usr/bin/openpower-proc-control",
    "System IM": "50003000"
},

Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
Change-Id: I078d5cba2e0fb705bf424d2f8f3010f2cd2063bb
diff --git a/extensions/phal/create_pel.cpp b/extensions/phal/create_pel.cpp
index 8638d5c..75ee064 100644
--- a/extensions/phal/create_pel.cpp
+++ b/extensions/phal/create_pel.cpp
@@ -79,7 +79,7 @@
 }
 
 void createErrorPEL(const std::string& event, const json& calloutData,
-                    const FFDCData& ffdcData)
+                    const FFDCData& ffdcData, const Severity severity)
 {
     std::map<std::string, std::string> additionalData;
     auto bus = sdbusplus::bus::new_default();
@@ -111,8 +111,7 @@
                                 loggingInterface, "CreateWithFFDCFiles");
         auto level =
             sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
-                sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
-                    Error);
+                severity);
         method.append(event, level, additionalData, pelCalloutInfo);
         auto resp = bus.call(method);
     }
diff --git a/extensions/phal/create_pel.hpp b/extensions/phal/create_pel.hpp
index 674381b..ffd1315 100644
--- a/extensions/phal/create_pel.hpp
+++ b/extensions/phal/create_pel.hpp
@@ -29,9 +29,11 @@
  * @param[in] event - the event type
  * @param[in] calloutData - callout data to append to PEL
  * @param[in] ffdcData - failure data to append to PEL
+ * @param[in] severity - severity of the log default to Informational
  */
 void createErrorPEL(const std::string& event, const json& calloutData = {},
-                    const FFDCData& ffdcData = {});
+                    const FFDCData& ffdcData = {},
+                    const Severity severity = Severity::Informational);
 
 /**
  * @brief Create SBE boot error PEL and return id
diff --git a/extensions/phal/phal_error.cpp b/extensions/phal/phal_error.cpp
index a53ba77..8879964 100644
--- a/extensions/phal/phal_error.cpp
+++ b/extensions/phal/phal_error.cpp
@@ -7,6 +7,7 @@
 #include "dump_utils.hpp"
 #include "extensions/phal/common_utils.hpp"
 #include "phal_error.hpp"
+#include "util.hpp"
 
 #include <attributes_info.H>
 #include <fmt/format.h>
@@ -31,6 +32,7 @@
 {
 using namespace phosphor::logging;
 using namespace openpower::phal::exception;
+using Severity = sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level;
 
 /**
  * Used to pass buffer to pdbg callback api to get required target
@@ -321,7 +323,7 @@
         });
     openpower::pel::createErrorPEL(
         "org.open_power.PHAL.Error.NonFunctionalBootProc", jsonCalloutDataList,
-        pelAdditionalData);
+        pelAdditionalData, Severity::Error);
     // reset trace log and exit
     reset();
 }
@@ -387,6 +389,69 @@
     jsonCalloutDataList.emplace_back(jsonCalloutData);
 }
 
+/**
+ * @brief processPoweroffError
+ *
+ * Creates informational PEL for the PLAT/HWP error occured during poweroff
+ *
+ * Not adding callouts from FFDC as the hardware errors in the poweroff path
+ * should be non-visible.  so that we don't throw out extraneous callouts for
+ * power errors or because the CEC is just not in an expected state.
+ *
+ * @param[in] ffdc - FFDC data capturd by the HWP
+ * @param[in] ffdc_prefix - prefix string for logging the data.
+ */
+
+void processPoweroffError(FFDC* ffdc, const std::string& ffdc_prefix)
+{
+    try
+    {
+        log<level::INFO>(
+            fmt::format("processPoweroffError: Message[{}]", ffdc->message)
+                .c_str());
+
+        // To store phal trace and other additional data about ffdc.
+        FFDCData pelAdditionalData;
+
+        if (ffdc->ffdc_type == FFDC_TYPE_HWP)
+        {
+            std::string keyWithPrefix(ffdc_prefix + "RC");
+            // Adding hardware procedures return code details
+            pelAdditionalData.emplace_back(keyWithPrefix,
+                                           ffdc->hwp_errorinfo.rc);
+            keyWithPrefix = ffdc_prefix + "RC_DESC";
+            pelAdditionalData.emplace_back(keyWithPrefix,
+                                           ffdc->hwp_errorinfo.rc_desc);
+        }
+        else if ((ffdc->ffdc_type != FFDC_TYPE_NONE) &&
+                 (ffdc->ffdc_type != FFDC_TYPE_UNSUPPORTED))
+        {
+            log<level::ERR>(
+                fmt::format("Unsupported phal FFDC type to create PEL. "
+                            "MSG: {}",
+                            ffdc->message)
+                    .c_str());
+        }
+
+        // Adding collected phal logs into PEL additional data
+        for_each(traceLog.begin(), traceLog.end(),
+                 [&pelAdditionalData](
+                     std::pair<std::string, std::string>& ele) -> void {
+                     pelAdditionalData.emplace_back(ele.first, ele.second);
+                 });
+
+        openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot", {},
+                                       pelAdditionalData,
+                                       Severity::Informational);
+    }
+    catch (const std::exception& ex)
+    {
+        reset();
+        throw ex;
+    }
+    reset();
+}
+
 void processBootErrorHelper(FFDC* ffdc, const std::string& ffdc_prefix)
 {
     log<level::INFO>("processBootErrorHelper ");
@@ -622,7 +687,8 @@
                 return true;
             });
         openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot",
-                                       jsonCalloutDataList, pelAdditionalData);
+                                       jsonCalloutDataList, pelAdditionalData,
+                                       Severity::Error);
     }
     catch (const std::exception& ex)
     {
@@ -640,7 +706,14 @@
     FFDC* ffdc = reinterpret_cast<FFDC*>(errInfo.private_data);
     try
     {
-        processBootErrorHelper(ffdc, "PLAT_");
+        if (util::isHostPoweringOff())
+        {
+            processPoweroffError(ffdc, "PLAT_");
+        }
+        else
+        {
+            processBootErrorHelper(ffdc, "PLAT_");
+        }
     }
     catch (const std::exception& ex)
     {
@@ -661,12 +734,18 @@
         // return If no failure during hwp execution
         if (status)
             return;
-
         // Collecting ffdc details from phal
         FFDC ffdc;
         libekb_get_ffdc(ffdc);
 
-        processBootErrorHelper(&ffdc, "HWP_");
+        if (util::isHostPoweringOff())
+        {
+            processPoweroffError(&ffdc, "HWP_");
+        }
+        else
+        {
+            processBootErrorHelper(&ffdc, "HWP_");
+        }
     }
     catch (const std::exception& ex)
     {
@@ -716,7 +795,7 @@
         jsonCalloutDataList.emplace_back(jsonCalloutData);
         openpower::pel::createErrorPEL(
             "org.open_power.Processor.Error.SbeBootFailure",
-            jsonCalloutDataList);
+            jsonCalloutDataList, {}, Severity::Error);
         return;
     }
     // SBE error object.