PHAL: Clock error handling support
-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 <rajerpp1@in.ibm.com>
Change-Id: Ifd2268b1c99be4dbfa9234e910d7e87771adb176
diff --git a/extensions/phal/phal_error.cpp b/extensions/phal/phal_error.cpp
index 27f9067..354210f 100644
--- a/extensions/phal/phal_error.cpp
+++ b/extensions/phal/phal_error.cpp
@@ -293,7 +293,32 @@
}
}
-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
@@ -311,17 +336,20 @@
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,
@@ -330,123 +358,141 @@
// 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 << "_";
+ 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("HW_ID"),
+ hwCallout.hwid);
- pelAdditionalData.emplace_back(
- std::string(keyPrefix.str()).append("PRIORITY"),
- hwCallout.callout_priority);
+ pelAdditionalData.emplace_back(
+ std::string(keyPrefix.str()).append("PRIORITY"),
+ hwCallout.callout_priority);
- phal::TargetInfo targetInfo;
- phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
- targetInfo);
+ // 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 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);
+ 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("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 << "_";
+ 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::TargetInfo targetInfo;
+ targetInfo.deconfigure = cdg_tgt.deconfigure;
- phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path,
- targetInfo);
+ 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);
+ 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_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("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("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_REQ"),
+ (cdg_tgt.guard == true ? "true" : "false"));
- pelAdditionalData.emplace_back(
- std::string(keyPrefix.str()).append("GUARD_TYPE"),
- cdg_tgt.guard_type);
+ 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;
+ 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;
+ 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);
- });
+ 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(
@@ -525,7 +571,7 @@
FFDC* ffdc = reinterpret_cast<FFDC*>(errInfo.private_data);
try
{
- processBootErrorHelper(ffdc);
+ processBootErrorHelper(ffdc, "PLAT_");
}
catch (const std::exception& ex)
{
@@ -551,7 +597,7 @@
FFDC ffdc;
libekb_get_ffdc(ffdc);
- processBootErrorHelper(&ffdc);
+ processBootErrorHelper(&ffdc, "HWP_");
}
catch (const std::exception& ex)
{