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/entry_points.cpp b/extensions/openpower-pels/entry_points.cpp
index 1b14879..3a990f8 100644
--- a/extensions/openpower-pels/entry_points.cpp
+++ b/extensions/openpower-pels/entry_points.cpp
@@ -23,6 +23,7 @@
 #include <phosphor-logging/log.hpp>
 
 #ifdef SBE_FFDC_SUPPORTED
+#include <libekb.H>
 #include <libpdbg.h>
 #endif
 
@@ -64,6 +65,12 @@
         log<level::ERR>("pdbg_targets_init failed");
         throw std::runtime_error("pdbg target initialization failed");
     }
+
+    if (libekb_init())
+    {
+        log<level::ERR>("libekb_init failed");
+        throw std::runtime_error("libekb initialization failed");
+    }
 #endif
 }
 
diff --git a/extensions/openpower-pels/meson.build b/extensions/openpower-pels/meson.build
index bc58427..1ef833e 100644
--- a/extensions/openpower-pels/meson.build
+++ b/extensions/openpower-pels/meson.build
@@ -42,6 +42,7 @@
     extra_dependencies += [
         dependency('libdt-api'),
         cpp.find_library('pdbg'),
+        cpp.find_library('ekb'),
     ]
     add_project_arguments('-DSBE_FFDC_SUPPORTED', language : ['c','cpp'])
 endif
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
diff --git a/extensions/openpower-pels/sbe_ffdc_handler.hpp b/extensions/openpower-pels/sbe_ffdc_handler.hpp
index efdaa03..f245947 100644
--- a/extensions/openpower-pels/sbe_ffdc_handler.hpp
+++ b/extensions/openpower-pels/sbe_ffdc_handler.hpp
@@ -3,6 +3,8 @@
 #include "additional_data.hpp"
 #include "pel.hpp"
 
+#include <libekb.H>
+
 namespace openpower
 {
 namespace pels
@@ -87,6 +89,21 @@
 
   private:
     /**
+     * @brief 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.
+     *
+     * @param ffdcPkt  SBE FFDC packet
+     *
+     * Any failure during the process stops the function
+     * execution to support the raw SBE FFDC data based
+     * PEL creation.
+     */
+    void process(const sbeFfdcPacketType& ffdcPkt);
+    /**
      * @brief  Temporary files path information created as part of FFDC
      *         processing.
      */