xref: /openbmc/openpower-hw-diags/main.cpp (revision f5210bb6)
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 hadrware 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             rc = analyzer::analyzeHardware(); // analyze hardware
64         }
65         // daemon mode
66         else
67         {
68             // Handle pending attentions
69             attn::Config attnConfig;
70             attn::attnHandler(&attnConfig);
71 
72             // assume listener is not running
73             bool listenerStarted = false;
74             bool newListener     = false;
75 
76             pthread_t ptidListener; // handle to listener thread
77 
78             // see if listener is already started
79             listenerStarted = listenerMqExists();
80 
81             // listener is not running so start it
82             if (false == listenerStarted)
83             {
84                 // create listener thread
85                 if (0 ==
86                     pthread_create(&ptidListener, NULL, &threadListener, NULL))
87                 {
88                     listenerStarted = true;
89                     newListener     = true;
90                 }
91                 else
92                 {
93                     rc = 1;
94                 }
95             }
96 
97             // listener was running or just started
98             if (true == listenerStarted)
99             {
100                 // If we created a new listener this instance of
101                 // openpower-hw-diags will become our daemon (it will not exit
102                 // until stopped).
103                 if (true == newListener)
104                 {
105                     bool listenerReady = false;
106 
107                     // It may take some time for the listener to become ready,
108                     // we will wait until the message queue has been created
109                     // before starting to communicate with our daemon.
110                     while (false == listenerReady)
111                     {
112                         usleep(500);
113                         listenerReady = listenerMqExists();
114                     }
115                 }
116 
117                 // send cmd line to listener thread
118                 if (argc != sendCmdLine(argc, argv))
119                 {
120                     rc = 1;
121                 }
122 
123                 // if this is a new listener let it run until "stopped"
124                 if (true == newListener)
125                 {
126                     pthread_join(ptidListener, NULL);
127                 }
128             }
129         }
130     }
131     return rc;
132 }
133