diff --git a/phalerror/create_pel.cpp b/phalerror/create_pel.cpp
index 4f65b48..ac1fff7 100644
--- a/phalerror/create_pel.cpp
+++ b/phalerror/create_pel.cpp
@@ -1,203 +1,203 @@
-#include "create_pel.hpp"
-
-#include <fcntl.h>
-#include <fmt/format.h>
-#include <libekb.H>
-#include <unistd.h>
-
-#include <cerrno>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <map>
-#include <phosphor-logging/elog.hpp>
-#include <stdexcept>
-#include <string>
-#include <tuple>
-#include <vector>
-#include <xyz/openbmc_project/Logging/Create/server.hpp>
-#include <xyz/openbmc_project/Logging/Entry/server.hpp>
-
-namespace openpower
-{
-using namespace phosphor::logging;
-
-namespace util
-{
-std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
-                       const std::string& interface)
-{
-    constexpr auto mapperBusBame = "xyz.openbmc_project.ObjectMapper";
-    constexpr auto mapperObjectPath = "/xyz/openbmc_project/object_mapper";
-    constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";
-    std::vector<std::pair<std::string, std::vector<std::string>>> response;
-    auto method = bus.new_method_call(mapperBusBame, mapperObjectPath,
-                                      mapperInterface, "GetObject");
-    method.append(objectPath, std::vector<std::string>({interface}));
-    try
-    {
-        auto reply = bus.call(method);
-        reply.read(response);
-    }
-    catch (const sdbusplus::exception::SdBusError& e)
-    {
-        log<level::ERR>("D-Bus call exception",
-                        entry("OBJPATH=%s", mapperObjectPath),
-                        entry("INTERFACE=%s", mapperInterface),
-                        entry("EXCEPTION=%s", e.what()));
-
-        throw std::runtime_error("Service name is not found");
-    }
-
-    if (response.empty())
-    {
-        throw std::runtime_error("Service name response is empty");
-    }
-    return response.begin()->first;
-}
-} // namespace util
-
-namespace pel
-{
-void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData)
-{
-    constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
-    constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create";
-
-    std::map<std::string, std::string> additionalData;
-    auto bus = sdbusplus::bus::new_default();
-    additionalData.emplace("_PID", std::to_string(getpid()));
-    for (auto& data : ffdcData)
-    {
-        additionalData.emplace(data);
-    }
-
-    try
-    {
-        FFDCFile ffdcFile(calloutData);
-
-        std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
-                                   server::Create::FFDCFormat,
-                               uint8_t, uint8_t, sdbusplus::message::unix_fd>>
-            pelCalloutInfo;
-
-        pelCalloutInfo.push_back(
-            std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
-                                Create::FFDCFormat::JSON,
-                            static_cast<uint8_t>(0xCA),
-                            static_cast<uint8_t>(0x01), ffdcFile.getFileFD()));
-
-        static constexpr auto bootErrorMessage =
-            "org.open_power.PHAL.Error.Boot";
-        std::string service =
-            util::getService(bus, loggingObjectPath, loggingInterface);
-        auto method =
-            bus.new_method_call(service.c_str(), loggingObjectPath,
-                                loggingInterface, "CreateWithFFDCFiles");
-        auto level =
-            sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
-                sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
-                    Error);
-        method.append(bootErrorMessage, level, additionalData, pelCalloutInfo);
-        auto resp = bus.call(method);
-    }
-    catch (const sdbusplus::exception::SdBusError& e)
-    {
-        log<level::ERR>("D-Bus call exception",
-                        entry("OBJPATH=%s", loggingObjectPath),
-                        entry("INTERFACE=%s", loggingInterface),
-                        entry("EXCEPTION=%s", e.what()));
-
-        throw std::runtime_error(
-            "Error in invoking D-Bus logging create interface");
-    }
-    catch (std::exception& e)
-    {
-        throw e;
-    }
-}
-
-FFDCFile::FFDCFile(const json& pHALCalloutData) :
-    calloutData(pHALCalloutData.dump()),
-    calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
-{
-    prepareFFDCFile();
-}
-
-FFDCFile::~FFDCFile()
-{
-    removeCalloutFile();
-}
-
-int FFDCFile::getFileFD() const
-{
-    return fileFD;
-}
-
-void FFDCFile::prepareFFDCFile()
-{
-    createCalloutFile();
-    writeCalloutData();
-    setCalloutFileSeekPos();
-}
-
-void FFDCFile::createCalloutFile()
-{
-    fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
-
-    if (fileFD == -1)
-    {
-        log<level::ERR>(fmt::format("Failed to create phalPELCallouts "
-                                    "file({}), errorno({}) and errormsg({})",
-                                    calloutFile, errno, strerror(errno))
-                            .c_str());
-        throw std::runtime_error("Failed to create phalPELCallouts file");
-    }
-}
-
-void FFDCFile::writeCalloutData()
-{
-    ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
-
-    if (rc == -1)
-    {
-        log<level::ERR>(fmt::format("Failed to write phaPELCallout info "
-                                    "in file({}), errorno({}), errormsg({})",
-                                    calloutFile, errno, strerror(errno))
-                            .c_str());
-        throw std::runtime_error("Failed to write phalPELCallouts info");
-    }
-    else if (rc != static_cast<ssize_t>(calloutData.size()))
-    {
-        log<level::WARNING>(fmt::format("Could not write all phal callout "
-                                        "info in file({}), written byte({}) "
-                                        "and total byte({})",
-                                        calloutFile, rc, calloutData.size())
-                                .c_str());
-    }
-}
-
-void FFDCFile::setCalloutFileSeekPos()
-{
-    int rc = lseek(fileFD, 0, SEEK_SET);
-
-    if (rc == -1)
-    {
-        log<level::ERR>(fmt::format("Failed to set SEEK_SET for "
-                                    "phalPELCallouts in file({}), errorno({}) "
-                                    "and errormsg({})",
-                                    calloutFile, errno, strerror(errno))
-                            .c_str());
-        throw std::runtime_error(
-            "Failed to set SEEK_SET for phalPELCallouts file");
-    }
-}
-
-void FFDCFile::removeCalloutFile()
-{
-    close(fileFD);
-    std::remove(calloutFile.c_str());
-}
-
-} // namespace pel
-} // namespace openpower
+#include "create_pel.hpp"
+
+#include <fcntl.h>
+#include <fmt/format.h>
+#include <libekb.H>
+#include <unistd.h>
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <phosphor-logging/elog.hpp>
+#include <stdexcept>
+#include <string>
+#include <tuple>
+#include <vector>
+#include <xyz/openbmc_project/Logging/Create/server.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
+namespace openpower
+{
+using namespace phosphor::logging;
+
+namespace util
+{
+std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
+                       const std::string& interface)
+{
+    constexpr auto mapperBusBame = "xyz.openbmc_project.ObjectMapper";
+    constexpr auto mapperObjectPath = "/xyz/openbmc_project/object_mapper";
+    constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";
+    std::vector<std::pair<std::string, std::vector<std::string>>> response;
+    auto method = bus.new_method_call(mapperBusBame, mapperObjectPath,
+                                      mapperInterface, "GetObject");
+    method.append(objectPath, std::vector<std::string>({interface}));
+    try
+    {
+        auto reply = bus.call(method);
+        reply.read(response);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("D-Bus call exception",
+                        entry("OBJPATH=%s", mapperObjectPath),
+                        entry("INTERFACE=%s", mapperInterface),
+                        entry("EXCEPTION=%s", e.what()));
+
+        throw std::runtime_error("Service name is not found");
+    }
+
+    if (response.empty())
+    {
+        throw std::runtime_error("Service name response is empty");
+    }
+    return response.begin()->first;
+}
+} // namespace util
+
+namespace pel
+{
+void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData)
+{
+    constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
+    constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create";
+
+    std::map<std::string, std::string> additionalData;
+    auto bus = sdbusplus::bus::new_default();
+    additionalData.emplace("_PID", std::to_string(getpid()));
+    for (auto& data : ffdcData)
+    {
+        additionalData.emplace(data);
+    }
+
+    try
+    {
+        FFDCFile ffdcFile(calloutData);
+
+        std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
+                                   server::Create::FFDCFormat,
+                               uint8_t, uint8_t, sdbusplus::message::unix_fd>>
+            pelCalloutInfo;
+
+        pelCalloutInfo.push_back(
+            std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
+                                Create::FFDCFormat::JSON,
+                            static_cast<uint8_t>(0xCA),
+                            static_cast<uint8_t>(0x01), ffdcFile.getFileFD()));
+
+        static constexpr auto bootErrorMessage =
+            "org.open_power.PHAL.Error.Boot";
+        std::string service =
+            util::getService(bus, loggingObjectPath, loggingInterface);
+        auto method =
+            bus.new_method_call(service.c_str(), loggingObjectPath,
+                                loggingInterface, "CreateWithFFDCFiles");
+        auto level =
+            sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
+                sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
+                    Error);
+        method.append(bootErrorMessage, level, additionalData, pelCalloutInfo);
+        auto resp = bus.call(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("D-Bus call exception",
+                        entry("OBJPATH=%s", loggingObjectPath),
+                        entry("INTERFACE=%s", loggingInterface),
+                        entry("EXCEPTION=%s", e.what()));
+
+        throw std::runtime_error(
+            "Error in invoking D-Bus logging create interface");
+    }
+    catch (std::exception& e)
+    {
+        throw e;
+    }
+}
+
+FFDCFile::FFDCFile(const json& pHALCalloutData) :
+    calloutData(pHALCalloutData.dump()),
+    calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
+{
+    prepareFFDCFile();
+}
+
+FFDCFile::~FFDCFile()
+{
+    removeCalloutFile();
+}
+
+int FFDCFile::getFileFD() const
+{
+    return fileFD;
+}
+
+void FFDCFile::prepareFFDCFile()
+{
+    createCalloutFile();
+    writeCalloutData();
+    setCalloutFileSeekPos();
+}
+
+void FFDCFile::createCalloutFile()
+{
+    fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
+
+    if (fileFD == -1)
+    {
+        log<level::ERR>(fmt::format("Failed to create phalPELCallouts "
+                                    "file({}), errorno({}) and errormsg({})",
+                                    calloutFile, errno, strerror(errno))
+                            .c_str());
+        throw std::runtime_error("Failed to create phalPELCallouts file");
+    }
+}
+
+void FFDCFile::writeCalloutData()
+{
+    ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
+
+    if (rc == -1)
+    {
+        log<level::ERR>(fmt::format("Failed to write phaPELCallout info "
+                                    "in file({}), errorno({}), errormsg({})",
+                                    calloutFile, errno, strerror(errno))
+                            .c_str());
+        throw std::runtime_error("Failed to write phalPELCallouts info");
+    }
+    else if (rc != static_cast<ssize_t>(calloutData.size()))
+    {
+        log<level::WARNING>(fmt::format("Could not write all phal callout "
+                                        "info in file({}), written byte({}) "
+                                        "and total byte({})",
+                                        calloutFile, rc, calloutData.size())
+                                .c_str());
+    }
+}
+
+void FFDCFile::setCalloutFileSeekPos()
+{
+    int rc = lseek(fileFD, 0, SEEK_SET);
+
+    if (rc == -1)
+    {
+        log<level::ERR>(fmt::format("Failed to set SEEK_SET for "
+                                    "phalPELCallouts in file({}), errorno({}) "
+                                    "and errormsg({})",
+                                    calloutFile, errno, strerror(errno))
+                            .c_str());
+        throw std::runtime_error(
+            "Failed to set SEEK_SET for phalPELCallouts file");
+    }
+}
+
+void FFDCFile::removeCalloutFile()
+{
+    close(fileFD);
+    std::remove(calloutFile.c_str());
+}
+
+} // namespace pel
+} // namespace openpower
diff --git a/phalerror/create_pel.hpp b/phalerror/create_pel.hpp
index b123a5a..b365272 100644
--- a/phalerror/create_pel.hpp
+++ b/phalerror/create_pel.hpp
@@ -1,123 +1,123 @@
-#pragma once
-
-#include <nlohmann/json.hpp>
-#include <sdbusplus/bus.hpp>
-#include <string>
-#include <vector>
-namespace openpower
-{
-namespace util
-{
-/**
- * Get D-Bus service name for the specified object and interface
- *
- * @param[in] bus - sdbusplus D-Bus to attach to
- * @param[in] objectPath - D-Bus object path
- * @param[in] interface - D-Bus interface name
- *
- * @return service name on success and exception on failure
- */
-std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
-                       const std::string& interface);
-} // namespace util
-namespace pel
-{
-using FFDCData = std::vector<std::pair<std::string, std::string>>;
-
-using json = nlohmann::json;
-
-/**
- * Create boot error PEL
- *
- * @param[in] ffdcData - failure data to append to PEL
- * @param[in] calloutData - callout data to append to PEL
- */
-void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData);
-
-/**
- * @class FFDCFile
- * @brief This class is used to create ffdc data file and to get fd
- */
-class FFDCFile
-{
-  public:
-    FFDCFile() = delete;
-    FFDCFile(const FFDCFile&) = delete;
-    FFDCFile& operator=(const FFDCFile&) = delete;
-    FFDCFile(FFDCFile&&) = delete;
-    FFDCFile& operator=(FFDCFile&&) = delete;
-
-    /**
-     * Used to pass json object to create unique ffdc file by using
-     * passed json data.
-     */
-    explicit FFDCFile(const json& pHALCalloutData);
-
-    /**
-     * Used to remove created ffdc file.
-     */
-    ~FFDCFile();
-
-    /**
-     * Used to get created ffdc file file descriptor id.
-     *
-     * @return file descriptor id
-     */
-    int getFileFD() const;
-
-  private:
-    /**
-     * Used to store callout ffdc data from passed json object.
-     */
-    std::string calloutData;
-
-    /**
-     * Used to store unique ffdc file name.
-     */
-    std::string calloutFile;
-
-    /**
-     * Used to store created ffdc file descriptor id.
-     */
-    int fileFD;
-
-    /**
-     * Used to create ffdc file to pass PEL api for creating
-     * pel records.
-     *
-     * @return NULL
-     */
-    void prepareFFDCFile();
-
-    /**
-     * Create unique ffdc file.
-     *
-     * @return NULL
-     */
-    void createCalloutFile();
-
-    /**
-     * Used write json object value into created file.
-     *
-     * @return NULL
-     */
-    void writeCalloutData();
-
-    /**
-     * Used set ffdc file seek position begining to consume by PEL
-     *
-     * @return NULL
-     */
-    void setCalloutFileSeekPos();
-
-    /**
-     * Used to remove created ffdc file.
-     *
-     * @return NULL
-     */
-    void removeCalloutFile();
-
-}; // FFDCFile end
-
-} // namespace pel
-} // namespace openpower
+#pragma once
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+#include <string>
+#include <vector>
+namespace openpower
+{
+namespace util
+{
+/**
+ * Get D-Bus service name for the specified object and interface
+ *
+ * @param[in] bus - sdbusplus D-Bus to attach to
+ * @param[in] objectPath - D-Bus object path
+ * @param[in] interface - D-Bus interface name
+ *
+ * @return service name on success and exception on failure
+ */
+std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
+                       const std::string& interface);
+} // namespace util
+namespace pel
+{
+using FFDCData = std::vector<std::pair<std::string, std::string>>;
+
+using json = nlohmann::json;
+
+/**
+ * Create boot error PEL
+ *
+ * @param[in] ffdcData - failure data to append to PEL
+ * @param[in] calloutData - callout data to append to PEL
+ */
+void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData);
+
+/**
+ * @class FFDCFile
+ * @brief This class is used to create ffdc data file and to get fd
+ */
+class FFDCFile
+{
+  public:
+    FFDCFile() = delete;
+    FFDCFile(const FFDCFile&) = delete;
+    FFDCFile& operator=(const FFDCFile&) = delete;
+    FFDCFile(FFDCFile&&) = delete;
+    FFDCFile& operator=(FFDCFile&&) = delete;
+
+    /**
+     * Used to pass json object to create unique ffdc file by using
+     * passed json data.
+     */
+    explicit FFDCFile(const json& pHALCalloutData);
+
+    /**
+     * Used to remove created ffdc file.
+     */
+    ~FFDCFile();
+
+    /**
+     * Used to get created ffdc file file descriptor id.
+     *
+     * @return file descriptor id
+     */
+    int getFileFD() const;
+
+  private:
+    /**
+     * Used to store callout ffdc data from passed json object.
+     */
+    std::string calloutData;
+
+    /**
+     * Used to store unique ffdc file name.
+     */
+    std::string calloutFile;
+
+    /**
+     * Used to store created ffdc file descriptor id.
+     */
+    int fileFD;
+
+    /**
+     * Used to create ffdc file to pass PEL api for creating
+     * pel records.
+     *
+     * @return NULL
+     */
+    void prepareFFDCFile();
+
+    /**
+     * Create unique ffdc file.
+     *
+     * @return NULL
+     */
+    void createCalloutFile();
+
+    /**
+     * Used write json object value into created file.
+     *
+     * @return NULL
+     */
+    void writeCalloutData();
+
+    /**
+     * Used set ffdc file seek position begining to consume by PEL
+     *
+     * @return NULL
+     */
+    void setCalloutFileSeekPos();
+
+    /**
+     * Used to remove created ffdc file.
+     *
+     * @return NULL
+     */
+    void removeCalloutFile();
+
+}; // FFDCFile end
+
+} // namespace pel
+} // namespace openpower
diff --git a/phalerror/phal_error.cpp b/phalerror/phal_error.cpp
index 75fb936..8957487 100644
--- a/phalerror/phal_error.cpp
+++ b/phalerror/phal_error.cpp
@@ -1,527 +1,527 @@
-extern "C" {
-#include <libpdbg.h>
-}
-
-#include "create_pel.hpp"
-#include "phal_error.hpp"
-
-#include <attributes_info.H>
-#include <fmt/format.h>
-#include <libekb.H>
-#include <libipl.H>
-
-#include <algorithm>
-#include <cstdlib>
-#include <cstring>
-#include <iomanip>
-#include <list>
-#include <map>
-#include <nlohmann/json.hpp>
-#include <phosphor-logging/elog.hpp>
-#include <sstream>
-#include <string>
-
-namespace openpower
-{
-namespace phal
-{
-using namespace phosphor::logging;
-
-/**
- * Used to pass buffer to pdbg callback api to get required target
- * data (attributes) based on given data (attribute).
- */
-struct TargetInfo
-{
-    ATTR_PHYS_BIN_PATH_Type physBinPath;
-    ATTR_LOCATION_CODE_Type locationCode;
-    ATTR_PHYS_DEV_PATH_Type physDevPath;
-    ATTR_MRU_ID_Type mruId;
-
-    bool deconfigure;
-
-    TargetInfo()
-    {
-        memset(&physBinPath, '\0', sizeof(physBinPath));
-        memset(&locationCode, '\0', sizeof(locationCode));
-        memset(&physDevPath, '\0', sizeof(physDevPath));
-        mruId = 0;
-        deconfigure = false;
-    }
-};
-
-/**
- * Used to return in callback function which are used to get
- * physical path value and it binary format value.
- *
- * The value for constexpr defined based on pdbg_target_traverse function usage.
- */
-constexpr int continueTgtTraversal = 0;
-constexpr int requireAttrFound = 1;
-constexpr int requireAttrNotFound = 2;
-
-/**
- * @brief Used to get target location code from phal device tree
- *
- * @param[in] target current device tree target
- * @param[out] appPrivData used for accessing|storing from|to application
- *
- * @return 0 to continue traverse, non-zero to stop traverse
- */
-int pdbgCallbackToGetTgtReqAttrsVal(struct pdbg_target* target,
-                                    void* appPrivData)
-{
-    TargetInfo* targetInfo = static_cast<TargetInfo*>(appPrivData);
-
-    ATTR_PHYS_BIN_PATH_Type physBinPath;
-    /**
-     * TODO: Issue: phal/pdata#16
-     * Should not use direct pdbg api to read attribute. Need to use DT_GET_PROP
-     * macro for bmc app's and this will call libdt-api api but, it will print
-     * "pdbg_target_get_attribute failed" trace if attribute is not found and
-     * this callback will call recursively by using pdbg_target_traverse() until
-     * find expected attribute based on return code from this callback. Because,
-     * need to do target iteration to get actual attribute (ATTR_PHYS_BIN_PATH)
-     * value when device tree target info doesn't know to read attribute from
-     * device tree. So, Due to this error trace user will get confusion while
-     * looking traces. Hence using pdbg api to avoid trace until libdt-api
-     * provides log level setup.
-     */
-    if (!pdbg_target_get_attribute(
-            target, "ATTR_PHYS_BIN_PATH",
-            std::stoi(dtAttr::fapi2::ATTR_PHYS_BIN_PATH_Spec),
-            dtAttr::fapi2::ATTR_PHYS_BIN_PATH_ElementCount, physBinPath))
-    {
-        return continueTgtTraversal;
-    }
-
-    if (std::memcmp(physBinPath, targetInfo->physBinPath,
-                    sizeof(physBinPath)) != 0)
-    {
-        return continueTgtTraversal;
-    }
-
-    if (DT_GET_PROP(ATTR_LOCATION_CODE, target, targetInfo->locationCode))
-    {
-        log<level::ERR>("Could not read LOCATION_CODE attribute");
-        return requireAttrNotFound;
-    }
-
-    if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, target, targetInfo->physDevPath))
-    {
-        log<level::ERR>("Could not read PHYS_DEV_PATH attribute");
-        return requireAttrNotFound;
-    }
-
-    if (DT_GET_PROP(ATTR_MRU_ID, target, targetInfo->mruId))
-    {
-        log<level::ERR>("Could not read MRU_ID attribute");
-        return requireAttrNotFound;
-    }
-
-    if (targetInfo->deconfigure)
-    {
-        ATTR_HWAS_STATE_Type hwasState;
-        if (DT_GET_PROP(ATTR_HWAS_STATE, target, hwasState))
-        {
-            log<level::ERR>("Could not read HWAS_STATE attribute");
-            return requireAttrNotFound;
-        }
-
-        log<level::INFO>(fmt::format("Marking target({}) as Non-Functional",
-                                     targetInfo->physDevPath)
-                             .c_str());
-        hwasState.functional = 0;
-
-        if (DT_SET_PROP(ATTR_HWAS_STATE, target, hwasState))
-        {
-            log<level::ERR>("Could not write HWAS_STATE attribute");
-            return requireAttrNotFound;
-        }
-    }
-
-    return requireAttrFound;
-}
-
-/**
- * @brief Used to get target info (attributes data)
- *
- * To get target required attributes value using another attribute value
- * ("PHYS_BIN_PATH" which is present in same target attributes list) by using
- * "ipdbg_target_traverse" api because, here we have attribute value only and
- * doesn't have respective device tree target info to get required attributes
- * values from it attributes list.
- *
- * @param[in] physBinPath to pass PHYS_BIN_PATH value
- * @param[out] targetInfo to pas buufer to fill with required attributes
- *
- * @return true on success otherwise false
- */
-bool getTgtReqAttrsVal(const std::vector<uint8_t>& physBinPath,
-                       TargetInfo& targetInfo)
-{
-    std::memcpy(&targetInfo.physBinPath, physBinPath.data(),
-                sizeof(targetInfo.physBinPath));
-
-    int ret = pdbg_target_traverse(NULL, pdbgCallbackToGetTgtReqAttrsVal,
-                                   &targetInfo);
-    if (ret == 0)
-    {
-        log<level::ERR>(fmt::format("Given ATTR_PHYS_BIN_PATH value({}) "
-                                    "not found in phal device tree",
-                                    targetInfo.physBinPath)
-                            .c_str());
-        return false;
-    }
-    else if (ret == requireAttrNotFound)
-    {
-        return false;
-    }
-
-    return true;
-}
-} // namespace phal
-
-namespace pel
-{
-using namespace phosphor::logging;
-
-namespace detail
-{
-using json = nlohmann::json;
-
-// keys need to be unique so using counter value to generate unique key
-static int counter = 0;
-
-// list of debug traces
-static std::vector<std::pair<std::string, std::string>> traceLog;
-
-void processLogTraceCallback(void* private_data, const char* fmt, va_list ap)
-{
-    va_list vap;
-    va_copy(vap, ap);
-    std::vector<char> logData(1 + std::vsnprintf(nullptr, 0, fmt, ap));
-    std::vsnprintf(logData.data(), logData.size(), fmt, vap);
-    va_end(vap);
-    std::string logstr(logData.begin(), logData.end());
-
-    log<level::INFO>(logstr.c_str());
-
-    char timeBuf[80];
-    time_t t = time(0);
-    tm myTm{};
-    gmtime_r(&t, &myTm);
-    strftime(timeBuf, 80, "%Y-%m-%d %H:%M:%S", &myTm);
-
-    // key values need to be unique for PEL
-    // TODO #openbmc/dev/issues/1563
-    // If written to Json no need to worry about unique KEY
-    std::stringstream str;
-    str << std::setfill('0');
-    str << "LOG" << std::setw(3) << counter;
-    str << " " << timeBuf;
-    traceLog.emplace_back(std::make_pair(str.str(), std::move(logstr)));
-    counter++;
-}
-
-/**
- * @brief GET PEL priority from pHAL priority
- *
- * The pHAL callout priority is in different format than PEL format
- * so, this api is used to return current phal supported priority into
- * PEL expected format.
- *
- * @param[in] phalPriority used to pass phal priority format string
- *
- * @return pel priority format string else empty if failure
- *
- * @note For "NONE" returning "L" (LOW)
- */
-static std::string getPelPriority(const std::string& phalPriority)
-{
-    const std::map<std::string, std::string> priorityMap = {
-        {"HIGH", "H"}, {"MEDIUM", "M"}, {"LOW", "L"}, {"NONE", "L"}};
-
-    auto it = priorityMap.find(phalPriority);
-    if (it == priorityMap.end())
-    {
-        log<level::ERR>(fmt::format("Unsupported phal priority({}) is given "
-                                    "to get pel priority format",
-                                    phalPriority)
-                            .c_str());
-        return "H";
-    }
-
-    return it->second;
-}
-
-void processBootErrorCallback(bool status)
-{
-    log<level::INFO>("processBootCallback ", entry("STATUS=%d", status));
-    try
-    {
-        // return If no failure during hwp execution
-        if (status)
-            return;
-
-        // Collecting ffdc details from phal
-        FFDC ffdc;
-        libekb_get_ffdc(ffdc);
-
-        log<level::INFO>(fmt::format("Collected pHAL FFDC. "
-                                     "MSG: {}",
-                                     ffdc.message)
-                             .c_str());
-
-        // To store callouts details in json format as per pel expectation.
-        json jsonCalloutDataList;
-        jsonCalloutDataList = json::array();
-
-        // To store phal trace and other additional data about ffdc.
-        FFDCData pelAdditionalData;
-
-        if (ffdc.ffdc_type == FFDC_TYPE_HWP)
-        {
-            // Adding hardware procedures return code details
-            pelAdditionalData.emplace_back("HWP_RC", ffdc.hwp_errorinfo.rc);
-            pelAdditionalData.emplace_back("HWP_RC_DESC",
-                                           ffdc.hwp_errorinfo.rc_desc);
-
-            // Adding hardware procedures required ffdc data for debug
-            for_each(ffdc.hwp_errorinfo.ffdcs_data.begin(),
-                     ffdc.hwp_errorinfo.ffdcs_data.end(),
-                     [&pelAdditionalData](
-                         std::pair<std::string, std::string>& ele) -> void {
-                         std::string keyWithPrefix("HWP_FFDC_");
-                         keyWithPrefix.append(ele.first);
-
-                         pelAdditionalData.emplace_back(keyWithPrefix,
-                                                        ele.second);
-                     });
-
-            // Adding hardware callout details
-            int calloutCount = 0;
-            for_each(ffdc.hwp_errorinfo.hwcallouts.begin(),
-                     ffdc.hwp_errorinfo.hwcallouts.end(),
-                     [&pelAdditionalData, &calloutCount, &jsonCalloutDataList](
-                         const HWCallout& hwCallout) -> void {
-                         calloutCount++;
-                         std::stringstream keyPrefix;
-                         keyPrefix << "HWP_HW_CO_" << std::setfill('0')
-                                   << std::setw(2) << calloutCount << "_";
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("HW_ID"),
-                             hwCallout.hwid);
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("PRIORITY"),
-                             hwCallout.callout_priority);
-
-                         phal::TargetInfo targetInfo;
-                         phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
-                                                 targetInfo);
-
-                         std::string locationCode =
-                             std::string(targetInfo.locationCode);
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("LOC_CODE"),
-                             locationCode);
-
-                         std::string physPath =
-                             std::string(targetInfo.physDevPath);
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("PHYS_PATH"),
-                             physPath);
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("CLK_POS"),
-                             std::to_string(hwCallout.clkPos));
-
-                         json jsonCalloutData;
-                         jsonCalloutData["LocationCode"] = locationCode;
-                         std::string pelPriority =
-                             getPelPriority(hwCallout.callout_priority);
-                         jsonCalloutData["Priority"] = pelPriority;
-
-                         if (targetInfo.mruId != 0)
-                         {
-                             jsonCalloutData["MRUs"] = json::array({
-                                 {{"ID", targetInfo.mruId},
-                                  {"Priority", pelPriority}},
-                             });
-                         }
-
-                         jsonCalloutDataList.emplace_back(jsonCalloutData);
-                     });
-
-            // Adding CDG (callout, deconfigure and guard) targets details
-            calloutCount = 0;
-            for_each(ffdc.hwp_errorinfo.cdg_targets.begin(),
-                     ffdc.hwp_errorinfo.cdg_targets.end(),
-                     [&pelAdditionalData, &calloutCount,
-                      &jsonCalloutDataList](const CDG_Target& cdg_tgt) -> void {
-                         calloutCount++;
-                         std::stringstream keyPrefix;
-                         keyPrefix << "HWP_CDG_TGT_" << std::setfill('0')
-                                   << std::setw(2) << calloutCount << "_";
-
-                         phal::TargetInfo targetInfo;
-                         targetInfo.deconfigure = cdg_tgt.deconfigure;
-
-                         phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path,
-                                                 targetInfo);
-
-                         std::string locationCode =
-                             std::string(targetInfo.locationCode);
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("LOC_CODE"),
-                             locationCode);
-                         std::string physPath =
-                             std::string(targetInfo.physDevPath);
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("PHYS_PATH"),
-                             physPath);
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("CO_REQ"),
-                             (cdg_tgt.callout == true ? "true" : "false"));
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("CO_PRIORITY"),
-                             cdg_tgt.callout_priority);
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("DECONF_REQ"),
-                             (cdg_tgt.deconfigure == true ? "true" : "false"));
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("GUARD_REQ"),
-                             (cdg_tgt.guard == true ? "true" : "false"));
-
-                         pelAdditionalData.emplace_back(
-                             std::string(keyPrefix.str()).append("GUARD_TYPE"),
-                             cdg_tgt.guard_type);
-
-                         json jsonCalloutData;
-                         jsonCalloutData["LocationCode"] = locationCode;
-                         std::string pelPriority =
-                             getPelPriority(cdg_tgt.callout_priority);
-                         jsonCalloutData["Priority"] = pelPriority;
-
-                         if (targetInfo.mruId != 0)
-                         {
-                             jsonCalloutData["MRUs"] = json::array({
-                                 {{"ID", targetInfo.mruId},
-                                  {"Priority", pelPriority}},
-                             });
-                         }
-                         jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
-                         jsonCalloutData["Guarded"] = cdg_tgt.guard;
-
-                         jsonCalloutDataList.emplace_back(jsonCalloutData);
-                     });
-        }
-        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);
-                 });
-
-        // TODO: #ibm-openbmc/dev/issues/2595 : Once enabled this support,
-        // callout details is not required to sort in H,M and L orders which
-        // are expected by pel because, pel will take care for sorting callouts
-        // based on priority so, now adding support to send callout in order
-        // i.e High -> Medium -> Low.
-        std::sort(
-            jsonCalloutDataList.begin(), jsonCalloutDataList.end(),
-            [](const json& aEle, const json& bEle) -> bool {
-                // Considering b element having higher priority than a element
-                // or Both element will be same priorty (to keep same order
-                // which are given by phal when two callouts are having same
-                // priority)
-                if (((aEle["Priority"] == "M") && (bEle["Priority"] == "H")) ||
-                    ((aEle["Priority"] == "L") &&
-                     ((bEle["Priority"] == "H") ||
-                      (bEle["Priority"] == "M"))) ||
-                    (aEle["Priority"] == bEle["Priority"]))
-                {
-                    return false;
-                }
-
-                // Considering a element having higher priority than b element
-                return true;
-            });
-
-        openpower::pel::createBootErrorPEL(pelAdditionalData,
-                                           jsonCalloutDataList);
-    }
-    catch (std::exception& ex)
-    {
-        reset();
-        throw ex;
-    }
-    reset();
-}
-
-void reset()
-{
-    // reset the trace log and counter
-    traceLog.clear();
-    counter = 0;
-}
-
-void pDBGLogTraceCallbackHelper(int log_level, const char* fmt, va_list ap)
-{
-    processLogTraceCallback(NULL, fmt, ap);
-}
-} // namespace detail
-
-static inline uint8_t getLogLevelFromEnv(const char* env, const uint8_t dValue)
-{
-    auto logLevel = dValue;
-    try
-    {
-        if (const char* env_p = std::getenv(env))
-        {
-            logLevel = std::stoi(env_p);
-        }
-    }
-    catch (std::exception& e)
-    {
-        log<level::ERR>(("Conversion Failure"), entry("ENVIRONMENT=%s", env),
-                        entry("EXCEPTION=%s", e.what()));
-    }
-    return logLevel;
-}
-
-void addBootErrorCallbacks()
-{
-    // Get individual phal repos log level from environment variable
-    // and update the  log level.
-    pdbg_set_loglevel(getLogLevelFromEnv("PDBG_LOG", PDBG_INFO));
-    libekb_set_loglevel(getLogLevelFromEnv("LIBEKB_LOG", LIBEKB_LOG_IMP));
-    ipl_set_loglevel(getLogLevelFromEnv("IPL_LOG", IPL_INFO));
-
-    // add callback for debug traces
-    pdbg_set_logfunc(detail::pDBGLogTraceCallbackHelper);
-    libekb_set_logfunc(detail::processLogTraceCallback, NULL);
-    ipl_set_logfunc(detail::processLogTraceCallback, NULL);
-
-    // add callback for ipl failures
-    ipl_set_error_callback_func(detail::processBootErrorCallback);
-}
-
-} // namespace pel
-} // namespace openpower
+extern "C" {
+#include <libpdbg.h>
+}
+
+#include "create_pel.hpp"
+#include "phal_error.hpp"
+
+#include <attributes_info.H>
+#include <fmt/format.h>
+#include <libekb.H>
+#include <libipl.H>
+
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <iomanip>
+#include <list>
+#include <map>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <sstream>
+#include <string>
+
+namespace openpower
+{
+namespace phal
+{
+using namespace phosphor::logging;
+
+/**
+ * Used to pass buffer to pdbg callback api to get required target
+ * data (attributes) based on given data (attribute).
+ */
+struct TargetInfo
+{
+    ATTR_PHYS_BIN_PATH_Type physBinPath;
+    ATTR_LOCATION_CODE_Type locationCode;
+    ATTR_PHYS_DEV_PATH_Type physDevPath;
+    ATTR_MRU_ID_Type mruId;
+
+    bool deconfigure;
+
+    TargetInfo()
+    {
+        memset(&physBinPath, '\0', sizeof(physBinPath));
+        memset(&locationCode, '\0', sizeof(locationCode));
+        memset(&physDevPath, '\0', sizeof(physDevPath));
+        mruId = 0;
+        deconfigure = false;
+    }
+};
+
+/**
+ * Used to return in callback function which are used to get
+ * physical path value and it binary format value.
+ *
+ * The value for constexpr defined based on pdbg_target_traverse function usage.
+ */
+constexpr int continueTgtTraversal = 0;
+constexpr int requireAttrFound = 1;
+constexpr int requireAttrNotFound = 2;
+
+/**
+ * @brief Used to get target location code from phal device tree
+ *
+ * @param[in] target current device tree target
+ * @param[out] appPrivData used for accessing|storing from|to application
+ *
+ * @return 0 to continue traverse, non-zero to stop traverse
+ */
+int pdbgCallbackToGetTgtReqAttrsVal(struct pdbg_target* target,
+                                    void* appPrivData)
+{
+    TargetInfo* targetInfo = static_cast<TargetInfo*>(appPrivData);
+
+    ATTR_PHYS_BIN_PATH_Type physBinPath;
+    /**
+     * TODO: Issue: phal/pdata#16
+     * Should not use direct pdbg api to read attribute. Need to use DT_GET_PROP
+     * macro for bmc app's and this will call libdt-api api but, it will print
+     * "pdbg_target_get_attribute failed" trace if attribute is not found and
+     * this callback will call recursively by using pdbg_target_traverse() until
+     * find expected attribute based on return code from this callback. Because,
+     * need to do target iteration to get actual attribute (ATTR_PHYS_BIN_PATH)
+     * value when device tree target info doesn't know to read attribute from
+     * device tree. So, Due to this error trace user will get confusion while
+     * looking traces. Hence using pdbg api to avoid trace until libdt-api
+     * provides log level setup.
+     */
+    if (!pdbg_target_get_attribute(
+            target, "ATTR_PHYS_BIN_PATH",
+            std::stoi(dtAttr::fapi2::ATTR_PHYS_BIN_PATH_Spec),
+            dtAttr::fapi2::ATTR_PHYS_BIN_PATH_ElementCount, physBinPath))
+    {
+        return continueTgtTraversal;
+    }
+
+    if (std::memcmp(physBinPath, targetInfo->physBinPath,
+                    sizeof(physBinPath)) != 0)
+    {
+        return continueTgtTraversal;
+    }
+
+    if (DT_GET_PROP(ATTR_LOCATION_CODE, target, targetInfo->locationCode))
+    {
+        log<level::ERR>("Could not read LOCATION_CODE attribute");
+        return requireAttrNotFound;
+    }
+
+    if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, target, targetInfo->physDevPath))
+    {
+        log<level::ERR>("Could not read PHYS_DEV_PATH attribute");
+        return requireAttrNotFound;
+    }
+
+    if (DT_GET_PROP(ATTR_MRU_ID, target, targetInfo->mruId))
+    {
+        log<level::ERR>("Could not read MRU_ID attribute");
+        return requireAttrNotFound;
+    }
+
+    if (targetInfo->deconfigure)
+    {
+        ATTR_HWAS_STATE_Type hwasState;
+        if (DT_GET_PROP(ATTR_HWAS_STATE, target, hwasState))
+        {
+            log<level::ERR>("Could not read HWAS_STATE attribute");
+            return requireAttrNotFound;
+        }
+
+        log<level::INFO>(fmt::format("Marking target({}) as Non-Functional",
+                                     targetInfo->physDevPath)
+                             .c_str());
+        hwasState.functional = 0;
+
+        if (DT_SET_PROP(ATTR_HWAS_STATE, target, hwasState))
+        {
+            log<level::ERR>("Could not write HWAS_STATE attribute");
+            return requireAttrNotFound;
+        }
+    }
+
+    return requireAttrFound;
+}
+
+/**
+ * @brief Used to get target info (attributes data)
+ *
+ * To get target required attributes value using another attribute value
+ * ("PHYS_BIN_PATH" which is present in same target attributes list) by using
+ * "ipdbg_target_traverse" api because, here we have attribute value only and
+ * doesn't have respective device tree target info to get required attributes
+ * values from it attributes list.
+ *
+ * @param[in] physBinPath to pass PHYS_BIN_PATH value
+ * @param[out] targetInfo to pas buufer to fill with required attributes
+ *
+ * @return true on success otherwise false
+ */
+bool getTgtReqAttrsVal(const std::vector<uint8_t>& physBinPath,
+                       TargetInfo& targetInfo)
+{
+    std::memcpy(&targetInfo.physBinPath, physBinPath.data(),
+                sizeof(targetInfo.physBinPath));
+
+    int ret = pdbg_target_traverse(NULL, pdbgCallbackToGetTgtReqAttrsVal,
+                                   &targetInfo);
+    if (ret == 0)
+    {
+        log<level::ERR>(fmt::format("Given ATTR_PHYS_BIN_PATH value({}) "
+                                    "not found in phal device tree",
+                                    targetInfo.physBinPath)
+                            .c_str());
+        return false;
+    }
+    else if (ret == requireAttrNotFound)
+    {
+        return false;
+    }
+
+    return true;
+}
+} // namespace phal
+
+namespace pel
+{
+using namespace phosphor::logging;
+
+namespace detail
+{
+using json = nlohmann::json;
+
+// keys need to be unique so using counter value to generate unique key
+static int counter = 0;
+
+// list of debug traces
+static std::vector<std::pair<std::string, std::string>> traceLog;
+
+void processLogTraceCallback(void* private_data, const char* fmt, va_list ap)
+{
+    va_list vap;
+    va_copy(vap, ap);
+    std::vector<char> logData(1 + std::vsnprintf(nullptr, 0, fmt, ap));
+    std::vsnprintf(logData.data(), logData.size(), fmt, vap);
+    va_end(vap);
+    std::string logstr(logData.begin(), logData.end());
+
+    log<level::INFO>(logstr.c_str());
+
+    char timeBuf[80];
+    time_t t = time(0);
+    tm myTm{};
+    gmtime_r(&t, &myTm);
+    strftime(timeBuf, 80, "%Y-%m-%d %H:%M:%S", &myTm);
+
+    // key values need to be unique for PEL
+    // TODO #openbmc/dev/issues/1563
+    // If written to Json no need to worry about unique KEY
+    std::stringstream str;
+    str << std::setfill('0');
+    str << "LOG" << std::setw(3) << counter;
+    str << " " << timeBuf;
+    traceLog.emplace_back(std::make_pair(str.str(), std::move(logstr)));
+    counter++;
+}
+
+/**
+ * @brief GET PEL priority from pHAL priority
+ *
+ * The pHAL callout priority is in different format than PEL format
+ * so, this api is used to return current phal supported priority into
+ * PEL expected format.
+ *
+ * @param[in] phalPriority used to pass phal priority format string
+ *
+ * @return pel priority format string else empty if failure
+ *
+ * @note For "NONE" returning "L" (LOW)
+ */
+static std::string getPelPriority(const std::string& phalPriority)
+{
+    const std::map<std::string, std::string> priorityMap = {
+        {"HIGH", "H"}, {"MEDIUM", "M"}, {"LOW", "L"}, {"NONE", "L"}};
+
+    auto it = priorityMap.find(phalPriority);
+    if (it == priorityMap.end())
+    {
+        log<level::ERR>(fmt::format("Unsupported phal priority({}) is given "
+                                    "to get pel priority format",
+                                    phalPriority)
+                            .c_str());
+        return "H";
+    }
+
+    return it->second;
+}
+
+void processBootErrorCallback(bool status)
+{
+    log<level::INFO>("processBootCallback ", entry("STATUS=%d", status));
+    try
+    {
+        // return If no failure during hwp execution
+        if (status)
+            return;
+
+        // Collecting ffdc details from phal
+        FFDC ffdc;
+        libekb_get_ffdc(ffdc);
+
+        log<level::INFO>(fmt::format("Collected pHAL FFDC. "
+                                     "MSG: {}",
+                                     ffdc.message)
+                             .c_str());
+
+        // To store callouts details in json format as per pel expectation.
+        json jsonCalloutDataList;
+        jsonCalloutDataList = json::array();
+
+        // To store phal trace and other additional data about ffdc.
+        FFDCData pelAdditionalData;
+
+        if (ffdc.ffdc_type == FFDC_TYPE_HWP)
+        {
+            // Adding hardware procedures return code details
+            pelAdditionalData.emplace_back("HWP_RC", ffdc.hwp_errorinfo.rc);
+            pelAdditionalData.emplace_back("HWP_RC_DESC",
+                                           ffdc.hwp_errorinfo.rc_desc);
+
+            // Adding hardware procedures required ffdc data for debug
+            for_each(ffdc.hwp_errorinfo.ffdcs_data.begin(),
+                     ffdc.hwp_errorinfo.ffdcs_data.end(),
+                     [&pelAdditionalData](
+                         std::pair<std::string, std::string>& ele) -> void {
+                         std::string keyWithPrefix("HWP_FFDC_");
+                         keyWithPrefix.append(ele.first);
+
+                         pelAdditionalData.emplace_back(keyWithPrefix,
+                                                        ele.second);
+                     });
+
+            // Adding hardware callout details
+            int calloutCount = 0;
+            for_each(ffdc.hwp_errorinfo.hwcallouts.begin(),
+                     ffdc.hwp_errorinfo.hwcallouts.end(),
+                     [&pelAdditionalData, &calloutCount, &jsonCalloutDataList](
+                         const HWCallout& hwCallout) -> void {
+                         calloutCount++;
+                         std::stringstream keyPrefix;
+                         keyPrefix << "HWP_HW_CO_" << std::setfill('0')
+                                   << std::setw(2) << calloutCount << "_";
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("HW_ID"),
+                             hwCallout.hwid);
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("PRIORITY"),
+                             hwCallout.callout_priority);
+
+                         phal::TargetInfo targetInfo;
+                         phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
+                                                 targetInfo);
+
+                         std::string locationCode =
+                             std::string(targetInfo.locationCode);
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("LOC_CODE"),
+                             locationCode);
+
+                         std::string physPath =
+                             std::string(targetInfo.physDevPath);
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("PHYS_PATH"),
+                             physPath);
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("CLK_POS"),
+                             std::to_string(hwCallout.clkPos));
+
+                         json jsonCalloutData;
+                         jsonCalloutData["LocationCode"] = locationCode;
+                         std::string pelPriority =
+                             getPelPriority(hwCallout.callout_priority);
+                         jsonCalloutData["Priority"] = pelPriority;
+
+                         if (targetInfo.mruId != 0)
+                         {
+                             jsonCalloutData["MRUs"] = json::array({
+                                 {{"ID", targetInfo.mruId},
+                                  {"Priority", pelPriority}},
+                             });
+                         }
+
+                         jsonCalloutDataList.emplace_back(jsonCalloutData);
+                     });
+
+            // Adding CDG (callout, deconfigure and guard) targets details
+            calloutCount = 0;
+            for_each(ffdc.hwp_errorinfo.cdg_targets.begin(),
+                     ffdc.hwp_errorinfo.cdg_targets.end(),
+                     [&pelAdditionalData, &calloutCount,
+                      &jsonCalloutDataList](const CDG_Target& cdg_tgt) -> void {
+                         calloutCount++;
+                         std::stringstream keyPrefix;
+                         keyPrefix << "HWP_CDG_TGT_" << std::setfill('0')
+                                   << std::setw(2) << calloutCount << "_";
+
+                         phal::TargetInfo targetInfo;
+                         targetInfo.deconfigure = cdg_tgt.deconfigure;
+
+                         phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path,
+                                                 targetInfo);
+
+                         std::string locationCode =
+                             std::string(targetInfo.locationCode);
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("LOC_CODE"),
+                             locationCode);
+                         std::string physPath =
+                             std::string(targetInfo.physDevPath);
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("PHYS_PATH"),
+                             physPath);
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("CO_REQ"),
+                             (cdg_tgt.callout == true ? "true" : "false"));
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("CO_PRIORITY"),
+                             cdg_tgt.callout_priority);
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("DECONF_REQ"),
+                             (cdg_tgt.deconfigure == true ? "true" : "false"));
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("GUARD_REQ"),
+                             (cdg_tgt.guard == true ? "true" : "false"));
+
+                         pelAdditionalData.emplace_back(
+                             std::string(keyPrefix.str()).append("GUARD_TYPE"),
+                             cdg_tgt.guard_type);
+
+                         json jsonCalloutData;
+                         jsonCalloutData["LocationCode"] = locationCode;
+                         std::string pelPriority =
+                             getPelPriority(cdg_tgt.callout_priority);
+                         jsonCalloutData["Priority"] = pelPriority;
+
+                         if (targetInfo.mruId != 0)
+                         {
+                             jsonCalloutData["MRUs"] = json::array({
+                                 {{"ID", targetInfo.mruId},
+                                  {"Priority", pelPriority}},
+                             });
+                         }
+                         jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
+                         jsonCalloutData["Guarded"] = cdg_tgt.guard;
+
+                         jsonCalloutDataList.emplace_back(jsonCalloutData);
+                     });
+        }
+        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);
+                 });
+
+        // TODO: #ibm-openbmc/dev/issues/2595 : Once enabled this support,
+        // callout details is not required to sort in H,M and L orders which
+        // are expected by pel because, pel will take care for sorting callouts
+        // based on priority so, now adding support to send callout in order
+        // i.e High -> Medium -> Low.
+        std::sort(
+            jsonCalloutDataList.begin(), jsonCalloutDataList.end(),
+            [](const json& aEle, const json& bEle) -> bool {
+                // Considering b element having higher priority than a element
+                // or Both element will be same priorty (to keep same order
+                // which are given by phal when two callouts are having same
+                // priority)
+                if (((aEle["Priority"] == "M") && (bEle["Priority"] == "H")) ||
+                    ((aEle["Priority"] == "L") &&
+                     ((bEle["Priority"] == "H") ||
+                      (bEle["Priority"] == "M"))) ||
+                    (aEle["Priority"] == bEle["Priority"]))
+                {
+                    return false;
+                }
+
+                // Considering a element having higher priority than b element
+                return true;
+            });
+
+        openpower::pel::createBootErrorPEL(pelAdditionalData,
+                                           jsonCalloutDataList);
+    }
+    catch (std::exception& ex)
+    {
+        reset();
+        throw ex;
+    }
+    reset();
+}
+
+void reset()
+{
+    // reset the trace log and counter
+    traceLog.clear();
+    counter = 0;
+}
+
+void pDBGLogTraceCallbackHelper(int log_level, const char* fmt, va_list ap)
+{
+    processLogTraceCallback(NULL, fmt, ap);
+}
+} // namespace detail
+
+static inline uint8_t getLogLevelFromEnv(const char* env, const uint8_t dValue)
+{
+    auto logLevel = dValue;
+    try
+    {
+        if (const char* env_p = std::getenv(env))
+        {
+            logLevel = std::stoi(env_p);
+        }
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>(("Conversion Failure"), entry("ENVIRONMENT=%s", env),
+                        entry("EXCEPTION=%s", e.what()));
+    }
+    return logLevel;
+}
+
+void addBootErrorCallbacks()
+{
+    // Get individual phal repos log level from environment variable
+    // and update the  log level.
+    pdbg_set_loglevel(getLogLevelFromEnv("PDBG_LOG", PDBG_INFO));
+    libekb_set_loglevel(getLogLevelFromEnv("LIBEKB_LOG", LIBEKB_LOG_IMP));
+    ipl_set_loglevel(getLogLevelFromEnv("IPL_LOG", IPL_INFO));
+
+    // add callback for debug traces
+    pdbg_set_logfunc(detail::pDBGLogTraceCallbackHelper);
+    libekb_set_logfunc(detail::processLogTraceCallback, NULL);
+    ipl_set_logfunc(detail::processLogTraceCallback, NULL);
+
+    // add callback for ipl failures
+    ipl_set_error_callback_func(detail::processBootErrorCallback);
+}
+
+} // namespace pel
+} // namespace openpower
diff --git a/phalerror/phal_error.hpp b/phalerror/phal_error.hpp
index 055cf35..b132b8f 100644
--- a/phalerror/phal_error.hpp
+++ b/phalerror/phal_error.hpp
@@ -1,49 +1,49 @@
-#pragma once
-
-#include <cstdarg>
-namespace openpower
-{
-namespace pel
-{
-namespace detail
-{
-
-/**
- * @brief Process debug traces
- *
- * Function adds debug traces to the list so that it will be added to the
- * PEL upon failure
- *
- * @param[in] private_data - pointer to private data, unused now
- * @param[in] fmt - format for variable list arguments
- * @param[in] ap - object of va_list, holds information needed to retrieve
- *                 the additional arguments
- */
-
-void processLogTraceCallback(void* private_data, const char* fmt, va_list ap);
-
-/**
- * @brief Process boot failure/success status
- *
- * If status is success log traces are cleared else used in the
- * creation of failure
- *
- * @param[in] status - Boot execution status
- */
-void processBootErrorCallback(bool status);
-
-/**
- * @brief Reset trace log list
- */
-void reset();
-} // namespace detail
-
-/**
- * @brief Add callbacks for debug traces and boot errors
- *
- * This function adds callback for debug traces and for boot
- * errors
- */
-void addBootErrorCallbacks();
-} // namespace pel
-} // namespace openpower
+#pragma once
+
+#include <cstdarg>
+namespace openpower
+{
+namespace pel
+{
+namespace detail
+{
+
+/**
+ * @brief Process debug traces
+ *
+ * Function adds debug traces to the list so that it will be added to the
+ * PEL upon failure
+ *
+ * @param[in] private_data - pointer to private data, unused now
+ * @param[in] fmt - format for variable list arguments
+ * @param[in] ap - object of va_list, holds information needed to retrieve
+ *                 the additional arguments
+ */
+
+void processLogTraceCallback(void* private_data, const char* fmt, va_list ap);
+
+/**
+ * @brief Process boot failure/success status
+ *
+ * If status is success log traces are cleared else used in the
+ * creation of failure
+ *
+ * @param[in] status - Boot execution status
+ */
+void processBootErrorCallback(bool status);
+
+/**
+ * @brief Reset trace log list
+ */
+void reset();
+} // namespace detail
+
+/**
+ * @brief Add callbacks for debug traces and boot errors
+ *
+ * This function adds callback for debug traces and for boot
+ * errors
+ */
+void addBootErrorCallbacks();
+} // namespace pel
+} // namespace openpower
