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