blob: cecd399f212506b8e0933e8343732680307f494a [file] [log] [blame]
Ramesh Iyyarc98bab52020-04-16 04:04:29 -05001extern "C" {
2#include <libpdbg.h>
3}
Marri Devender Rao78479602020-01-06 03:45:11 -06004
5#include "create_pel.hpp"
Ramesh Iyyarc98bab52020-04-16 04:04:29 -05006#include "phal_error.hpp"
Marri Devender Rao78479602020-01-06 03:45:11 -06007
8#include <libekb.H>
9#include <libipl.H>
10
11#include <iomanip>
12#include <phosphor-logging/elog.hpp>
13#include <sstream>
14
15namespace openpower
16{
17namespace pel
18{
19using namespace phosphor::logging;
20
21namespace detail
22{
23
24// keys need to be unique so using counter value to generate unique key
25static int counter = 0;
26
27// list of debug traces
28static std::vector<std::pair<std::string, std::string>> traceLog;
29
30void processLogTraceCallback(void* private_data, const char* fmt, va_list ap)
31{
32 va_list vap;
33 va_copy(vap, ap);
34 std::vector<char> log(1 + std::vsnprintf(nullptr, 0, fmt, ap));
35 std::vsnprintf(log.data(), log.size(), fmt, vap);
36 va_end(vap);
37 std::string logstr(log.begin(), log.end());
38
39 // ignore stray characters in log traces coming from ekb
40 // example: "\n", which are good for print to screen
41 if (logstr.length() < 5)
42 {
43 return;
44 }
45
46 char timeBuf[80];
47 time_t t = time(0);
48 tm myTm{};
49 gmtime_r(&t, &myTm);
50 strftime(timeBuf, 80, "%Y-%m-%d %H:%M:%S", &myTm);
51
52 // key values need to be unique for PEL
53 // TODO #openbmc/dev/issues/1563
54 // If written to Json no need to worry about unique KEY
55 std::stringstream str;
56 str << std::setfill('0');
57 str << "LOG" << std::setw(3) << counter;
58 str << " " << timeBuf;
59 traceLog.emplace_back(std::make_pair(str.str(), std::move(logstr)));
60 counter++;
61}
62
63void processBootErrorCallback(bool status)
64{
65 log<level::INFO>("processBootCallback ", entry("STATUS=%d", status));
66 try
67 {
68 // If failure in hwp execution
69 if (!status)
70 {
71 FFDCData ffdc = libekb_get_ffdc();
72 ffdc.insert(ffdc.end(), traceLog.begin(), traceLog.end());
73 openpower::pel::createBootErrorPEL(ffdc);
74 }
75 }
76 catch (std::exception& ex)
77 {
78 reset();
79 throw ex;
80 }
81 reset();
82}
83
84void reset()
85{
86 // reset the trace log and counter
87 traceLog.clear();
88 counter = 0;
89}
Ramesh Iyyarc98bab52020-04-16 04:04:29 -050090
91void pDBGLogTraceCallbackHelper(int log_level, const char* fmt, va_list ap)
92{
93 processLogTraceCallback(NULL, fmt, ap);
94}
Marri Devender Rao78479602020-01-06 03:45:11 -060095} // namespace detail
96
97void addBootErrorCallbacks()
98{
99 // set log level to info
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500100 pdbg_set_loglevel(PDBG_INFO);
101 libekb_set_loglevel(LIBEKB_LOG_INF);
Marri Devender Rao78479602020-01-06 03:45:11 -0600102 ipl_set_loglevel(IPL_INFO);
103
104 // add callback for debug traces
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500105 pdbg_set_logfunc(detail::pDBGLogTraceCallbackHelper);
106 libekb_set_logfunc(detail::processLogTraceCallback, NULL);
Marri Devender Rao78479602020-01-06 03:45:11 -0600107 ipl_set_logfunc(detail::processLogTraceCallback, NULL);
108
109 // add callback for ipl failures
Jayanth Othayothaefde692020-03-27 07:56:47 -0500110 ipl_set_error_callback_func(detail::processBootErrorCallback);
Marri Devender Rao78479602020-01-06 03:45:11 -0600111}
112} // namespace pel
113} // namespace openpower