1 #include <fmt/format.h>
2 extern "C"
3 {
4 #include <libpdbg.h>
5 #include <libpdbg_sbe.h>
6 }
7 
8 #include <libphal.H>
9 
10 #include <phosphor-logging/log.hpp>
11 #include <watchdog_common.hpp>
12 #include <watchdog_dbus.hpp>
13 #include <watchdog_handler.hpp>
14 #include <watchdog_logging.hpp>
15 
16 namespace watchdog
17 {
18 namespace dump
19 {
20 
21 using namespace phosphor::logging;
22 
23 void triggerHostbootDump(const uint32_t timeout)
24 {
25     constexpr auto HOST_STATE_DIAGNOSTIC_MODE =
26         "obmc-host-diagnostic-mode@0.target";
27     constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";
28 
29     // Put system into diagnostic mode
30     transitionHost(HOST_STATE_DIAGNOSTIC_MODE);
31 
32     eventWatchdogTimeout(timeout);
33 
34     // Put system into quiesce state
35     transitionHost(HOST_STATE_QUIESCE_TGT);
36 }
37 
38 void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout)
39 {
40     using namespace openpower::phal;
41 
42     sbeError_t sbeError;
43     bool dumpIsRequired = false;
44 
45     try
46     {
47         // Capture FFDC information on primary processor
48         sbeError = sbe::captureFFDC(procTarget);
49     }
50     catch (const std::exception& e)
51     {
52         // Failed to collect FFDC information
53         log<level::ERR>(
54             fmt::format("captureFFDC: Exception{}", e.what()).c_str());
55         dumpIsRequired = true;
56     }
57 
58     // event type
59     std::string event;
60     if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) ||
61         (sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired))
62     {
63         log<level::INFO>("No FFDC data");
64         event = "org.open_power.Processor.Error.SbeBootTimeout";
65         dumpIsRequired = true;
66     }
67     else
68     {
69         log<level::ERR>("SBE Boot failure");
70         event = "org.open_power.Processor.Error.SbeBootFailure";
71     }
72 
73     // Additional data
74     std::map<std::string, std::string> additionalData;
75 
76     // SRC6 : [0:15] chip position
77     uint32_t index = pdbg_target_index(procTarget);
78     additionalData.emplace("SRC6", std::to_string(index << 16));
79     additionalData.emplace("SBE_ERR_MSG", sbeError.what());
80 
81     // FFDC
82     auto ffdc = std::vector<FFDCTuple>{};
83     // get SBE ffdc file descriptor
84     auto fd = sbeError.getFd();
85 
86     // Log error with additional ffdc if fd is valid
87     if (fd > 0)
88     {
89         ffdc.push_back(
90             std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
91                                 Create::FFDCFormat::Custom,
92                             static_cast<uint8_t>(0xCB),
93                             static_cast<uint8_t>(0x01), sbeError.getFd()));
94     }
95 
96     auto pelId = createPel(event, additionalData, ffdc);
97 
98     if (dumpIsRequired)
99     {
100         try
101         {
102             using namespace openpower::phal;
103 
104             // Check SBE dump collection allowed
105             bool dumpAllowed = sbe::isDumpAllowed(procTarget);
106             if (!dumpAllowed)
107             {
108                 // Possibly another collection in progress, skip dump collection
109                 log<level::INFO>("Another collection is in progress, skipping "
110                                  "dump collection");
111                 return;
112             }
113         }
114         catch (const std::exception& e)
115         {
116             log<level::ERR>(
117                 fmt::format("Exception {} occurred", e.what()).c_str());
118             return;
119         }
120 
121         DumpParameters dumpParameters;
122         dumpParameters.logId = pelId;
123         dumpParameters.unitId = index;
124         dumpParameters.timeout = timeout;
125         dumpParameters.dumpType = DumpType::SBE;
126 
127         // will not return until dump is complete or timeout
128         requestDump(dumpParameters);
129     }
130 }
131 
132 } // namespace dump
133 } // namespace watchdog
134