blob: 8677b6a24ee0e68eeed0cabd6b1208303b80d1cb [file] [log] [blame]
Brad Bishop5e5d4452020-10-27 19:46:13 -04001extern "C"
2{
Brad Bishopf6783cd2020-10-27 19:25:09 -04003#include <libpdbg.h>
4}
5
6#include "create_pel.hpp"
Jayanth Othayoth006641e2021-10-07 06:56:24 -05007#include "dump_utils.hpp"
Jayanth Othayoth4079f092021-09-20 07:36:54 -05008#include "extensions/phal/common_utils.hpp"
Brad Bishopf6783cd2020-10-27 19:25:09 -04009#include "phal_error.hpp"
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -050010#include "util.hpp"
Brad Bishopf6783cd2020-10-27 19:25:09 -040011
12#include <attributes_info.H>
Brad Bishopf6783cd2020-10-27 19:25:09 -040013#include <libekb.H>
Jayanth Othayoth4079f092021-09-20 07:36:54 -050014#include <libphal.H>
Brad Bishopf6783cd2020-10-27 19:25:09 -040015
Brad Bishop5e5d4452020-10-27 19:46:13 -040016#include <nlohmann/json.hpp>
17#include <phosphor-logging/elog.hpp>
18
Brad Bishopf6783cd2020-10-27 19:25:09 -040019#include <algorithm>
20#include <cstdlib>
21#include <cstring>
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +000022#include <format>
Brad Bishopf6783cd2020-10-27 19:25:09 -040023#include <iomanip>
24#include <list>
25#include <map>
Brad Bishopf6783cd2020-10-27 19:25:09 -040026#include <sstream>
27#include <string>
28
29namespace openpower
30{
31namespace phal
32{
33using namespace phosphor::logging;
Jayanth Othayoth5d5eb312021-11-15 01:54:07 -060034using namespace openpower::phal::exception;
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -050035using Severity = sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level;
Brad Bishopf6783cd2020-10-27 19:25:09 -040036
37/**
38 * Used to pass buffer to pdbg callback api to get required target
39 * data (attributes) based on given data (attribute).
40 */
41struct TargetInfo
42{
43 ATTR_PHYS_BIN_PATH_Type physBinPath;
44 ATTR_LOCATION_CODE_Type locationCode;
45 ATTR_PHYS_DEV_PATH_Type physDevPath;
46 ATTR_MRU_ID_Type mruId;
47
48 bool deconfigure;
49
50 TargetInfo()
51 {
52 memset(&physBinPath, '\0', sizeof(physBinPath));
53 memset(&locationCode, '\0', sizeof(locationCode));
54 memset(&physDevPath, '\0', sizeof(physDevPath));
55 mruId = 0;
56 deconfigure = false;
57 }
58};
59
60/**
61 * Used to return in callback function which are used to get
62 * physical path value and it binary format value.
63 *
64 * The value for constexpr defined based on pdbg_target_traverse function usage.
65 */
66constexpr int continueTgtTraversal = 0;
67constexpr int requireAttrFound = 1;
68constexpr int requireAttrNotFound = 2;
69
70/**
71 * @brief Used to get target location code from phal device tree
72 *
73 * @param[in] target current device tree target
74 * @param[out] appPrivData used for accessing|storing from|to application
75 *
76 * @return 0 to continue traverse, non-zero to stop traverse
77 */
78int pdbgCallbackToGetTgtReqAttrsVal(struct pdbg_target* target,
79 void* appPrivData)
80{
Jayanth Othayoth5d5eb312021-11-15 01:54:07 -060081 using namespace openpower::phal::pdbg;
82
Brad Bishopf6783cd2020-10-27 19:25:09 -040083 TargetInfo* targetInfo = static_cast<TargetInfo*>(appPrivData);
84
85 ATTR_PHYS_BIN_PATH_Type physBinPath;
86 /**
87 * TODO: Issue: phal/pdata#16
88 * Should not use direct pdbg api to read attribute. Need to use DT_GET_PROP
89 * macro for bmc app's and this will call libdt-api api but, it will print
90 * "pdbg_target_get_attribute failed" trace if attribute is not found and
91 * this callback will call recursively by using pdbg_target_traverse() until
92 * find expected attribute based on return code from this callback. Because,
93 * need to do target iteration to get actual attribute (ATTR_PHYS_BIN_PATH)
94 * value when device tree target info doesn't know to read attribute from
95 * device tree. So, Due to this error trace user will get confusion while
96 * looking traces. Hence using pdbg api to avoid trace until libdt-api
97 * provides log level setup.
98 */
99 if (!pdbg_target_get_attribute(
100 target, "ATTR_PHYS_BIN_PATH",
101 std::stoi(dtAttr::fapi2::ATTR_PHYS_BIN_PATH_Spec),
102 dtAttr::fapi2::ATTR_PHYS_BIN_PATH_ElementCount, physBinPath))
103 {
104 return continueTgtTraversal;
105 }
106
107 if (std::memcmp(physBinPath, targetInfo->physBinPath,
108 sizeof(physBinPath)) != 0)
109 {
110 return continueTgtTraversal;
111 }
112
Jayanth Othayothde909252021-11-15 02:36:45 -0600113 // Found Target, now collect the required attributes associated to the
114 // target. Incase of any attribute read failure, initialize the data with
115 // default value.
Jayanth Othayoth5d5eb312021-11-15 01:54:07 -0600116 try
Brad Bishopf6783cd2020-10-27 19:25:09 -0400117 {
Jayanth Othayoth5d5eb312021-11-15 01:54:07 -0600118 // Get location code information
119 openpower::phal::pdbg::getLocationCode(target,
120 targetInfo->locationCode);
121 }
122 catch (const std::exception& e)
123 {
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000124 log<level::ERR>(std::format("getLocationCode({}): Exception({})",
Jayanth Othayoth5d5eb312021-11-15 01:54:07 -0600125 pdbg_target_path(target), e.what())
126 .c_str());
Brad Bishopf6783cd2020-10-27 19:25:09 -0400127 }
128
129 if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, target, targetInfo->physDevPath))
130 {
Jayanth Othayothde909252021-11-15 02:36:45 -0600131 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000132 std::format("Could not read({}) PHYS_DEV_PATH attribute",
Jayanth Othayothde909252021-11-15 02:36:45 -0600133 pdbg_target_path(target))
134 .c_str());
Brad Bishopf6783cd2020-10-27 19:25:09 -0400135 }
136
137 if (DT_GET_PROP(ATTR_MRU_ID, target, targetInfo->mruId))
138 {
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000139 log<level::ERR>(std::format("Could not read({}) ATTR_MRU_ID attribute",
Jayanth Othayothde909252021-11-15 02:36:45 -0600140 pdbg_target_path(target))
141 .c_str());
Brad Bishopf6783cd2020-10-27 19:25:09 -0400142 }
143
Brad Bishopf6783cd2020-10-27 19:25:09 -0400144 return requireAttrFound;
145}
146
147/**
148 * @brief Used to get target info (attributes data)
149 *
150 * To get target required attributes value using another attribute value
151 * ("PHYS_BIN_PATH" which is present in same target attributes list) by using
152 * "ipdbg_target_traverse" api because, here we have attribute value only and
153 * doesn't have respective device tree target info to get required attributes
154 * values from it attributes list.
155 *
156 * @param[in] physBinPath to pass PHYS_BIN_PATH value
157 * @param[out] targetInfo to pas buufer to fill with required attributes
158 *
159 * @return true on success otherwise false
160 */
161bool getTgtReqAttrsVal(const std::vector<uint8_t>& physBinPath,
162 TargetInfo& targetInfo)
163{
164 std::memcpy(&targetInfo.physBinPath, physBinPath.data(),
165 sizeof(targetInfo.physBinPath));
166
167 int ret = pdbg_target_traverse(NULL, pdbgCallbackToGetTgtReqAttrsVal,
168 &targetInfo);
169 if (ret == 0)
170 {
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000171 std::string fmt;
172 for (auto value : targetInfo.physBinPath)
173 {
174 fmt += std::format("{:02X} ", value);
175 }
176
177 log<level::ERR>(std::format("Given ATTR_PHYS_BIN_PATH value {} "
Brad Bishopf6783cd2020-10-27 19:25:09 -0400178 "not found in phal device tree",
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000179 fmt)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400180 .c_str());
181 return false;
182 }
183 else if (ret == requireAttrNotFound)
184 {
185 return false;
186 }
187
188 return true;
189}
190} // namespace phal
191
192namespace pel
193{
194using namespace phosphor::logging;
195
196namespace detail
197{
198using json = nlohmann::json;
199
200// keys need to be unique so using counter value to generate unique key
201static int counter = 0;
202
203// list of debug traces
204static std::vector<std::pair<std::string, std::string>> traceLog;
205
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600206/**
207 * @brief Process platform realted boot failure
208 *
209 * @param[in] errInfo - error details
210 */
211static void processPlatBootError(const ipl_error_info& errInfo);
212
Brad Bishop63508a72020-10-27 18:55:01 -0400213void processLogTraceCallback(void*, const char* fmt, va_list ap)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400214{
215 va_list vap;
216 va_copy(vap, ap);
217 std::vector<char> logData(1 + std::vsnprintf(nullptr, 0, fmt, ap));
218 std::vsnprintf(logData.data(), logData.size(), fmt, vap);
219 va_end(vap);
220 std::string logstr(logData.begin(), logData.end());
221
222 log<level::INFO>(logstr.c_str());
223
224 char timeBuf[80];
225 time_t t = time(0);
226 tm myTm{};
227 gmtime_r(&t, &myTm);
228 strftime(timeBuf, 80, "%Y-%m-%d %H:%M:%S", &myTm);
229
230 // key values need to be unique for PEL
231 // TODO #openbmc/dev/issues/1563
232 // If written to Json no need to worry about unique KEY
233 std::stringstream str;
234 str << std::setfill('0');
235 str << "LOG" << std::setw(3) << counter;
236 str << " " << timeBuf;
237 traceLog.emplace_back(std::make_pair(str.str(), std::move(logstr)));
238 counter++;
239}
240
241/**
242 * @brief GET PEL priority from pHAL priority
243 *
244 * The pHAL callout priority is in different format than PEL format
245 * so, this api is used to return current phal supported priority into
246 * PEL expected format.
247 *
248 * @param[in] phalPriority used to pass phal priority format string
249 *
250 * @return pel priority format string else empty if failure
251 *
252 * @note For "NONE" returning "L" (LOW)
253 */
254static std::string getPelPriority(const std::string& phalPriority)
255{
256 const std::map<std::string, std::string> priorityMap = {
257 {"HIGH", "H"}, {"MEDIUM", "M"}, {"LOW", "L"}, {"NONE", "L"}};
258
259 auto it = priorityMap.find(phalPriority);
260 if (it == priorityMap.end())
261 {
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000262 log<level::ERR>(std::format("Unsupported phal priority({}) is given "
Brad Bishopf6783cd2020-10-27 19:25:09 -0400263 "to get pel priority format",
264 phalPriority)
265 .c_str());
266 return "H";
267 }
268
269 return it->second;
270}
271
Jayanth Othayoth69708fb2022-03-22 04:49:01 -0500272/**
273 * @brief Helper function to create PEL for non functional boot
274 * processor related failure.
275 * This function adds the BMC code callout as priority 1 to fix
276 * devtree related software issue. Incase the issue still persist
277 * after reboot recommend to replacing the primary processor.
278 */
279void processNonFunctionalBootProc()
280{
281 json jsonCalloutDataList;
282 json jsonProcedCallout;
283 // Add BMC code callout
284 jsonProcedCallout["Procedure"] = "BMC0001";
285 jsonProcedCallout["Priority"] = "H";
286 jsonCalloutDataList.emplace_back(std::move(jsonProcedCallout));
287
288 // get primary processor
289 struct pdbg_target* procTarget;
290 pdbg_for_each_class_target("proc", procTarget)
291 {
292 if (openpower::phal::isPrimaryProc(procTarget))
293 break;
294 procTarget = nullptr;
295 }
296 // check valid primary processor is available
297 if (procTarget == nullptr)
298 {
299 log<level::ERR>(
300 "processNonFunctionalBootProc: fail to get primary processor");
301 }
302 else
303 {
304 try
305 {
306 ATTR_LOCATION_CODE_Type locationCode = {'\0'};
307 // Get location code information
308 openpower::phal::pdbg::getLocationCode(procTarget, locationCode);
309 json jsonProcCallout;
310 jsonProcCallout["LocationCode"] = locationCode;
311 jsonProcCallout["Deconfigured"] = false;
312 jsonProcCallout["Guarded"] = false;
313 jsonProcCallout["Priority"] = "M";
314 jsonCalloutDataList.emplace_back(std::move(jsonProcCallout));
315 }
316 catch (const std::exception& e)
317 {
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000318 log<level::ERR>(std::format("getLocationCode({}): Exception({})",
Jayanth Othayoth69708fb2022-03-22 04:49:01 -0500319 pdbg_target_path(procTarget), e.what())
320 .c_str());
321 }
322 }
323 // Adding collected phal logs into PEL additional data
324 FFDCData pelAdditionalData;
325 for_each(
326 traceLog.begin(), traceLog.end(),
327 [&pelAdditionalData](std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400328 pelAdditionalData.emplace_back(ele.first, ele.second);
329 });
Jayanth Othayoth69708fb2022-03-22 04:49:01 -0500330 openpower::pel::createErrorPEL(
331 "org.open_power.PHAL.Error.NonFunctionalBootProc", jsonCalloutDataList,
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500332 pelAdditionalData, Severity::Error);
Jayanth Othayoth69708fb2022-03-22 04:49:01 -0500333 // reset trace log and exit
334 reset();
335}
336
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500337/**
338 * @brief processClockInfoErrorHelper
339 *
340 * Creates informational PEL for spare clock failure
341 *
342 * @param[in] ffdc - FFDC data capturd by the HWP
343 * @param[in] ffdc_prefix - prefix string for logging the data.
344 */
345void processClockInfoErrorHelper(FFDC* ffdc, const std::string& ffdc_prefix)
346{
347 try
348 {
349 log<level::INFO>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000350 std::format("processClockInfoErrorHelper: FFDC Message[{}]",
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500351 ffdc->message)
352 .c_str());
353
354 // To store callouts details in json format as per pel expectation.
355 json jsonCalloutDataList;
356 jsonCalloutDataList = json::array();
357
358 // To store phal trace and other additional data about ffdc.
359 FFDCData pelAdditionalData;
360
361 std::string keyWithPrefix(ffdc_prefix + "RC");
362 // Adding hardware procedures return code details
363 pelAdditionalData.emplace_back(keyWithPrefix, ffdc->hwp_errorinfo.rc);
364 keyWithPrefix = ffdc_prefix + "RC_DESC";
365 pelAdditionalData.emplace_back(keyWithPrefix,
366 ffdc->hwp_errorinfo.rc_desc);
367
368 // Adding hardware procedures required ffdc data for debug
369 for_each(ffdc->hwp_errorinfo.ffdcs_data.begin(),
370 ffdc->hwp_errorinfo.ffdcs_data.end(),
371 [&pelAdditionalData, &ffdc_prefix](
372 std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400373 std::string keyWithPrefix(ffdc_prefix + "FFDC_");
374 keyWithPrefix.append(ele.first);
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500375
Patrick Williams1e43be02024-08-16 15:20:32 -0400376 pelAdditionalData.emplace_back(keyWithPrefix, ele.second);
377 });
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500378 // get clock position information
379 auto clk_pos = 0xFF; // Invalid position.
380 for (auto& hwCallout : ffdc->hwp_errorinfo.hwcallouts)
381 {
382 if ((hwCallout.hwid == "PROC_REF_CLOCK") ||
383 (hwCallout.hwid == "PCI_REF_CLOCK"))
384 {
385 clk_pos = hwCallout.clkPos;
386 break;
387 }
388 }
389
390 // Adding CDG (Only deconfigure) targets details
391 for_each(ffdc->hwp_errorinfo.cdg_targets.begin(),
392 ffdc->hwp_errorinfo.cdg_targets.end(),
393 [&pelAdditionalData, &jsonCalloutDataList,
394 clk_pos](const CDG_Target& cdg_tgt) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400395 json jsonCalloutData;
396 std::string pelPriority = "L";
397 jsonCalloutData["Priority"] = pelPriority; // Not used
398 jsonCalloutData["SymbolicFRU"] =
399 "REFCLK" + std::to_string(clk_pos);
400 jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
401 jsonCalloutData["EntityPath"] = cdg_tgt.target_entity_path;
402 jsonCalloutDataList.emplace_back(jsonCalloutData);
403 });
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500404
405 // Adding collected phal logs into PEL additional data
406 for_each(traceLog.begin(), traceLog.end(),
407 [&pelAdditionalData](
408 std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400409 pelAdditionalData.emplace_back(ele.first, ele.second);
410 });
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500411
412 openpower::pel::createErrorPEL("org.open_power.PHAL.Error.SpareClock",
413 jsonCalloutDataList, pelAdditionalData,
414 Severity::Informational);
415 }
416 catch (const std::exception& ex)
417 {
418 reset();
419 throw ex;
420 }
421 reset();
422}
423
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500424void processIplErrorCallback(const ipl_error_info& errInfo)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400425{
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500426 log<level::INFO>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000427 std::format("processIplErrorCallback: Error type({})",
ojayanthcb23cb22023-06-08 07:13:37 -0500428 static_cast<std::underlying_type<ipl_error_type>::type>(
429 errInfo.type))
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500430 .c_str());
431
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600432 switch (errInfo.type)
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500433 {
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600434 case IPL_ERR_OK:
435 // reset trace log and exit
436 reset();
437 break;
438 case IPL_ERR_SBE_BOOT:
439 case IPL_ERR_SBE_CHIPOP:
440 // handle SBE related failures.
441 processSbeBootError();
442 break;
443 case IPL_ERR_HWP:
444 // Handle hwp failure
445 processBootError(false);
446 break;
447 case IPL_ERR_PLAT:
448 processPlatBootError(errInfo);
449 break;
Jayanth Othayoth69708fb2022-03-22 04:49:01 -0500450 case IPL_ERR_PRI_PROC_NON_FUNC:
451 // Handle non functional boot processor error.
452 processNonFunctionalBootProc();
453 break;
deepakala-k9f351b02022-10-05 09:03:57 -0500454 case IPL_ERR_GUARD_PARTITION_ACCESS:
455 processGuardPartitionAccessError();
456 break;
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600457 default:
458 createPEL("org.open_power.PHAL.Error.Boot");
459 // reset trace log and exit
460 reset();
461 break;
Jayanth Othayothfaaef2a2021-10-08 06:49:36 -0500462 }
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500463}
464
rajerpp1db924722021-11-30 11:00:05 -0600465/**
466 * @brief addPlanarCallout
467 *
468 * This function will add a json for planar callout in the input json list.
469 * The caller can pass this json list into createErrorPEL to apply the callout.
470 *
471 * @param[in,out] jsonCalloutDataList - json list where callout json will be
472 * emplaced
473 * @param[in] priority - string indicating priority.
474 */
475static void addPlanarCallout(json& jsonCalloutDataList,
476 const std::string& priority)
477{
478 json jsonCalloutData;
479
480 // Inventory path for planar
481 jsonCalloutData["InventoryPath"] =
482 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
483 jsonCalloutData["Deconfigured"] = false;
484 jsonCalloutData["Guarded"] = false;
485 jsonCalloutData["Priority"] = priority;
486
487 jsonCalloutDataList.emplace_back(jsonCalloutData);
488}
489
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500490/**
491 * @brief processPoweroffError
492 *
493 * Creates informational PEL for the PLAT/HWP error occured during poweroff
494 *
495 * Not adding callouts from FFDC as the hardware errors in the poweroff path
496 * should be non-visible. so that we don't throw out extraneous callouts for
497 * power errors or because the CEC is just not in an expected state.
498 *
499 * @param[in] ffdc - FFDC data capturd by the HWP
500 * @param[in] ffdc_prefix - prefix string for logging the data.
501 */
502
503void processPoweroffError(FFDC* ffdc, const std::string& ffdc_prefix)
504{
505 try
506 {
507 log<level::INFO>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000508 std::format("processPoweroffError: Message[{}]", ffdc->message)
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500509 .c_str());
510
511 // To store phal trace and other additional data about ffdc.
512 FFDCData pelAdditionalData;
513
514 if (ffdc->ffdc_type == FFDC_TYPE_HWP)
515 {
516 std::string keyWithPrefix(ffdc_prefix + "RC");
517 // Adding hardware procedures return code details
518 pelAdditionalData.emplace_back(keyWithPrefix,
519 ffdc->hwp_errorinfo.rc);
520 keyWithPrefix = ffdc_prefix + "RC_DESC";
521 pelAdditionalData.emplace_back(keyWithPrefix,
522 ffdc->hwp_errorinfo.rc_desc);
523 }
524 else if ((ffdc->ffdc_type != FFDC_TYPE_NONE) &&
525 (ffdc->ffdc_type != FFDC_TYPE_UNSUPPORTED))
526 {
527 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000528 std::format("Unsupported phal FFDC type to create PEL. "
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500529 "MSG: {}",
530 ffdc->message)
531 .c_str());
532 }
533
534 // Adding collected phal logs into PEL additional data
535 for_each(traceLog.begin(), traceLog.end(),
536 [&pelAdditionalData](
537 std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400538 pelAdditionalData.emplace_back(ele.first, ele.second);
539 });
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500540
541 openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot", {},
542 pelAdditionalData,
543 Severity::Informational);
544 }
545 catch (const std::exception& ex)
546 {
547 reset();
548 throw ex;
549 }
550 reset();
551}
552
rajerpp1db924722021-11-30 11:00:05 -0600553void processBootErrorHelper(FFDC* ffdc, const std::string& ffdc_prefix)
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500554{
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600555 log<level::INFO>("processBootErrorHelper ");
Brad Bishopf6783cd2020-10-27 19:25:09 -0400556 try
557 {
Ramesh Iyyar3af83eb2020-11-19 23:11:38 -0600558 log<level::INFO>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000559 std::format("PHAL FFDC: Return Message[{}]", ffdc->message)
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600560 .c_str());
Brad Bishopf6783cd2020-10-27 19:25:09 -0400561
Jayanth Othayothd8be1eb2022-06-28 07:33:06 -0500562 // Special handling for spare clock related errors.
563 if (ffdc->ffdc_type == FFDC_TYPE_SPARE_CLOCK_INFO)
564 {
565 processClockInfoErrorHelper(ffdc, ffdc_prefix);
566 return;
567 }
Brad Bishopf6783cd2020-10-27 19:25:09 -0400568 // To store callouts details in json format as per pel expectation.
569 json jsonCalloutDataList;
570 jsonCalloutDataList = json::array();
571
572 // To store phal trace and other additional data about ffdc.
573 FFDCData pelAdditionalData;
574
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600575 if (ffdc->ffdc_type == FFDC_TYPE_HWP)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400576 {
rajerpp1db924722021-11-30 11:00:05 -0600577 std::string keyWithPrefix(ffdc_prefix + "RC");
Brad Bishopf6783cd2020-10-27 19:25:09 -0400578 // Adding hardware procedures return code details
rajerpp1db924722021-11-30 11:00:05 -0600579 pelAdditionalData.emplace_back(keyWithPrefix,
580 ffdc->hwp_errorinfo.rc);
581 keyWithPrefix = ffdc_prefix + "RC_DESC";
582 pelAdditionalData.emplace_back(keyWithPrefix,
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600583 ffdc->hwp_errorinfo.rc_desc);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400584
585 // Adding hardware procedures required ffdc data for debug
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600586 for_each(ffdc->hwp_errorinfo.ffdcs_data.begin(),
587 ffdc->hwp_errorinfo.ffdcs_data.end(),
rajerpp1db924722021-11-30 11:00:05 -0600588 [&pelAdditionalData, &ffdc_prefix](
Brad Bishopf6783cd2020-10-27 19:25:09 -0400589 std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400590 std::string keyWithPrefix(ffdc_prefix + "FFDC_");
591 keyWithPrefix.append(ele.first);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400592
Patrick Williams1e43be02024-08-16 15:20:32 -0400593 pelAdditionalData.emplace_back(keyWithPrefix,
594 ele.second);
595 });
Brad Bishopf6783cd2020-10-27 19:25:09 -0400596
597 // Adding hardware callout details
598 int calloutCount = 0;
Patrick Williams1e43be02024-08-16 15:20:32 -0400599 for_each(
600 ffdc->hwp_errorinfo.hwcallouts.begin(),
601 ffdc->hwp_errorinfo.hwcallouts.end(),
602 [&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
603 &ffdc_prefix](const HWCallout& hwCallout) -> void {
604 calloutCount++;
605 std::stringstream keyPrefix;
606 keyPrefix << ffdc_prefix << "HW_CO_" << std::setfill('0')
607 << std::setw(2) << calloutCount << "_";
Brad Bishopf6783cd2020-10-27 19:25:09 -0400608
Patrick Williams1e43be02024-08-16 15:20:32 -0400609 pelAdditionalData.emplace_back(
610 std::string(keyPrefix.str()).append("HW_ID"),
611 hwCallout.hwid);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400612
Patrick Williams1e43be02024-08-16 15:20:32 -0400613 pelAdditionalData.emplace_back(
614 std::string(keyPrefix.str()).append("PRIORITY"),
615 hwCallout.callout_priority);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400616
Patrick Williams1e43be02024-08-16 15:20:32 -0400617 // Log target details only if entity path is
618 // available. For example target entity path will not
619 // be available for non-hwp clock failure.
620 if (!hwCallout.target_entity_path.empty())
621 {
622 phal::TargetInfo targetInfo;
623 phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
624 targetInfo);
625
626 std::string locationCode =
627 std::string(targetInfo.locationCode);
628 pelAdditionalData.emplace_back(
629 std::string(keyPrefix.str()).append("LOC_CODE"),
630 locationCode);
631
632 std::string physPath =
633 std::string(targetInfo.physDevPath);
634 pelAdditionalData.emplace_back(
635 std::string(keyPrefix.str()).append("PHYS_PATH"),
636 physPath);
637 }
638
639 pelAdditionalData.emplace_back(
640 std::string(keyPrefix.str()).append("CLK_POS"),
641 std::to_string(hwCallout.clkPos));
642
643 pelAdditionalData.emplace_back(
644 std::string(keyPrefix.str()).append("CALLOUT_PLANAR"),
645 (hwCallout.isPlanarCallout == true ? "true" : "false"));
646
647 std::string pelPriority =
648 getPelPriority(hwCallout.callout_priority);
649
650 if (hwCallout.isPlanarCallout)
651 {
652 addPlanarCallout(jsonCalloutDataList, pelPriority);
653 }
654 });
655
656 // Adding CDG (callout, deconfigure and guard) targets details
657 calloutCount = 0;
658 for_each(
659 ffdc->hwp_errorinfo.cdg_targets.begin(),
660 ffdc->hwp_errorinfo.cdg_targets.end(),
661 [&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
662 &ffdc_prefix](const CDG_Target& cdg_tgt) -> void {
663 calloutCount++;
664 std::stringstream keyPrefix;
665 keyPrefix << ffdc_prefix << "CDG_TGT_" << std::setfill('0')
666 << std::setw(2) << calloutCount << "_";
667
rajerpp1db924722021-11-30 11:00:05 -0600668 phal::TargetInfo targetInfo;
Patrick Williams1e43be02024-08-16 15:20:32 -0400669 targetInfo.deconfigure = cdg_tgt.deconfigure;
670
671 phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path,
rajerpp1db924722021-11-30 11:00:05 -0600672 targetInfo);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400673
rajerpp1db924722021-11-30 11:00:05 -0600674 std::string locationCode =
675 std::string(targetInfo.locationCode);
676 pelAdditionalData.emplace_back(
677 std::string(keyPrefix.str()).append("LOC_CODE"),
678 locationCode);
679 std::string physPath = std::string(targetInfo.physDevPath);
680 pelAdditionalData.emplace_back(
681 std::string(keyPrefix.str()).append("PHYS_PATH"),
682 physPath);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400683
Patrick Williams1e43be02024-08-16 15:20:32 -0400684 pelAdditionalData.emplace_back(
685 std::string(keyPrefix.str()).append("CO_REQ"),
686 (cdg_tgt.callout == true ? "true" : "false"));
Brad Bishopf6783cd2020-10-27 19:25:09 -0400687
Patrick Williams1e43be02024-08-16 15:20:32 -0400688 pelAdditionalData.emplace_back(
689 std::string(keyPrefix.str()).append("CO_PRIORITY"),
690 cdg_tgt.callout_priority);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400691
Patrick Williams1e43be02024-08-16 15:20:32 -0400692 pelAdditionalData.emplace_back(
693 std::string(keyPrefix.str()).append("DECONF_REQ"),
694 (cdg_tgt.deconfigure == true ? "true" : "false"));
Brad Bishopf6783cd2020-10-27 19:25:09 -0400695
Patrick Williams1e43be02024-08-16 15:20:32 -0400696 pelAdditionalData.emplace_back(
697 std::string(keyPrefix.str()).append("GUARD_REQ"),
698 (cdg_tgt.guard == true ? "true" : "false"));
Brad Bishopf6783cd2020-10-27 19:25:09 -0400699
Patrick Williams1e43be02024-08-16 15:20:32 -0400700 pelAdditionalData.emplace_back(
701 std::string(keyPrefix.str()).append("GUARD_TYPE"),
702 cdg_tgt.guard_type);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400703
Patrick Williams1e43be02024-08-16 15:20:32 -0400704 json jsonCalloutData;
705 jsonCalloutData["LocationCode"] = locationCode;
706 std::string pelPriority =
707 getPelPriority(cdg_tgt.callout_priority);
708 jsonCalloutData["Priority"] = pelPriority;
Brad Bishopf6783cd2020-10-27 19:25:09 -0400709
Patrick Williams1e43be02024-08-16 15:20:32 -0400710 if (targetInfo.mruId != 0)
711 {
712 jsonCalloutData["MRUs"] = json::array({
713 {{"ID", targetInfo.mruId},
714 {"Priority", pelPriority}},
715 });
716 }
717 jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
718 jsonCalloutData["Guarded"] = cdg_tgt.guard;
719 jsonCalloutData["GuardType"] = cdg_tgt.guard_type;
720 jsonCalloutData["EntityPath"] = cdg_tgt.target_entity_path;
Brad Bishopf6783cd2020-10-27 19:25:09 -0400721
Patrick Williams1e43be02024-08-16 15:20:32 -0400722 jsonCalloutDataList.emplace_back(jsonCalloutData);
723 });
Jayanth Othayoth0ac7c382021-11-15 05:43:24 -0600724 // Adding procedure callout
725 calloutCount = 0;
726 for_each(
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600727 ffdc->hwp_errorinfo.procedures_callout.begin(),
728 ffdc->hwp_errorinfo.procedures_callout.end(),
rajerpp1db924722021-11-30 11:00:05 -0600729 [&pelAdditionalData, &calloutCount, &jsonCalloutDataList,
730 &ffdc_prefix](const ProcedureCallout& procCallout) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400731 calloutCount++;
732 std::stringstream keyPrefix;
733 keyPrefix << ffdc_prefix << "PROC_CO_" << std::setfill('0')
734 << std::setw(2) << calloutCount << "_";
Jayanth Othayoth0ac7c382021-11-15 05:43:24 -0600735
Patrick Williams1e43be02024-08-16 15:20:32 -0400736 pelAdditionalData.emplace_back(
737 std::string(keyPrefix.str()).append("PRIORITY"),
738 procCallout.callout_priority);
Jayanth Othayoth0ac7c382021-11-15 05:43:24 -0600739
Patrick Williams1e43be02024-08-16 15:20:32 -0400740 pelAdditionalData.emplace_back(
741 std::string(keyPrefix.str()).append("MAINT_PROCEDURE"),
742 procCallout.proc_callout);
Jayanth Othayoth0ac7c382021-11-15 05:43:24 -0600743
Patrick Williams1e43be02024-08-16 15:20:32 -0400744 json jsonCalloutData;
745 jsonCalloutData["Procedure"] = procCallout.proc_callout;
746 std::string pelPriority =
747 getPelPriority(procCallout.callout_priority);
748 jsonCalloutData["Priority"] = pelPriority;
749 jsonCalloutDataList.emplace_back(jsonCalloutData);
750 });
Brad Bishopf6783cd2020-10-27 19:25:09 -0400751 }
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600752 else if ((ffdc->ffdc_type != FFDC_TYPE_NONE) &&
753 (ffdc->ffdc_type != FFDC_TYPE_UNSUPPORTED))
Brad Bishopf6783cd2020-10-27 19:25:09 -0400754 {
755 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000756 std::format("Unsupported phal FFDC type to create PEL. "
Brad Bishopf6783cd2020-10-27 19:25:09 -0400757 "MSG: {}",
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600758 ffdc->message)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400759 .c_str());
760 }
761
762 // Adding collected phal logs into PEL additional data
763 for_each(traceLog.begin(), traceLog.end(),
764 [&pelAdditionalData](
765 std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400766 pelAdditionalData.emplace_back(ele.first, ele.second);
767 });
Brad Bishopf6783cd2020-10-27 19:25:09 -0400768
769 // TODO: #ibm-openbmc/dev/issues/2595 : Once enabled this support,
770 // callout details is not required to sort in H,M and L orders which
771 // are expected by pel because, pel will take care for sorting callouts
772 // based on priority so, now adding support to send callout in order
773 // i.e High -> Medium -> Low.
Patrick Williams915b38f2023-10-20 11:18:55 -0500774 std::sort(jsonCalloutDataList.begin(), jsonCalloutDataList.end(),
775 [](const json& aEle, const json& bEle) -> bool {
Patrick Williams1e43be02024-08-16 15:20:32 -0400776 // Considering b element having higher priority than a
777 // element or Both element will be same priorty (to keep
778 // same order which are given by phal when two callouts
779 // are having same priority)
780 if (((aEle["Priority"] == "M") &&
781 (bEle["Priority"] == "H")) ||
782 ((aEle["Priority"] == "L") &&
783 ((bEle["Priority"] == "H") ||
784 (bEle["Priority"] == "M"))) ||
785 (aEle["Priority"] == bEle["Priority"]))
786 {
787 return false;
788 }
Brad Bishopf6783cd2020-10-27 19:25:09 -0400789
Patrick Williams1e43be02024-08-16 15:20:32 -0400790 // Considering a element having higher priority than b
791 // element
792 return true;
793 });
Jayanth Othayoth8fe9ff92021-11-14 09:15:59 -0600794 openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot",
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500795 jsonCalloutDataList, pelAdditionalData,
796 Severity::Error);
Brad Bishopf6783cd2020-10-27 19:25:09 -0400797 }
Patrick Williams1a9a5a62021-10-06 13:05:06 -0500798 catch (const std::exception& ex)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400799 {
800 reset();
801 throw ex;
802 }
803 reset();
804}
805
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600806void processPlatBootError(const ipl_error_info& errInfo)
807{
808 log<level::INFO>("processPlatBootError ");
809
810 // Collecting ffdc details from phal
811 FFDC* ffdc = reinterpret_cast<FFDC*>(errInfo.private_data);
812 try
813 {
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500814 if (util::isHostPoweringOff())
815 {
816 processPoweroffError(ffdc, "PLAT_");
817 }
818 else
819 {
820 processBootErrorHelper(ffdc, "PLAT_");
821 }
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600822 }
823 catch (const std::exception& ex)
824 {
825 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000826 std::format("processPlatBootError: exception({})", ex.what())
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600827 .c_str());
828 throw ex;
829 }
830}
831
832void processBootError(bool status)
833{
834 log<level::INFO>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000835 std::format("processBootError: status({})", status).c_str());
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600836
837 try
838 {
839 // return If no failure during hwp execution
840 if (status)
841 return;
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600842 // Collecting ffdc details from phal
843 FFDC ffdc;
844 libekb_get_ffdc(ffdc);
845
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500846 if (util::isHostPoweringOff())
847 {
848 processPoweroffError(&ffdc, "HWP_");
849 }
850 else
851 {
852 processBootErrorHelper(&ffdc, "HWP_");
853 }
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600854 }
855 catch (const std::exception& ex)
856 {
857 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000858 std::format("processBootError: exception({})", ex.what()).c_str());
Marri Devender Rao381c3e32021-12-01 06:27:55 -0600859 throw ex;
860 }
861}
862
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500863void processSbeBootError()
864{
865 log<level::INFO>("processSbeBootError : Entered ");
866
867 using namespace openpower::phal::sbe;
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500868
869 // To store phal trace and other additional data about ffdc.
870 FFDCData pelAdditionalData;
871
872 // Adding collected phal logs into PEL additional data
873 for_each(
874 traceLog.begin(), traceLog.end(),
875 [&pelAdditionalData](std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400876 pelAdditionalData.emplace_back(ele.first, ele.second);
877 });
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500878
879 // reset the trace log and counter
880 reset();
881
882 // get primary processor to collect FFDC/Dump information.
883 struct pdbg_target* procTarget;
884 pdbg_for_each_class_target("proc", procTarget)
885 {
886 if (openpower::phal::isPrimaryProc(procTarget))
887 break;
888 procTarget = nullptr;
889 }
890 // check valid primary processor is available
891 if (procTarget == nullptr)
892 {
893 log<level::ERR>("processSbeBootError: fail to get primary processor");
Jayanth Othayoth0a516de2021-11-14 09:59:06 -0600894 // Add BMC code callout and create PEL
895 json jsonCalloutDataList;
896 jsonCalloutDataList = json::array();
897 json jsonCalloutData;
898 jsonCalloutData["Procedure"] = "BMC0001";
899 jsonCalloutData["Priority"] = "H";
900 jsonCalloutDataList.emplace_back(jsonCalloutData);
901 openpower::pel::createErrorPEL(
902 "org.open_power.Processor.Error.SbeBootFailure",
Marri Devender Rao4d5b5bf2022-05-23 09:23:31 -0500903 jsonCalloutDataList, {}, Severity::Error);
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500904 return;
905 }
906 // SBE error object.
907 sbeError_t sbeError;
908 bool dumpIsRequired = false;
909
910 try
911 {
912 // Capture FFDC information on primary processor
913 sbeError = captureFFDC(procTarget);
914 }
Jayanth Othayothfaaef2a2021-10-08 06:49:36 -0500915 catch (const phalError_t& phalError)
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500916 {
917 // Fail to collect FFDC information , trigger Dump
918 log<level::ERR>(
Jayanth Othayothe0dd7af2023-09-13 09:03:30 +0000919 std::format("captureFFDC: Exception({})", phalError.what())
Jayanth Othayothfaaef2a2021-10-08 06:49:36 -0500920 .c_str());
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500921 dumpIsRequired = true;
922 }
923
Jayanth Othayoth006641e2021-10-07 06:56:24 -0500924 std::string event;
925
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500926 if ((sbeError.errType() == SBE_FFDC_NO_DATA) ||
927 (sbeError.errType() == SBE_CMD_TIMEOUT) || (dumpIsRequired))
928 {
Jayanth Othayoth006641e2021-10-07 06:56:24 -0500929 event = "org.open_power.Processor.Error.SbeBootTimeout";
930 dumpIsRequired = true;
931 }
932 else
933 {
934 event = "org.open_power.Processor.Error.SbeBootFailure";
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500935 }
936 // SRC6 : [0:15] chip position
Jayanth Othayoth006641e2021-10-07 06:56:24 -0500937 uint32_t index = pdbg_target_index(procTarget);
938 pelAdditionalData.emplace_back("SRC6", std::to_string(index << 16));
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500939 // Create SBE Error with FFDC data.
Patrick Williams1e43be02024-08-16 15:20:32 -0400940 auto logId =
941 createSbeErrorPEL(event, sbeError, pelAdditionalData, procTarget);
Jayanth Othayoth006641e2021-10-07 06:56:24 -0500942
943 if (dumpIsRequired)
944 {
945 using namespace openpower::phal::dump;
946 DumpParameters dumpParameters = {logId, index, SBE_DUMP_TIMEOUT,
947 DumpType::SBE};
948 try
949 {
950 requestDump(dumpParameters);
951 }
952 catch (const std::runtime_error& e)
953 {
954 // Allowing call back to handle the error gracefully.
955 log<level::ERR>("Dump collection failed");
956 // TODO revist error handling.
957 }
958 }
Jayanth Othayoth4079f092021-09-20 07:36:54 -0500959}
960
deepakala-k9f351b02022-10-05 09:03:57 -0500961void processGuardPartitionAccessError()
962{
963 // Adding collected phal logs into PEL additional data
964 FFDCData pelAdditionalData;
965
966 for_each(
967 traceLog.begin(), traceLog.end(),
968 [&pelAdditionalData](std::pair<std::string, std::string>& ele) -> void {
Patrick Williams1e43be02024-08-16 15:20:32 -0400969 pelAdditionalData.emplace_back(ele.first, ele.second);
970 });
deepakala-k9f351b02022-10-05 09:03:57 -0500971
972 openpower::pel::createPEL("org.open_power.PHAL.Error.GuardPartitionAccess",
973 pelAdditionalData);
974}
975
Brad Bishopf6783cd2020-10-27 19:25:09 -0400976void reset()
977{
978 // reset the trace log and counter
979 traceLog.clear();
980 counter = 0;
981}
982
Brad Bishop63508a72020-10-27 18:55:01 -0400983void pDBGLogTraceCallbackHelper(int, const char* fmt, va_list ap)
Brad Bishopf6783cd2020-10-27 19:25:09 -0400984{
985 processLogTraceCallback(NULL, fmt, ap);
986}
987} // namespace detail
988
989static inline uint8_t getLogLevelFromEnv(const char* env, const uint8_t dValue)
990{
991 auto logLevel = dValue;
992 try
993 {
994 if (const char* env_p = std::getenv(env))
995 {
996 logLevel = std::stoi(env_p);
997 }
998 }
Patrick Williams1a9a5a62021-10-06 13:05:06 -0500999 catch (const std::exception& e)
Brad Bishopf6783cd2020-10-27 19:25:09 -04001000 {
1001 log<level::ERR>(("Conversion Failure"), entry("ENVIRONMENT=%s", env),
1002 entry("EXCEPTION=%s", e.what()));
1003 }
1004 return logLevel;
1005}
1006
1007void addBootErrorCallbacks()
1008{
1009 // Get individual phal repos log level from environment variable
1010 // and update the log level.
1011 pdbg_set_loglevel(getLogLevelFromEnv("PDBG_LOG", PDBG_INFO));
1012 libekb_set_loglevel(getLogLevelFromEnv("LIBEKB_LOG", LIBEKB_LOG_IMP));
1013 ipl_set_loglevel(getLogLevelFromEnv("IPL_LOG", IPL_INFO));
1014
1015 // add callback for debug traces
1016 pdbg_set_logfunc(detail::pDBGLogTraceCallbackHelper);
1017 libekb_set_logfunc(detail::processLogTraceCallback, NULL);
1018 ipl_set_logfunc(detail::processLogTraceCallback, NULL);
1019
1020 // add callback for ipl failures
Jayanth Othayoth2b211702021-09-06 05:14:23 -05001021 ipl_set_error_callback_func(detail::processIplErrorCallback);
Brad Bishopf6783cd2020-10-27 19:25:09 -04001022}
1023
1024} // namespace pel
1025} // namespace openpower