Callout support for SBE when watchdog times out

This commit provides additional callout support for SBE when the
host does not respond within watchdog timeout interval during SBE
boot window.

Testing:
Steps used:
 1. obmcutil poweroff
 2. istep -s0
 3. systemctl start org.open_power.Dump.Manager.service
 4. systemctl start openpower-debug-collector-watchdog@0.service
 5. Check the journal log, and get the PEL id to print PEL info

PEL info:
    "Callout Section": {
        "Callout Count":        "2",
        "Callouts": [{
            "FRU Type":         "Maintenance Procedure Required",
            "Priority":         "Mandatory, replace all with this type
as a unit",
            "Procedure":        "BMC0002"
        }, {
            "FRU Type":         "Normal Hardware FRU",
            "Priority":         "Medium Priority",
            "Location Code":    "xxxxxxxxxxxxx",
            "Part Number":      "xxxxx",
            "CCIN":             "xxxx",
            "Serial Number":    "xxxxxxx"
        }
...
"User Data 2": {
    "Section Version": "1",
    "Sub-section type": "1",
    "Created by": "0x2000",
    "Data": [
        {
            "Priority": "H",
            "Procedure": "BMC0002"
        },
        {
            "Deconfigured": false,
            "Guarded": false,
            "LocationCode": "Ufcs-xx-xxx",
            "Priority": "M"
        }
    ]
}

Signed-off-by: Shantappa Teekappanavar <sbteeks@yahoo.com>
Change-Id: I5e182cb415a807d97c98812a6713905d39fdbc9a
diff --git a/watchdog/watchdog_main.cpp b/watchdog/watchdog_main.cpp
index 274867a..4fa4887 100644
--- a/watchdog/watchdog_main.cpp
+++ b/watchdog/watchdog_main.cpp
@@ -35,6 +35,48 @@
     transitionHost(HOST_STATE_QUIESCE_TGT);
 }
 
+/**
+ * @brief get SBE special callout information
+ *
+ * @details This function adds the special sbe callout in the user provided
+ * json callout list. includes BMC0002 procedure callout with high priority
+ * and processor callout with medium priority.
+ *
+ * @param[in] procTarget - pdbg processor target
+ * @param[out] jsonCalloutDataList - reference to json callout list
+ */
+static void getSBECallout(struct pdbg_target* procTarget,
+                          json& jsonCalloutDataList)
+{
+    using namespace openpower::phal::pdbg;
+    json jsonProcedCallout;
+
+    // Add procedure callout
+    jsonProcedCallout["Procedure"] = "BMC0002";
+    jsonProcedCallout["Priority"] = "H";
+    jsonCalloutDataList.emplace_back(jsonProcedCallout);
+    try
+    {
+        ATTR_LOCATION_CODE_Type locationCode;
+        // Initialize with default data.
+        memset(&locationCode, '\0', sizeof(locationCode));
+        // Get location code information
+        openpower::phal::pdbg::getLocationCode(procTarget, locationCode);
+        json jsonProcCallout;
+        jsonProcCallout["LocationCode"] = locationCode;
+        jsonProcCallout["Deconfigured"] = false;
+        jsonProcCallout["Guarded"] = false;
+        jsonProcCallout["Priority"] = "M";
+        jsonCalloutDataList.emplace_back(jsonProcCallout);
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(fmt::format("getLocationCode({}): Exception({})",
+                                    pdbg_target_path(procTarget), e.what())
+                            .c_str());
+    }
+}
+
 void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout)
 {
     using namespace openpower::phal;
@@ -93,6 +135,26 @@
                             static_cast<uint8_t>(0x01), sbeError.getFd()));
     }
 
+    std::unique_ptr<FFDCFile> ffdcFilePtr;
+    try
+    {
+        json jsonCalloutDataList;
+        jsonCalloutDataList = json::array();
+        getSBECallout(procTarget, jsonCalloutDataList);
+        ffdcFilePtr = std::make_unique<FFDCFile>(jsonCalloutDataList);
+        ffdc.push_back(std::make_tuple(
+            sdbusplus::xyz::openbmc_project::Logging::server::Create::
+                FFDCFormat::JSON,
+            static_cast<uint8_t>(0xCA), static_cast<uint8_t>(0x01),
+            ffdcFilePtr->getFileDescriptor()));
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+            fmt::format("Skipping SBE special callout due to Exception({})",
+                        e.what())
+                .c_str());
+    }
     auto pelId = createPel(event, additionalData, ffdc);
 
     if (dumpIsRequired)