xref: /openbmc/openpower-hw-diags/main.cpp (revision 9e4d1906)
1 #include <libpdbg.h>
2 
3 #include <analyzer/analyzer_main.hpp>
4 #include <boost/interprocess/ipc/message_queue.hpp>
5 #include <cli.hpp>
6 #include <listener.hpp>
7 
8 /**
9  * @brief Attention handler application main()
10  *
11  * This is the main interface to the hardware diagnostics application. This
12  * application will either be loaded as a daemon for monitoring the attention
13  * gpio or it will be loaded as an application to analyze hardware and
14  * diagnose hardware error conditions.
15  *
16  *     Usage:
17  *        --analyze:              Analyze the hardware
18  *        --start:                Start the attention handler
19  *        --stop:                 Stop the attention handler
20  *        --all <on|off>:         All attention handling
21  *        --vital <on|off>:       Vital attention handling
22  *        --checkstop <on|off>:   Checkstop attention handling
23  *        --terminate <on|off>:   Terminate Immiediately attention handling
24  *        --breakpoints <on|off>: Breakpoint attention handling
25  *
26  *     Example: openpower-hw-diags --start --vital off
27  *
28  * @return 0 = success
29  */
30 int main(int argc, char* argv[])
31 {
32     int rc = RC_SUCCESS; // assume success
33 
34     using namespace boost::interprocess;
35 
36     if (argc == 1)
37     {
38         printf("openpower-hw-diags <options>\n");
39         printf("options:\n");
40         printf("  --analyze:              Analyze the hardware\n");
41         printf("  --start:                Start the attention handler\n");
42         printf("  --stop:                 Stop the attention handler\n");
43         printf("  --all <on|off>:         All attention handling\n");
44         printf("  --vital <on|off>:       Vital attention handling\n");
45         printf("  --checkstop <on|off>:   Checkstop attention handling\n");
46         printf("  --terminate <on|off>:   Terminate Immediately attention "
47                "handling\n");
48         printf("  --breakpoints <on|off>: Breakpoint attention handling\n");
49     }
50     else
51     {
52         // Pdbg targets should only be initialized once according to
53         // libpdbg documentation. Initializing them here will make sure
54         // they are initialized for the attention handler, invocation of
55         // the analyzer via attention handler and direct invocation of
56         // the analyzer via command line (--analyze).
57 
58         pdbg_targets_init(nullptr); // nullptr == use default fdt
59 
60         // Either analyze (application mode) or daemon mode
61         if (true == getCliOption(argv, argv + argc, "--analyze"))
62         {
63             // Analyze the host hardware.
64             // TODO: At the moment, we'll only do MANUAL analysis (no service
65             //       actions). It may be possible in the future to allow command
66             //       line options to change the analysis type, if needed.
67 
68             attn::DumpParameters dumpParameters;
69             analyzer::analyzeHardware(analyzer::AnalysisType::MANUAL,
70                                       dumpParameters);
71         }
72         // daemon mode
73         else
74         {
75             // Handle pending attentions
76             attn::Config attnConfig;
77             attn::attnHandler(&attnConfig);
78 
79             // assume listener is not running
80             bool listenerStarted = false;
81             bool newListener     = false;
82 
83             pthread_t ptidListener; // handle to listener thread
84 
85             // see if listener is already started
86             listenerStarted = listenerMqExists();
87 
88             // listener is not running so start it
89             if (false == listenerStarted)
90             {
91                 // create listener thread
92                 if (0 ==
93                     pthread_create(&ptidListener, NULL, &threadListener, NULL))
94                 {
95                     listenerStarted = true;
96                     newListener     = true;
97                 }
98                 else
99                 {
100                     rc = 1;
101                 }
102             }
103 
104             // listener was running or just started
105             if (true == listenerStarted)
106             {
107                 // If we created a new listener this instance of
108                 // openpower-hw-diags will become our daemon (it will not exit
109                 // until stopped).
110                 if (true == newListener)
111                 {
112                     bool listenerReady = false;
113 
114                     // It may take some time for the listener to become ready,
115                     // we will wait until the message queue has been created
116                     // before starting to communicate with our daemon.
117                     while (false == listenerReady)
118                     {
119                         usleep(500);
120                         listenerReady = listenerMqExists();
121                     }
122                 }
123 
124                 // send cmd line to listener thread
125                 if (argc != sendCmdLine(argc, argv))
126                 {
127                     rc = 1;
128                 }
129 
130                 // if this is a new listener let it run until "stopped"
131                 if (true == newListener)
132                 {
133                     pthread_join(ptidListener, NULL);
134                 }
135             }
136         }
137     }
138     return rc;
139 }
140