PEL: Add SBE FFDC process function

 Helper function to process SBE FFDC packet.
This function call libekb function to process the
FFDC packet and convert in to known format for PEL
specific file creation. This function also creates
json callout file and text type file, which includes
the addition debug data included in SBE FFDC packet.

Tested: Manually verified,

Sample test results with all the cores de-configured
system boot usecase.

"User Data 3": {
    "Section Version": "1",
    "Sub-section type": "1",
    "Created by": "0x2000",
    "Data": [
        {
            "Deconfigured": false,
            "Guarded": false,
            "LocationCode": "Ufcs-P0-C24",
            "MRUs": [
                {
                    "ID": 65536,
                    "Priority": "H"
                }
            ],
            "Priority": "H"
        }
    ]
},
"User Data 4": {
    "Section Version": "1",
    "Sub-section type": "3",
    "Created by": "0x2000",
    "Data": [
        "HWP_RC = RC_SBE_SELECT_EX_INSUFFICIENT_ACTIVE_CORES_ERROR",
        "HWP_RC_DESC = The requested active cores were
                       not able to be configured.",
        "HWP_FFDC_CHIP = 6b3a7570 306e3a30 3a30733a 00323070
             00000000 00000000 00000000 00000000 00000000
             00000000 00000000 00000000 00000000 00000000
             00000000 00000000",
        "HWP_FFDC_CORE_CONFIG = 00000000",
        "HWP_FFDC_ATTR_ACTIVE_CORES_NUM = 02",
        "HWP_FFDC_ACTIVE_CORES_NUM = 00000000",
        "HWP_FFDC_ACTIVE_CORES_VEC = 00000000",
        "HWP_CDG_TGT_01_LOC_CODE = Ufcs-P0-C24",
        "HWP_CDG_TGT_01_PHYS_PATH = physical:sys-0/node-0/proc-2",
        "HWP_CDG_TGT_01_CO_REQ = true",
        "HWP_CDG_TGT_01_CO_PRIORITY = HIGH",
        "HWP_CDG_TGT_01_DECONF_REQ = false",
        "HWP_CDG_TGT_01_GUARD_REQ = false",
        "HWP_CDG_TGT_01_GUARD_TYPE = GARD_Fatal"
    ]
}

Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
Change-Id: Iac2689c3608ddb0090a1c17753bbf9be96d12939
diff --git a/extensions/openpower-pels/sbe_ffdc_handler.cpp b/extensions/openpower-pels/sbe_ffdc_handler.cpp
index 55e3cbe..a36b6cf 100644
--- a/extensions/openpower-pels/sbe_ffdc_handler.cpp
+++ b/extensions/openpower-pels/sbe_ffdc_handler.cpp
@@ -16,6 +16,10 @@
 
 #include "sbe_ffdc_handler.hpp"
 
+#include "fapi_data_process.hpp"
+#include "pel.hpp"
+#include "temporary_file.hpp"
+
 #include <fmt/format.h>
 
 #include <phosphor-logging/log.hpp>
@@ -69,6 +73,67 @@
     }
 }
 
+void SbeFFDC::process(const sbeFfdcPacketType& ffdcPkt)
+{
+    using json = nlohmann::json;
+
+    // formated FFDC data structure after FFDC packet processing
+    FFDC ffdc;
+
+    try
+    {
+        // libekb provided wrapper function to convert SBE FFDC
+        // in to known ffdc structure.
+        libekb_get_sbe_ffdc(ffdc, ffdcPkt, procPos);
+    }
+    catch (...)
+    {
+        log<level::ERR>("libekb_get_sbe_ffdc failed, skipping ffdc processing");
+        return;
+    }
+
+    // To store callouts details in json format as per pel expectation.
+    json pelJSONFmtCalloutDataList;
+    pelJSONFmtCalloutDataList = json::array();
+
+    // To store other user data from FFDC.
+    openpower::pels::phal::FFDCData ffdcUserData;
+
+    // Get FFDC and required info to include in PEL
+    openpower::pels::phal::convertFAPItoPELformat(
+        ffdc, pelJSONFmtCalloutDataList, ffdcUserData);
+
+    // Get callout information and sore in to file.
+    auto calloutData = pelJSONFmtCalloutDataList.dump();
+    util::TemporaryFile ffdcFile(calloutData.c_str(), calloutData.size());
+
+    // Create json callout type pel FFDC file structre.
+    PelFFDCfile pf;
+    pf.format = openpower::pels::UserDataFormat::json;
+    pf.subType = openpower::pels::jsonCalloutSubtype;
+    pf.version = 0x01;
+    pf.fd = ffdcFile.getFd();
+    ffdcFiles.push_back(pf);
+
+    // save the file path to delete the file after usage.
+    paths.push_back(ffdcFile.getPath());
+
+    // Format ffdc user data and create new file.
+    std::string data;
+    for (auto& d : ffdcUserData)
+    {
+        data += d.first + " = " + d.second + "\n";
+    }
+    util::TemporaryFile pelDataFile(data.c_str(), data.size());
+    PelFFDCfile pdf;
+    pdf.format = openpower::pels::UserDataFormat::text;
+    pdf.version = 0x01;
+    pdf.fd = pelDataFile.getFd();
+    ffdcFiles.push_back(pdf);
+
+    paths.push_back(pelDataFile.getPath());
+}
+
 } // namespace sbe
 } // namespace pels
 } // namespace openpower