xref: /openbmc/openpower-hw-diags/main.cpp (revision 27dd6368d4e6b1fd03610503356f24eb08a16c02)
187eabc65SBen Tyner #include <libpdbg.h>
287eabc65SBen Tyner 
30205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp>
48c2f8b24SBen Tyner #include <boost/interprocess/ipc/message_queue.hpp>
57212d21dSBen Tyner #include <cli.hpp>
68c2f8b24SBen Tyner #include <listener.hpp>
70205f3b3SBen Tyner 
80205f3b3SBen Tyner /**
90205f3b3SBen Tyner  * @brief Attention handler application main()
100205f3b3SBen Tyner  *
110205f3b3SBen Tyner  * This is the main interface to the hardware diagnostics application. This
120205f3b3SBen Tyner  * application will either be loaded as a daemon for monitoring the attention
130205f3b3SBen Tyner  * gpio or it will be loaded as an application to analyze hardware and
14611b3442SZane Shelley  * diagnose hardware error conditions.
150205f3b3SBen Tyner  *
168c2f8b24SBen Tyner  *     Usage:
178c2f8b24SBen Tyner  *        --analyze:              Analyze the hardware
188c2f8b24SBen Tyner  *        --start:                Start the attention handler
198c2f8b24SBen Tyner  *        --stop:                 Stop the attention handler
208c2f8b24SBen Tyner  *        --all <on|off>:         All attention handling
218c2f8b24SBen Tyner  *        --vital <on|off>:       Vital attention handling
228c2f8b24SBen Tyner  *        --checkstop <on|off>:   Checkstop attention handling
238c2f8b24SBen Tyner  *        --terminate <on|off>:   Terminate Immiediately attention handling
248c2f8b24SBen Tyner  *        --breakpoints <on|off>: Breakpoint attention handling
250205f3b3SBen Tyner  *
268c2f8b24SBen Tyner  *     Example: openpower-hw-diags --start --vital off
270205f3b3SBen Tyner  *
280205f3b3SBen Tyner  * @return 0 = success
290205f3b3SBen Tyner  */
main(int argc,char * argv[])300205f3b3SBen Tyner int main(int argc, char* argv[])
310205f3b3SBen Tyner {
32b1ebfcb1SBen Tyner     int rc = RC_SUCCESS; // assume success
330205f3b3SBen Tyner 
348c2f8b24SBen Tyner     using namespace boost::interprocess;
353fb52e53SBen Tyner 
368c2f8b24SBen Tyner     if (argc == 1)
370205f3b3SBen Tyner     {
388c2f8b24SBen Tyner         printf("openpower-hw-diags <options>\n");
398c2f8b24SBen Tyner         printf("options:\n");
408c2f8b24SBen Tyner         printf("  --analyze:              Analyze the hardware\n");
418c2f8b24SBen Tyner         printf("  --start:                Start the attention handler\n");
428c2f8b24SBen Tyner         printf("  --stop:                 Stop the attention handler\n");
438c2f8b24SBen Tyner         printf("  --all <on|off>:         All attention handling\n");
448c2f8b24SBen Tyner         printf("  --vital <on|off>:       Vital attention handling\n");
458c2f8b24SBen Tyner         printf("  --checkstop <on|off>:   Checkstop attention handling\n");
468c2f8b24SBen Tyner         printf("  --terminate <on|off>:   Terminate Immediately attention "
478c2f8b24SBen Tyner                "handling\n");
488c2f8b24SBen Tyner         printf("  --breakpoints <on|off>: Breakpoint attention handling\n");
490205f3b3SBen Tyner     }
500205f3b3SBen Tyner     else
510205f3b3SBen Tyner     {
5287eabc65SBen Tyner         // Pdbg targets should only be initialized once according to
5387eabc65SBen Tyner         // libpdbg documentation. Initializing them here will make sure
5487eabc65SBen Tyner         // they are initialized for the attention handler, invocation of
5587eabc65SBen Tyner         // the analyzer via attention handler and direct invocation of
5687eabc65SBen Tyner         // the analyzer via command line (--analyze).
5787eabc65SBen Tyner 
5887eabc65SBen Tyner         pdbg_targets_init(nullptr); // nullptr == use default fdt
598c2f8b24SBen Tyner 
608c2f8b24SBen Tyner         // Either analyze (application mode) or daemon mode
618c2f8b24SBen Tyner         if (true == getCliOption(argv, argv + argc, "--analyze"))
620205f3b3SBen Tyner         {
63*ebff0d37SZane Shelley             // Analyze the host hardware.
64*ebff0d37SZane Shelley             // TODO: At the moment, we'll only do MANUAL analysis (no service
65*ebff0d37SZane Shelley             //       actions). It may be possible in the future to allow command
66*ebff0d37SZane Shelley             //       line options to change the analysis type, if needed.
67*ebff0d37SZane Shelley 
68611b3442SZane Shelley             attn::DumpParameters dumpParameters;
69*ebff0d37SZane Shelley             analyzer::analyzeHardware(analyzer::AnalysisType::MANUAL,
70*ebff0d37SZane Shelley                                       dumpParameters);
710205f3b3SBen Tyner         }
728c2f8b24SBen Tyner         // daemon mode
738c2f8b24SBen Tyner         else
748c2f8b24SBen Tyner         {
75d70033a5SBen Tyner             // Handle pending attentions
76d70033a5SBen Tyner             attn::Config attnConfig;
77d70033a5SBen Tyner             attn::attnHandler(&attnConfig);
78d70033a5SBen Tyner 
798c2f8b24SBen Tyner             // assume listener is not running
808c2f8b24SBen Tyner             bool listenerStarted = false;
818c2f8b24SBen Tyner             bool newListener = false;
828c2f8b24SBen Tyner 
838c2f8b24SBen Tyner             pthread_t ptidListener; // handle to listener thread
848c2f8b24SBen Tyner 
858c2f8b24SBen Tyner             // see if listener is already started
868c2f8b24SBen Tyner             listenerStarted = listenerMqExists();
878c2f8b24SBen Tyner 
888c2f8b24SBen Tyner             // listener is not running so start it
898c2f8b24SBen Tyner             if (false == listenerStarted)
908c2f8b24SBen Tyner             {
918c2f8b24SBen Tyner                 // create listener thread
928c2f8b24SBen Tyner                 if (0 ==
938c2f8b24SBen Tyner                     pthread_create(&ptidListener, NULL, &threadListener, NULL))
948c2f8b24SBen Tyner                 {
958c2f8b24SBen Tyner                     listenerStarted = true;
968c2f8b24SBen Tyner                     newListener = true;
978c2f8b24SBen Tyner                 }
988c2f8b24SBen Tyner                 else
998c2f8b24SBen Tyner                 {
1008c2f8b24SBen Tyner                     rc = 1;
1018c2f8b24SBen Tyner                 }
1020205f3b3SBen Tyner             }
1030205f3b3SBen Tyner 
1048c2f8b24SBen Tyner             // listener was running or just started
1058c2f8b24SBen Tyner             if (true == listenerStarted)
1068c2f8b24SBen Tyner             {
1078c2f8b24SBen Tyner                 // If we created a new listener this instance of
1088c2f8b24SBen Tyner                 // openpower-hw-diags will become our daemon (it will not exit
1098c2f8b24SBen Tyner                 // until stopped).
1108c2f8b24SBen Tyner                 if (true == newListener)
1118c2f8b24SBen Tyner                 {
1128c2f8b24SBen Tyner                     bool listenerReady = false;
1138c2f8b24SBen Tyner 
1148c2f8b24SBen Tyner                     // It may take some time for the listener to become ready,
1158c2f8b24SBen Tyner                     // we will wait until the message queue has been created
1168c2f8b24SBen Tyner                     // before starting to communicate with our daemon.
1178c2f8b24SBen Tyner                     while (false == listenerReady)
1188c2f8b24SBen Tyner                     {
1198c2f8b24SBen Tyner                         usleep(500);
1208c2f8b24SBen Tyner                         listenerReady = listenerMqExists();
1218c2f8b24SBen Tyner                     }
1228c2f8b24SBen Tyner                 }
1238c2f8b24SBen Tyner 
1248c2f8b24SBen Tyner                 // send cmd line to listener thread
1258c2f8b24SBen Tyner                 if (argc != sendCmdLine(argc, argv))
1268c2f8b24SBen Tyner                 {
1278c2f8b24SBen Tyner                     rc = 1;
1288c2f8b24SBen Tyner                 }
1298c2f8b24SBen Tyner 
1308c2f8b24SBen Tyner                 // if this is a new listener let it run until "stopped"
1318c2f8b24SBen Tyner                 if (true == newListener)
1328c2f8b24SBen Tyner                 {
1338c2f8b24SBen Tyner                     pthread_join(ptidListener, NULL);
1348c2f8b24SBen Tyner                 }
1358c2f8b24SBen Tyner             }
1368c2f8b24SBen Tyner         }
1378c2f8b24SBen Tyner     }
1380205f3b3SBen Tyner     return rc;
1390205f3b3SBen Tyner }
140