xref: /openbmc/openpower-proc-control/procedures/phal/thread_stopall.cpp (revision e0dd7af42a30b89e9f820c999bfe4a9bacc2a01d)
15f2eaf18SJayanth Othayoth #include "extensions/phal/create_pel.hpp"
25f2eaf18SJayanth Othayoth #include "extensions/phal/dump_utils.hpp"
35f2eaf18SJayanth Othayoth #include "registration.hpp"
45f2eaf18SJayanth Othayoth 
55f2eaf18SJayanth Othayoth #include <attributes_info.H>
6cb23cb2dSojayanth #include <libipl.H>
75f2eaf18SJayanth Othayoth #include <libphal.H>
85f2eaf18SJayanth Othayoth #include <phal_exception.H>
9*e0dd7af4SJayanth Othayoth 
10*e0dd7af4SJayanth Othayoth #include <format>
115f2eaf18SJayanth Othayoth extern "C"
125f2eaf18SJayanth Othayoth {
135f2eaf18SJayanth Othayoth #include <libpdbg.h>
145f2eaf18SJayanth Othayoth }
155f2eaf18SJayanth Othayoth #include <phosphor-logging/log.hpp>
165f2eaf18SJayanth Othayoth 
175f2eaf18SJayanth Othayoth namespace openpower
185f2eaf18SJayanth Othayoth {
195f2eaf18SJayanth Othayoth namespace phal
205f2eaf18SJayanth Othayoth {
215f2eaf18SJayanth Othayoth using namespace openpower::pel;
225f2eaf18SJayanth Othayoth using namespace openpower::phal::exception;
235f2eaf18SJayanth Othayoth using namespace phosphor::logging;
245f2eaf18SJayanth Othayoth 
255f2eaf18SJayanth Othayoth /**
265f2eaf18SJayanth Othayoth  * @brief Stop instruction executions on all functional threads in the
275f2eaf18SJayanth Othayoth  *        host processors.
285f2eaf18SJayanth Othayoth  *        This procedure is used to stop all threads in the system in
295f2eaf18SJayanth Othayoth  *        Attempt best case approch. Like issue processor level stopall
305f2eaf18SJayanth Othayoth  *        chip-op with ignore hardware error mode. Since this function
315f2eaf18SJayanth Othayoth  *        is used in power-off/error path, ignore the internal error now.
325f2eaf18SJayanth Othayoth  */
threadStopAll(void)335f2eaf18SJayanth Othayoth void threadStopAll(void)
345f2eaf18SJayanth Othayoth {
355f2eaf18SJayanth Othayoth     // CMD details based on SBE spec, used for logging purpose
365f2eaf18SJayanth Othayoth     constexpr auto SBEFIFO_CMD_CLASS_INSTRUCTION = 0xA700;
375f2eaf18SJayanth Othayoth     constexpr auto SBEFIFO_CMD_CONTROL_INSN = 0x01;
385f2eaf18SJayanth Othayoth     uint32_t cmd = SBEFIFO_CMD_CLASS_INSTRUCTION | SBEFIFO_CMD_CONTROL_INSN;
395f2eaf18SJayanth Othayoth 
405f2eaf18SJayanth Othayoth     try
415f2eaf18SJayanth Othayoth     {
425f2eaf18SJayanth Othayoth         // initialize the pdbg.
435f2eaf18SJayanth Othayoth         openpower::phal::pdbg::init();
445f2eaf18SJayanth Othayoth 
455f2eaf18SJayanth Othayoth         // Check Host is started.
465f2eaf18SJayanth Othayoth         if (!openpower::phal::sbe::isPrimaryIplDone())
475f2eaf18SJayanth Othayoth         {
485f2eaf18SJayanth Othayoth             log<level::INFO>("threadStopAll : skipping, Host is not running");
495f2eaf18SJayanth Othayoth             return;
505f2eaf18SJayanth Othayoth         }
515f2eaf18SJayanth Othayoth 
525f2eaf18SJayanth Othayoth         struct pdbg_target* procTarget;
535f2eaf18SJayanth Othayoth         ATTR_HWAS_STATE_Type hwasState;
545f2eaf18SJayanth Othayoth         pdbg_for_each_class_target("proc", procTarget)
555f2eaf18SJayanth Othayoth         {
565f2eaf18SJayanth Othayoth             if (DT_GET_PROP(ATTR_HWAS_STATE, procTarget, hwasState))
575f2eaf18SJayanth Othayoth             {
585f2eaf18SJayanth Othayoth                 log<level::ERR>(
59*e0dd7af4SJayanth Othayoth                     std::format("({})Could not read HWAS_STATE attribute",
605f2eaf18SJayanth Othayoth                                 pdbg_target_path(procTarget))
615f2eaf18SJayanth Othayoth                         .c_str());
625f2eaf18SJayanth Othayoth                 continue;
635f2eaf18SJayanth Othayoth             }
645f2eaf18SJayanth Othayoth             if (!hwasState.functional)
655f2eaf18SJayanth Othayoth             {
665f2eaf18SJayanth Othayoth                 continue;
675f2eaf18SJayanth Othayoth             }
685f2eaf18SJayanth Othayoth 
695f2eaf18SJayanth Othayoth             try
705f2eaf18SJayanth Othayoth             {
715f2eaf18SJayanth Othayoth                 openpower::phal::sbe::threadStopProc(procTarget);
725f2eaf18SJayanth Othayoth             }
735f2eaf18SJayanth Othayoth             catch (const sbeError_t& sbeError)
745f2eaf18SJayanth Othayoth             {
755f2eaf18SJayanth Othayoth                 auto errType = sbeError.errType();
765f2eaf18SJayanth Othayoth 
775f2eaf18SJayanth Othayoth                 // Create PEL only for  valid SBE reported failures
785f2eaf18SJayanth Othayoth                 if (errType == SBE_CMD_FAILED)
795f2eaf18SJayanth Othayoth                 {
805f2eaf18SJayanth Othayoth                     log<level::ERR>(
81*e0dd7af4SJayanth Othayoth                         std::format(
82cb23cb2dSojayanth                             "threadStopAll failed({}) on proc({})",
83cb23cb2dSojayanth                             static_cast<
84cb23cb2dSojayanth                                 std::underlying_type<ipl_error_type>::type>(
85cb23cb2dSojayanth                                 errType),
86cb23cb2dSojayanth                             pdbg_target_index(procTarget))
875f2eaf18SJayanth Othayoth                             .c_str());
885f2eaf18SJayanth Othayoth 
895f2eaf18SJayanth Othayoth                     uint32_t index = pdbg_target_index(procTarget);
905f2eaf18SJayanth Othayoth                     // To store additional data about ffdc.
915f2eaf18SJayanth Othayoth                     FFDCData pelAdditionalData;
925f2eaf18SJayanth Othayoth 
935f2eaf18SJayanth Othayoth                     // SRC6 : [0:15] chip position
945f2eaf18SJayanth Othayoth                     //        [16:23] command class,  [24:31] Type
955f2eaf18SJayanth Othayoth                     pelAdditionalData.emplace_back(
965f2eaf18SJayanth Othayoth                         "SRC6", std::to_string((index << 16) | cmd));
975f2eaf18SJayanth Othayoth 
9880f8ff95SJayanth Othayoth                     // Create informational error log.
995f2eaf18SJayanth Othayoth                     createSbeErrorPEL(
1005f2eaf18SJayanth Othayoth                         "org.open_power.Processor.Error.SbeChipOpFailure",
101e5ba5fd0SJayanth Othayoth                         sbeError, pelAdditionalData, procTarget,
102e5ba5fd0SJayanth Othayoth                         Severity::Informational);
1035f2eaf18SJayanth Othayoth                 }
1045f2eaf18SJayanth Othayoth                 else
1055f2eaf18SJayanth Othayoth                 {
1065f2eaf18SJayanth Othayoth                     // SBE is not ready to accept chip-ops,
1075f2eaf18SJayanth Othayoth                     // Skip the request, no additional error handling required.
1085f2eaf18SJayanth Othayoth                     log<level::INFO>(
109*e0dd7af4SJayanth Othayoth                         std::format("threadStopAll: Skipping ({}) on proc({})",
1105f2eaf18SJayanth Othayoth                                     sbeError.what(),
1115f2eaf18SJayanth Othayoth                                     pdbg_target_index(procTarget))
1125f2eaf18SJayanth Othayoth                             .c_str());
1135f2eaf18SJayanth Othayoth                 }
1145f2eaf18SJayanth Othayoth                 continue;
1155f2eaf18SJayanth Othayoth             }
1165f2eaf18SJayanth Othayoth             log<level::INFO>(
117*e0dd7af4SJayanth Othayoth                 std::format("Processor thread stopall completed on proc({})",
1185f2eaf18SJayanth Othayoth                             pdbg_target_index(procTarget))
1195f2eaf18SJayanth Othayoth                     .c_str());
1205f2eaf18SJayanth Othayoth         }
1215f2eaf18SJayanth Othayoth     }
1225f2eaf18SJayanth Othayoth     // Capture general exception
1235f2eaf18SJayanth Othayoth     catch (const std::exception& ex)
1245f2eaf18SJayanth Othayoth     {
1255f2eaf18SJayanth Othayoth         // This failure could be related to BMC firmware
1265f2eaf18SJayanth Othayoth         // Dont throw exception on failure because, need to proceed
1275f2eaf18SJayanth Othayoth         // further to complete power-off/reboot.
1285f2eaf18SJayanth Othayoth         log<level::ERR>(
129*e0dd7af4SJayanth Othayoth             std::format("threadStopAll: Exception({})", ex.what()).c_str());
1305f2eaf18SJayanth Othayoth 
1315f2eaf18SJayanth Othayoth         // To store additional data about ffdc.
1325f2eaf18SJayanth Othayoth         FFDCData pelAdditionalData;
1335f2eaf18SJayanth Othayoth 
1345f2eaf18SJayanth Othayoth         // SRC6 : [0:15] chip position, setting 0xFF to indicate generic fail
1355f2eaf18SJayanth Othayoth         //        [16:23] command class,  [24:31] Type
1365f2eaf18SJayanth Othayoth         pelAdditionalData.emplace_back("SRC6",
1375f2eaf18SJayanth Othayoth                                        std::to_string((0xFF << 16) | cmd));
1385f2eaf18SJayanth Othayoth         json jsonCalloutDataList;
1395f2eaf18SJayanth Othayoth         jsonCalloutDataList = json::array();
1405f2eaf18SJayanth Othayoth         json jsonCalloutData;
1415f2eaf18SJayanth Othayoth         jsonCalloutData["Procedure"] = "BMC0001";
1425f2eaf18SJayanth Othayoth         jsonCalloutData["Priority"] = "H";
1435f2eaf18SJayanth Othayoth         jsonCalloutDataList.emplace_back(jsonCalloutData);
1445f2eaf18SJayanth Othayoth         openpower::pel::createErrorPEL(
1455f2eaf18SJayanth Othayoth             "org.open_power.Processor.Error.SbeChipOpFailure",
1464d5b5bfeSMarri Devender Rao             jsonCalloutDataList, pelAdditionalData, Severity::Informational);
1475f2eaf18SJayanth Othayoth         return;
1485f2eaf18SJayanth Othayoth     }
1495f2eaf18SJayanth Othayoth }
1505f2eaf18SJayanth Othayoth 
1515f2eaf18SJayanth Othayoth REGISTER_PROCEDURE("threadStopAll", threadStopAll)
1525f2eaf18SJayanth Othayoth 
1535f2eaf18SJayanth Othayoth } // namespace phal
1545f2eaf18SJayanth Othayoth } // namespace openpower
155