1 #include <config.h>
2 
3 #include <CLI/CLI.hpp>
4 
5 #ifdef WATCHDOG_DUMP_COLLECTION
6 extern "C"
7 {
8 #include <libpdbg.h>
9 #include <libpdbg_sbe.h>
10 }
11 
12 #include <libphal.H>
13 
14 #include <phosphor-logging/lg2.hpp>
15 #include <watchdog/watchdog_common.hpp>
16 #include <watchdog/watchdog_dbus.hpp>
17 #include <watchdog/watchdog_main.hpp>
18 
19 #else
20 #include <org/open_power/Host/Boot/error.hpp>
21 #include <phosphor-logging/elog-errors.hpp>
22 #include <phosphor-logging/elog.hpp>
23 #endif
24 
25 int main(int argc, char* argv[])
26 {
27     CLI::App app{"Hostboot dump collector for watchdog timeout"};
28 
29 #ifdef WATCHDOG_DUMP_COLLECTION
30     constexpr uint32_t dumpTimeout = 1500; // in seconds
31     uint32_t timeout = dumpTimeout;
32     app.add_option("-t,--timeout", timeout,
33                    "Set timeout interval for watchdog timeout in seconds");
34 #endif
35 
36     CLI11_PARSE(app, argc, argv);
37 
38 #ifdef WATCHDOG_DUMP_COLLECTION
39     using namespace watchdog::dump;
40 
41     lg2::info("Host did not respond within watchdog timeout interval");
42     try
43     {
44         using namespace openpower::phal;
45 
46         // Initialize pdbg library, default parameters are used for init()
47         pdbg::init();
48 
49         // Get Primary Proc
50         struct pdbg_target* procTarget = pdbg::getPrimaryProc();
51 
52         // Check Primary IPL done
53         bool primaryIplDone = sbe::isPrimaryIplDone();
54         if (primaryIplDone)
55         {
56             // Collect hostboot dump only if the host is in 'Running' state
57             if (!isHostStateRunning())
58             {
59                 lg2::info(
60                     "CurrentHostState is not in 'Running' state. Dump maybe "
61                     "already occurring, skipping this dump request...");
62                 return EXIT_SUCCESS;
63             }
64 
65             // SBE boot done, Need to collect hostboot dump
66             lg2::info("Handle Hostboot boot failure");
67             triggerHostbootDump(timeout);
68         }
69         else
70         {
71             // SBE boot window, handle SBE boot failure
72             lg2::info("Handle SBE boot failure");
73             handleSbeBootError(procTarget, timeout);
74         }
75     }
76     catch (const std::exception& e)
77     {
78         lg2::error("Exception {ERROR} occurred", "ERROR", e);
79         std::string eventType =
80             "org.open_power.Host.Boot.Error.WatchdogTimedOut";
81         auto ffdc = std::vector<FFDCTuple>{};
82         std::map<std::string, std::string> additionalData;
83 
84         if (!createPel(eventType, additionalData, ffdc))
85         {
86             lg2::error("Failed to create PEL");
87         }
88 
89         return EXIT_SUCCESS;
90     }
91 
92 #else
93     using namespace phosphor::logging;
94     using error =
95         sdbusplus::org::open_power::Host::Boot::Error::WatchdogTimedOut;
96     report<error>();
97 #endif
98 
99     return EXIT_SUCCESS;
100 }
101