diff options
Diffstat (limited to 'src/usr/isteps/istep08')
-rw-r--r-- | src/usr/isteps/istep08/call_proc_check_slave_sbe_seeprom_complete.C | 61 | ||||
-rw-r--r-- | src/usr/isteps/istep08/makefile | 1 | ||||
-rw-r--r-- | src/usr/isteps/istep08/sbe_extract_rc_handler.C | 218 | ||||
-rw-r--r-- | src/usr/isteps/istep08/sbe_extract_rc_handler.H | 107 |
4 files changed, 377 insertions, 10 deletions
diff --git a/src/usr/isteps/istep08/call_proc_check_slave_sbe_seeprom_complete.C b/src/usr/isteps/istep08/call_proc_check_slave_sbe_seeprom_complete.C index 30e5fcca7..956a59ab9 100644 --- a/src/usr/isteps/istep08/call_proc_check_slave_sbe_seeprom_complete.C +++ b/src/usr/isteps/istep08/call_proc_check_slave_sbe_seeprom_complete.C @@ -58,10 +58,12 @@ #include <fapi2/target.H> #include <fapi2/plat_hwp_invoker.H> +#include <return_code.H> #include <p9_extract_sbe_rc.H> #include <p9_get_sbe_msg_register.H> #include <p9_getecid.H> +#include "sbe_extract_rc_handler.H" using namespace ISTEP; using namespace ISTEP_ERROR; @@ -176,7 +178,7 @@ void* call_proc_check_slave_sbe_seeprom_complete( void *io_pArgs ) /*@ * @errortype * @reasoncode RC_SBE_SLAVE_TIMEOUT - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL * @moduleid MOD_CHECK_SLAVE_SBE_SEEPROM_COMPLETE * @userdata1 HUID of proc which had SBE timeout * @userdata2 SBE MSG Register @@ -187,7 +189,7 @@ void* call_proc_check_slave_sbe_seeprom_complete( void *io_pArgs ) * @custdesc A processor in the system has failed to initialize */ l_errl = new ErrlEntry( - ERRL_SEV_UNRECOVERABLE, + ERRL_SEV_INFORMATIONAL, MOD_CHECK_SLAVE_SBE_SEEPROM_COMPLETE, RC_SBE_SLAVE_TIMEOUT, TARGETING::get_huid(l_cpu_target), @@ -195,17 +197,56 @@ void* call_proc_check_slave_sbe_seeprom_complete( void *io_pArgs ) l_errl->collectTrace( "ISTEPS_TRACE", 256); - l_errl->addHwCallout( l_cpu_target, - HWAS::SRCI_PRIORITY_HIGH, - HWAS::DECONFIG, - HWAS::GARD_NULL ); - - // Create IStep error log and cross reference to error that occurred - l_stepError.addErrorDetails( l_errl ); - // Commit error and continue, this is not terminating since // we can still at least boot with master proc errlCommit(l_errl,ISTEP_COMP_ID); + + // Setup for the HWP + P9_EXTRACT_SBE_RC::RETURN_ACTION l_rcAction = + P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM; + FAPI_INVOKE_HWP(l_errl, p9_extract_sbe_rc, + l_cpu_target, l_rcAction); + + if(l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR : proc_check_slave_sbe_seeprom_complete " + "failed, p9_extract_sbe_rc HWP returning errorlog " + "PLID=0x%x",l_errl->plid()); + + // capture the target data in the elog + ErrlUserDetailsTarget(l_cpu_target).addToLog( l_errl ); + + // Create IStep error log and cross reference to error + l_stepError.addErrorDetails( l_errl ); + + // Commit error log + errlCommit( l_errl, HWPF_COMP_ID ); + + } + else if(!l_errl && l_rcAction != P9_EXTRACT_SBE_RC::ERROR_RECOVERED) + { + + if(INITSERVICE::spBaseServicesEnabled()) + { + // When we are on an FSP machine, we want to fail out of + // hostboot and give control back to the FSP. They have + // better diagnostics for this type of error. + INITSERVICE::doShutdownWithError(RC_HWSV_COLLECT_SBE_RC, + TARGETING::get_huid(l_cpu_target)); + } + + // Pull out previous rc error for threshold + uint8_t l_prevError = (l_cpu_target)->getAttr< + TARGETING::ATTR_PREVIOUS_SBE_ERROR>(); + // Save the current rc error + (l_cpu_target)->setAttr< + TARGETING::ATTR_PREVIOUS_SBE_ERROR>(l_rcAction); + + proc_extract_sbe_handler( l_cpu_target, + l_prevError, l_rcAction); + } + } else if (l_errl) { diff --git a/src/usr/isteps/istep08/makefile b/src/usr/isteps/istep08/makefile index 523fd901d..a200aed91 100644 --- a/src/usr/isteps/istep08/makefile +++ b/src/usr/isteps/istep08/makefile @@ -52,6 +52,7 @@ OBJS += call_proc_chiplet_fabric_scominit.o OBJS += call_proc_xbus_scominit.o OBJS += call_proc_xbus_enable_ridi.o OBJS += call_host_attnlisten_proc.o +OBJS += sbe_extract_rc_handler.o VPATH += ${PROCEDURES_PATH}/hwp/perv/ ${PROCEDURES_PATH}/hwp/nest/ VPATH += ${PROCEDURES_PATH}/hwp/io/ ${PROCEDURES_PATH}/hwp/initfiles/ diff --git a/src/usr/isteps/istep08/sbe_extract_rc_handler.C b/src/usr/isteps/istep08/sbe_extract_rc_handler.C new file mode 100644 index 000000000..6c267c5e0 --- /dev/null +++ b/src/usr/isteps/istep08/sbe_extract_rc_handler.C @@ -0,0 +1,218 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep08/sbe_extract_rc_handler.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file sbe_extract_rc_handler.H + * + * Handle a SBE extract rc error. We use a switch-case to determine + * what action to take, and a finite state machine to control the + * threshold actions. + */ + +/*****************************************************************************/ +// Includes +/*****************************************************************************/ +#include <stdint.h> +#include <trace/interface.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <p9_extract_sbe_rc.H> + +#include <fapi2/target.H> +#include <fapi2/plat_hwp_invoker.H> +#include <isteps/istep_reasoncodes.H> +#include <initservice/isteps_trace.H> +#include <errl/errludtarget.H> + +#include <p9_start_cbs.H> +#include "sbe_extract_rc_handler.H" + +/* array and enum must be in sync */ +P9_EXTRACT_SBE_RC::RETURN_ACTION (* state[])(TARGETING::Target * i_target, + uint8_t i_prev_error) = + { same_side_retry_state, other_side_state, + working_exit_state, failing_exit_state }; +enum state_codes { same_side_retry, other_side, + working_exit, failing_exit }; +struct transition +{ + enum state_codes src_state; + uint8_t ret_code; + enum state_codes dst_state; +}; + +/* transistions from end states aren't needed */ +struct transition state_transitions[] = { + { same_side_retry, 0, working_exit }, + { same_side_retry, 1, other_side }, + { other_side, 0, working_exit }, + { other_side, 1, failing_exit } +}; + +enum state_codes get_next_state( enum state_codes i_src, uint8_t i_rc ) +{ + return (state_transitions[ i_src*2 + i_rc ]).dst_state; +} + +void sbe_threshold_handler( bool i_procSide, + TARGETING::Target * i_target, + P9_EXTRACT_SBE_RC::RETURN_ACTION i_initialAction, + uint8_t i_previousError ) +{ + // Note: This is set up as a finite state machine since all actions are + // connected and most of them lead to another. + + state_codes cur_state = same_side_retry; + + // The initial state depends on our inputs + if( i_procSide ) + { + cur_state = other_side; + } + + // Setup the rest of the FSM + P9_EXTRACT_SBE_RC::RETURN_ACTION l_returnedAction; + P9_EXTRACT_SBE_RC::RETURN_ACTION (*state_fcn)(TARGETING::Target * i_target, + uint8_t i_prev_error); + + P9_EXTRACT_SBE_RC::RETURN_ACTION l_currentAction = i_initialAction; + + // Begin FSM + for(;;) + { + state_fcn = state[cur_state]; + l_returnedAction = state_fcn(i_target, l_currentAction); + + if( cur_state == working_exit || cur_state == failing_exit) + { + break; + } + l_currentAction = l_returnedAction; + // If the returned action was 0, the return is a pass: 0, + // Else, the SBE did not start cleanly and we continue + cur_state = get_next_state(cur_state, + !(P9_EXTRACT_SBE_RC::ERROR_RECOVERED == l_returnedAction)); + + } + + return; + +} + +P9_EXTRACT_SBE_RC::RETURN_ACTION same_side_retry_state( + TARGETING::Target * i_target, + uint8_t i_prev_error) +{ + return P9_EXTRACT_SBE_RC::ERROR_RECOVERED; //pass +} + +P9_EXTRACT_SBE_RC::RETURN_ACTION other_side_state( + TARGETING::Target * i_target, + uint8_t i_prev_error) +{ + return P9_EXTRACT_SBE_RC::ERROR_RECOVERED; //pass +} + +P9_EXTRACT_SBE_RC::RETURN_ACTION working_exit_state( + TARGETING::Target * i_target, + uint8_t i_prev_error) +{ + return P9_EXTRACT_SBE_RC::ERROR_RECOVERED; //pass +} + +P9_EXTRACT_SBE_RC::RETURN_ACTION failing_exit_state( + TARGETING::Target * i_target, + uint8_t i_prev_error) +{ + return P9_EXTRACT_SBE_RC::ERROR_RECOVERED; //pass +} +// end FSM + + +void proc_extract_sbe_handler( TARGETING::Target * i_target, + uint8_t i_previous_error, uint8_t i_current_error) +{ + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK + "proc_extract_sbe_handler error: %llx",i_current_error); + + errlHndl_t l_errl = NULL; + + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL + * @moduleid ISTEP::MOD_SBE_EXTRACT_RC_HANDLER + * @reasoncode ISTEP::RC_SBE_EXTRACT_RC_ERROR + * @userdata1 HUID of proc that had the SBE timeout + * @userdata2 SBE failing code + * + * @devdesc SBE did not start, this funciton is looking at + * the error to determine next course of action + * + * @custdesc The SBE did not start, we will attempt a reboot if possible + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + ISTEP::MOD_SBE_EXTRACT_RC_HANDLER, + ISTEP::RC_SBE_EXTRACT_RC_ERROR, + TARGETING::get_huid(i_target), + i_current_error); + + l_errl->collectTrace("ISTEPS_TRACE",256); + + // Commit error and continue + errlCommit(l_errl, ISTEP_COMP_ID); + + switch(i_current_error) + { + case P9_EXTRACT_SBE_RC::RESTART_SBE: + case P9_EXTRACT_SBE_RC::RESTART_CBS: + { + break; + } + case P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM: + { + break; + } + case P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM: + { + break; + } + case P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION: + { + break; + } + default: + { + break; + } + } + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK + "proc_extract_sbe_handler"); + + return; +} + + + diff --git a/src/usr/isteps/istep08/sbe_extract_rc_handler.H b/src/usr/isteps/istep08/sbe_extract_rc_handler.H new file mode 100644 index 000000000..a83febf22 --- /dev/null +++ b/src/usr/isteps/istep08/sbe_extract_rc_handler.H @@ -0,0 +1,107 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep08/sbe_extract_rc_handler.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __SBE_EXTRACT_RC_HANDLER_H +#define __SBE_EXTRACT_RC_HANDLER_H + +/*************************** State declarations ***************************/ +/** + * @brief This is the initial retry. If we get to a failure, we attempt to + * reboot the SBE on the other side. + * + * @param[in] i_target - current proc target + * @param[in] i_prev_error - Previous SBE error + * + * @return - pass(0) or specific returned SBE error + */ +P9_EXTRACT_SBE_RC::RETURN_ACTION same_side_retry_state( + TARGETING::Target * i_target,uint8_t i_prev_error); + +/** + * @brief This is the other side retry. If we fail twice on the same side + * We attempt to reboot the SBE on the other proc. + * + * @param[in] i_target - current proc target + * @param[in] i_prev_error - Previous SBE error + * + * @return - pass(0) or specific returned SBE error + */ +P9_EXTRACT_SBE_RC::RETURN_ACTION other_side_state( + TARGETING::Target * i_target,uint8_t i_prev_error); + +/** + * @brief This is the working (passing) exit state. This state occurs when + * we start an SBE correctly within the threshold FSM. Depending on + * which state we come from, there are some different functions. + * + * @param[in] i_target - current proc target + * @param[in] i_prev_error - Previous SBE error + * + * @return - pass(0) or specific returned SBE error + */ +P9_EXTRACT_SBE_RC::RETURN_ACTION working_exit_state( + TARGETING::Target * i_target,uint8_t i_prev_error); + +/** + * @brief This is the failing exit state. This state only occurs when we + * fail on every retry. In this case we look at where we came from + * and either escalate to REIPL_BKP_SEEPROM or we gard and callout + * this proc and return to complete the istep. + * + * @param[in] i_target - current proc target + * @param[in] i_prev_error - Previous SBE error + * + * @return - pass(0) or specific returned SBE error + */ +P9_EXTRACT_SBE_RC::RETURN_ACTION failing_exit_state( + TARGETING::Target * i_target,uint8_t i_prev_error); + +/** + * @brief This is the main function of the finite state machine. It handles + * the outputs, current state and next state transitions. + * + * @param[in] i_procSide - Which side we want to try to reboot. + * 0/1: current/other + * @param[in] i_target - Current Proc target + * @param[in] i_currentAction - Most recent return value from HWP + * @param[in] i_previousError - The previous return value from HWP + */ +void sbe_threshold_handler( bool i_procSide, + TARGETING::Target * i_target, + P9_EXTRACT_SBE_RC::RETURN_ACTION i_currentAction, + uint8_t i_previousError ); + +/** + * @brief This is the switch case that handles the different actions needed for + * each output of the proc_extract_sbe_rc HWP. + * + * @param[in] i_target - current proc target + * @param[in] i_previous_error - The previous return value from HWP + * @param[in] i_current_error - The most recent return value from HWP + * + * @return - NULL + */ +void proc_extract_sbe_handler( TARGETING::Target * i_target, + uint8_t i_previous_error, uint8_t i_current_error); +#endif |