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