Skip to content

Commit

Permalink
PHAL: Clock error handling support
Browse files Browse the repository at this point in the history
-Supporting new flag to indicate planar callout required
    -This flag can be set from either clock HWP error or clock
     non-HWP error.
-Adding new error type for ipl error callback
    -This error type can be called for non-hwp failures
    -Additional data sent will be parsed and included in PEL
-Different prefix is added for HWP error and PLAT error.
Tested:
"Primary SRC": {
    "Deconfigured":             "False",
    "Guarded":                  "False",
    "Error Details": {
        "Message":              "Failure occured during boot process"
    },
    "Callout Section": {
        "Callout Count":        "1",
        "Callouts": [{
            "FRU Type":         "Normal Hardware FRU",
            "Priority":         "Mandatory, replace all with this type as a unit",
            "Location Code":    "U780C.ND0.1234567-P0",
            "Part Number":      "F040221",
            "CCIN":             "2E33",
            "Serial Number":    "YL2E33010000"
        }]
    }
},
"User Data 1": {
    "Section Version": "1",
    "Sub-section type": "1",
    "Created by": "0x2000",

    "PLAT_FFDC_FAIL_TYPE": "STATUS_READ",
    "PLAT_FFDC_I2C_RC": "0",
    "PLAT_HW_CO_01_CALLOUT_PLANAR": "true",
    "PLAT_HW_CO_01_CLK_POS": "1",
    "PLAT_HW_CO_01_HW_ID": "PROC_REF_CLOCK",
    "PLAT_HW_CO_01_PRIORITY": "HIGH",
    "PLAT_RC": "10",
    "PLAT_RC_DESC": "Error in executing clock initialisation",
    "_PID": "21916"
},
"User Data 2": {
    "Section Version": "1",
    "Sub-section type": "1",
    "Created by": "0x2000",
    "Data": [
        {
            "Deconfigured": false,
            "Guarded": false,
            "InventoryPath": "/xyz/openbmc_project/inventory/system/chassis/motherboard",
            "Priority": "H"
        }
    ]
}

Signed-off-by: Rajees P P <[email protected]>
Change-Id: Ifd2268b1c99be4dbfa9234e910d7e87771adb176
  • Loading branch information
rajez133 committed Dec 14, 2021
1 parent b6074db commit db92472
Showing 1 changed file with 160 additions and 114 deletions.
274 changes: 160 additions & 114 deletions extensions/phal/phal_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,32 @@ void processIplErrorCallback(const ipl_error_info& errInfo)
}
}

void processBootErrorHelper(FFDC* ffdc)
/**
* @brief addPlanarCallout
*
* This function will add a json for planar callout in the input json list.
* The caller can pass this json list into createErrorPEL to apply the callout.
*
* @param[in,out] jsonCalloutDataList - json list where callout json will be
* emplaced
* @param[in] priority - string indicating priority.
*/
static void addPlanarCallout(json& jsonCalloutDataList,
const std::string& priority)
{
json jsonCalloutData;

// Inventory path for planar
jsonCalloutData["InventoryPath"] =
"/xyz/openbmc_project/inventory/system/chassis/motherboard";
jsonCalloutData["Deconfigured"] = false;
jsonCalloutData["Guarded"] = false;
jsonCalloutData["Priority"] = priority;

jsonCalloutDataList.emplace_back(jsonCalloutData);
}

void processBootErrorHelper(FFDC* ffdc, const std::string& ffdc_prefix)
{
log<level::INFO>("processBootErrorHelper ");
try
Expand All @@ -311,17 +336,20 @@ void processBootErrorHelper(FFDC* ffdc)

if (ffdc->ffdc_type == FFDC_TYPE_HWP)
{
std::string keyWithPrefix(ffdc_prefix + "RC");
// Adding hardware procedures return code details
pelAdditionalData.emplace_back("HWP_RC", ffdc->hwp_errorinfo.rc);
pelAdditionalData.emplace_back("HWP_RC_DESC",
pelAdditionalData.emplace_back(keyWithPrefix,
ffdc->hwp_errorinfo.rc);
keyWithPrefix = ffdc_prefix + "RC_DESC";
pelAdditionalData.emplace_back(keyWithPrefix,
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](
[&pelAdditionalData, &ffdc_prefix](
std::pair<std::string, std::string>& ele) -> void {
std::string keyWithPrefix("HWP_FFDC_");
std::string keyWithPrefix(ffdc_prefix + "FFDC_");
keyWithPrefix.append(ele.first);

pelAdditionalData.emplace_back(keyWithPrefix,
Expand All @@ -330,123 +358,141 @@ void processBootErrorHelper(FFDC* ffdc)

// 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));
});
for_each(
ffdc->hwp_errorinfo.hwcallouts.begin(),
ffdc->hwp_errorinfo.hwcallouts.end(),
[&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
&ffdc_prefix](const HWCallout& hwCallout) -> void {
calloutCount++;
std::stringstream keyPrefix;
keyPrefix << ffdc_prefix << "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);

// Log target details only if entity path is
// available. For example target entity path will not
// be available for non-hwp clock failure.
if (!hwCallout.target_entity_path.empty())
{
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));

pelAdditionalData.emplace_back(
std::string(keyPrefix.str()).append("CALLOUT_PLANAR"),
(hwCallout.isPlanarCallout == true ? "true" : "false"));

std::string pelPriority =
getPelPriority(hwCallout.callout_priority);

if (hwCallout.isPlanarCallout)
{
addPlanarCallout(jsonCalloutDataList, pelPriority);
}
});

// 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;
jsonCalloutData["GuardType"] = cdg_tgt.guard_type;
jsonCalloutData["EntityPath"] =
cdg_tgt.target_entity_path;

jsonCalloutDataList.emplace_back(jsonCalloutData);
});
for_each(
ffdc->hwp_errorinfo.cdg_targets.begin(),
ffdc->hwp_errorinfo.cdg_targets.end(),
[&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
&ffdc_prefix](const CDG_Target& cdg_tgt) -> void {
calloutCount++;
std::stringstream keyPrefix;
keyPrefix << ffdc_prefix << "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;
jsonCalloutData["GuardType"] = cdg_tgt.guard_type;
jsonCalloutData["EntityPath"] = cdg_tgt.target_entity_path;

jsonCalloutDataList.emplace_back(jsonCalloutData);
});
// Adding procedure callout
calloutCount = 0;
for_each(
ffdc->hwp_errorinfo.procedures_callout.begin(),
ffdc->hwp_errorinfo.procedures_callout.end(),
[&pelAdditionalData, &calloutCount, &jsonCalloutDataList](
const ProcedureCallout& procCallout) -> void {
[&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
&ffdc_prefix](const ProcedureCallout& procCallout) -> void {
calloutCount++;
std::stringstream keyPrefix;
keyPrefix << "HWP_PROC_CO_" << std::setfill('0')
keyPrefix << ffdc_prefix << "PROC_CO_" << std::setfill('0')
<< std::setw(2) << calloutCount << "_";

pelAdditionalData.emplace_back(
Expand Down Expand Up @@ -525,7 +571,7 @@ void processPlatBootError(const ipl_error_info& errInfo)
FFDC* ffdc = reinterpret_cast<FFDC*>(errInfo.private_data);
try
{
processBootErrorHelper(ffdc);
processBootErrorHelper(ffdc, "PLAT_");
}
catch (const std::exception& ex)
{
Expand All @@ -551,7 +597,7 @@ void processBootError(bool status)
FFDC ffdc;
libekb_get_ffdc(ffdc);

processBootErrorHelper(&ffdc);
processBootErrorHelper(&ffdc, "HWP_");
}
catch (const std::exception& ex)
{
Expand Down

0 comments on commit db92472

Please sign in to comment.