summaryrefslogtreecommitdiffstats
path: root/src/usr/sbeio/common
diff options
context:
space:
mode:
authorElizabeth Liner <eliner@us.ibm.com>2018-02-07 16:23:09 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-02-15 14:26:06 -0500
commit1e337a9565c8c08a4a13a145890027a10c043bf0 (patch)
tree808f7a9eff1b0f3207662a844779bbf3f48104d2 /src/usr/sbeio/common
parent77b70bb7119cb13cc35976fa63201ee305538ad3 (diff)
downloadtalos-hostboot-1e337a9565c8c08a4a13a145890027a10c043bf0.tar.gz
talos-hostboot-1e337a9565c8c08a4a13a145890027a10c043bf0.zip
Moving Sbe Retry Handler work to common file for runtime
We want to move the sbe_retry_handler.C and other files associated with it to a common directory and makefile. Change-Id: Ifc725709d23d9eec75d2f91b2be73728c91a8d86 RTC:180241 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/53591 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Roland Veloz <rveloz@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/sbeio/common')
-rw-r--r--src/usr/sbeio/common/common.mk26
-rw-r--r--src/usr/sbeio/common/sbe_attn.C106
-rw-r--r--src/usr/sbeio/common/sbe_retry_handler.C1063
3 files changed, 1195 insertions, 0 deletions
diff --git a/src/usr/sbeio/common/common.mk b/src/usr/sbeio/common/common.mk
new file mode 100644
index 000000000..397af666f
--- /dev/null
+++ b/src/usr/sbeio/common/common.mk
@@ -0,0 +1,26 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/sbeio/common/common.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2018
+# [+] 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
+SBEIO_COMMON_OBJS += sbe_attn.o
+SBEIO_COMMON_OBJS += sbe_retry_handler.o
diff --git a/src/usr/sbeio/common/sbe_attn.C b/src/usr/sbeio/common/sbe_attn.C
new file mode 100644
index 000000000..a6fcb0583
--- /dev/null
+++ b/src/usr/sbeio/common/sbe_attn.C
@@ -0,0 +1,106 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbeio/common/sbe_attn.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* [+] 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 */
+/*
+ Contains the logic that is needed to handle and recover from SBE vital
+ attentions that occur when the SBE crashes.
+*/
+
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <sbeio/sbe_attn.H>
+#include <fapi2/target.H>
+#include <fapi2/plat_hwp_invoker.H>
+#include <p9_extract_sbe_rc.H>
+#include <sbeio/sbeioreasoncodes.H>
+#include <sbeio/sbe_retry_handler.H>
+
+extern trace_desc_t* g_trac_sbeio;
+
+namespace SBEIO
+{
+
+ /**
+ * @brief Gathers FFDC and recovers from SBE errors
+ */
+ errlHndl_t handleVitalAttn( TARGETING::Target* i_procTarg )
+ {
+ TRACFCOMP( g_trac_sbeio,
+ ENTER_MRK "handleVitalAttn> i_procTarg=",
+ TARGETING::get_huid(i_procTarg) );
+ errlHndl_t l_errhdl = nullptr;
+
+ uint32_t l_sbePlid = getSbeRC(i_procTarg);
+
+ TRACFCOMP( g_trac_sbeio, "handleVitalAttn> Returned SBE PLID=0x%x",
+ l_sbePlid);
+
+ // @todo - RTC:180242 - Restart SBE
+
+ SbeRetryHandler l_sbeObj = SbeRetryHandler(
+ SbeRetryHandler::SBE_MODE_OF_OPERATION::ATTEMPT_REBOOT);
+ // @todo - RTC:180242. Once the hreset method is finalized,
+ // we can call the sbe handler with that method
+ //l_sbeObj.setSbeRestartMethod(SbeRetryHandler::
+ // SBE_RESTART_METHOD::HRESET);
+
+ l_sbeObj.main_sbe_handler(i_procTarg);
+
+ // @todo - RTC:180244 - Disable the OCC
+ // @todo - RTC:180245 - Inform OPAL
+
+ TRACFCOMP( g_trac_sbeio,
+ EXIT_MRK "handleVitalAttn> ");
+ return l_errhdl;
+ }
+
+ uint32_t getSbeRC(TARGETING::Target* i_target)
+ {
+ TRACFCOMP( g_trac_sbeio, ENTER_MRK "getSbeRC()");
+
+ errlHndl_t l_errl = nullptr;
+
+ uint32_t l_errlPlid = NULL;
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi2ProcTarget(
+ const_cast<TARGETING::Target*> (i_target));
+
+ P9_EXTRACT_SBE_RC::RETURN_ACTION l_ret =
+ P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
+ FAPI_INVOKE_HWP(l_errl, p9_extract_sbe_rc,
+ l_fapi2ProcTarget, l_ret);
+
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_sbeio, "ERROR: p9_extract_sbe_rc HWP returning "
+ "errorlog PLID: 0x%x", l_errl->plid());
+
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errlPlid = l_errl->plid();
+ }
+
+ return l_errlPlid;
+ }
+
+};
diff --git a/src/usr/sbeio/common/sbe_retry_handler.C b/src/usr/sbeio/common/sbe_retry_handler.C
new file mode 100644
index 000000000..b18480df4
--- /dev/null
+++ b/src/usr/sbeio/common/sbe_retry_handler.C
@@ -0,0 +1,1063 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbeio/common/sbe_retry_handler.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* [+] 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_dd.C
+ *
+ * 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 <initservice/isteps_trace.H>
+#include <initservice/initserviceif.H>
+#include <errl/errludtarget.H>
+#include <sys/time.h>
+#include <util/misc.H>
+#include <ipmi/ipmiwatchdog.H>
+
+#include <p9_start_cbs.H>
+#include <p9_get_sbe_msg_register.H>
+#include <p9_perv_scom_addresses.H>
+#include <sbe/sbe_update.H>
+#include <sbeio/sbeioif.H>
+#include <sbeio/sbe_sp_intf.H>
+#include <../../usr/sbeio/sbe_fifodd.H>
+#include <../../usr/sbeio/sbe_fifo_buffer.H>
+#include <sbeio/sbe_ffdc_parser.H>
+#include <sbeio/sbeioreasoncodes.H>
+#include <sbeio/sbe_retry_handler.H>
+#include <secureboot/service.H>
+
+#include <devicefw/driverif.H>
+
+
+extern trace_desc_t* g_trac_sbeio;
+
+#define SBE_TRACF(printf_string,args...) \
+ TRACFCOMP(g_trac_sbeio,"sbe_retry_handler.C: " printf_string,##args)
+#define SBE_TRACD(printf_string,args...) \
+ TRACDCOMP(g_trac_sbeio,"sbe_retry_handler.C: " printf_string,##args)
+#define SBE_TRACU(args...)
+#define SBE_TRACFBIN(printf_string,args...) \
+ TRACFBIN(g_trac_sbeio,"sbe_retry_handler.C: " printf_string,##args)
+#define SBE_TRACDBIN(printf_string,args...) \
+ TRACDBIN(g_trac_sbeio,"sbe_retry_handler.C: " printf_string,##args)
+
+using namespace ERRORLOG;
+
+namespace SBEIO
+{
+
+SbeRetryHandler::SbeRetryHandler(SBE_MODE_OF_OPERATION i_sbeMode)
+: SbeRetryHandler(i_sbeMode, 0)
+{
+}
+
+SbeRetryHandler::SbeRetryHandler(SBE_MODE_OF_OPERATION i_sbeMode,
+ uint32_t i_plid)
+
+: iv_useSDB(false)
+, iv_secureModeDisabled(false) //Per HW team this should always be 0
+, iv_sbeRestarted(false)
+, iv_sbeSide(0)
+, iv_errorLogPLID(0)
+, iv_callerErrorLogPLID(i_plid)
+, iv_switchSidesCount(0)
+, iv_currentAction(P9_EXTRACT_SBE_RC::ERROR_RECOVERED)
+, iv_currentSBEState(SBE_REG_RETURN::SBE_FAILED_TO_BOOT)
+, iv_retriggeredMain(false)
+, iv_sbeMode(i_sbeMode)
+, iv_sbeRestartMethod(SBE_RESTART_METHOD::START_CBS)
+{
+ SBE_TRACF(ENTER_MRK "SbeRetryHandler::SbeRetryHandler()");
+
+ // Initialize members that have no default initialization
+ iv_sbeRegister.reg = 0;
+
+ SBE_TRACF(EXIT_MRK "SbeRetryHandler::SbeRetryHandler()");
+}
+
+SbeRetryHandler::~SbeRetryHandler()
+{
+
+}
+
+void SbeRetryHandler::main_sbe_handler( TARGETING::Target * i_target )
+{
+ SBE_TRACF(ENTER_MRK "main_sbe_handler()");
+
+ do
+ {
+ errlHndl_t l_errl = NULL;
+
+ if(!i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>().useXscom)
+ {
+ this->iv_useSDB = true;
+ }
+
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi2ProcTarget(
+ const_cast<TARGETING::Target*> (i_target));
+
+ bool l_retry = false;
+
+ if(this->iv_sbeMode != INFORMATIONAL_ONLY)
+ {
+ this->get_sbe_reg(i_target);
+
+ if( (this->iv_sbeRegister.currState != SBE_STATE_RUNTIME) &&
+ !(this->iv_sbeMode == SBE_ACTION_SET))
+ {
+ // return, false if no boot is needed, true if boot is needed.
+ l_retry = this->sbe_boot_fail_handler(i_target);
+ }
+ else if(this->iv_sbeMode == SBE_ACTION_SET)
+ {
+ l_retry = true;
+ }
+
+ while((this->iv_sbeRegister.currState != SBE_STATE_RUNTIME) &&
+ l_retry)
+ {
+
+ SBE_TRACF("main_sbe_handler(): current SBE state is %d, retry "
+ "is %d current SBE action is %d",
+ this->iv_sbeRegister.currState,
+ l_retry, this->iv_currentAction);
+
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid SBEIO_EXTRACT_RC_HANDLER
+ * @reasoncode SBEIO_EXTRACT_RC_ERROR
+ * @userdata1 HUID of proc that had the SBE timeout
+ * @userdata2 SBE failing code
+ *
+ * @devdesc SBE did not start, this function 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,
+ SBEIO_EXTRACT_RC_HANDLER,
+ SBEIO_EXTRACT_RC_ERROR,
+ TARGETING::get_huid(i_target),
+ this->iv_currentAction);
+
+ l_errl->collectTrace("ISTEPS_TRACE",256);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ // Commit error and continue
+ errlCommit(l_errl, ISTEP_COMP_ID);
+
+ // if no recovery action, fail out.
+ if(this->iv_currentAction ==
+ P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION)
+ {
+ // There is no action possible. Gard and Callout the proc
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid SBEIO_EXTRACT_RC_HANDLER
+ * @reasoncode SBEIO_NO_RECOVERY_ACTION
+ * @userdata1 SBE current error
+ * @userdata2 HUID of proc
+ * @devdesc There is no recovery action on the SBE.
+ * We're garding this proc
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SBEIO_EXTRACT_RC_HANDLER,
+ SBEIO_NO_RECOVERY_ACTION,
+ P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION,
+ TARGETING::get_huid(i_target));
+ l_errl->collectTrace( "ISTEPS_TRACE", 256);
+ l_errl->addHwCallout( i_target,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL );
+
+ // Cache PLID of error log
+ iv_errorLogPLID = l_errl->plid();
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl, ISTEP_COMP_ID);
+
+ SBE_TRACF("main_sbe_handler(): updating return value "
+ "to indicate that we have deconfigured the proc");
+ this->iv_currentSBEState = SBE_REG_RETURN::PROC_DECONFIG;
+
+ break;
+ }
+
+ // if the bkp_seeprom or upd_seeprom, attempt to switch sides.
+ // This is also dependent on the iv_switchSideCount.
+ if(this->iv_currentAction ==
+ P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM ||
+ this->iv_currentAction ==
+ P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM)
+ {
+ l_errl = this->switch_sbe_sides(i_target);
+ if(l_errl)
+ {
+ errlCommit(l_errl, ISTEP_COMP_ID);
+ break;
+ }
+ }
+
+ // Attempt SBE restart
+ if(this->iv_sbeRestartMethod == SBE_RESTART_METHOD::START_CBS)
+ {
+ SBE_TRACF("Invoking p9_start_cbs HWP");
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ l_fapi2_proc_target (i_target);
+
+ FAPI_INVOKE_HWP(l_errl, p9_start_cbs,
+ l_fapi2_proc_target, true);
+ if(l_errl)
+ {
+ SBE_TRACF("ERROR: call p9_start_cbs, PLID=0x%x",
+ l_errl->plid() );
+ l_errl->collectTrace( "ISTEPS_TRACE", 256 );
+
+ // Gard the target, when SBE Retry fails
+ l_errl->addHwCallout(i_target,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_Predictive);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit( l_errl, ISTEP_COMP_ID);
+ }
+ }else
+ {
+ //@todo - RTC:180242 - Restart SBE
+ }
+
+ // Get the sbe register
+ this->get_sbe_reg(i_target);
+
+ if( (this->iv_sbeRegister.currState != SBE_STATE_RUNTIME))
+ {
+ // return, false if no boot is needed.
+ l_retry = this->sbe_boot_fail_handler(i_target);
+ }
+ }
+ }
+ else
+ {
+ // In the informational only mode, we just need enough information
+ // to get the SBE RC returned from the HWP. We are running with
+ // the knowledge that the SBE has failed already.
+
+ // pass true to have log show up
+ this->sbe_boot_fail_handler(i_target, true);
+ this->iv_currentSBEState = SBE_FAILED_TO_BOOT;
+ }
+
+ this->handle_sbe_reg_value(i_target);
+
+ // if we have started the sbe, and the current action is upd_seeprom
+ // or bkp_seeprom, note that we started on an unexpected side
+ if(i_target->getAttr<TARGETING::ATTR_SBE_IS_STARTED>() &&
+ (this->iv_currentAction == P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM ||
+ this->iv_currentAction == P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM) )
+ {
+ /*@
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid SBEIO_EXTRACT_RC_HANDLER
+ * @reasoncode SBEIO_BOOTED_UNEXPECTED_SIDE
+ * @userdata1 0
+ * @userdata2 HUID of working proc
+ * @devdesc SBE booted from unexpected side.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ SBEIO_EXTRACT_RC_HANDLER,
+ SBEIO_BOOTED_UNEXPECTED_SIDE,
+ 0,TARGETING::get_huid(i_target));
+ l_errl->collectTrace("ISTEPS_TRACE",256);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl, ISTEP_COMP_ID);
+ }
+
+ }while(0);
+
+ SBE_TRACF(EXIT_MRK "main_sbe_handler()");
+}
+
+void SbeRetryHandler::get_sbe_reg(TARGETING::Target * i_target)
+{
+ SBE_TRACF(ENTER_MRK "get_sbe_reg()");
+
+ errlHndl_t l_errl = nullptr;
+
+ do
+ {
+ l_errl = this->sbe_timeout_handler(i_target);
+
+ if((!l_errl) && (this->iv_sbeRegister.currState != SBE_STATE_RUNTIME))
+ {
+ // See if async FFDC bit is set in SBE register
+ if(this->iv_sbeRegister.asyncFFDC)
+ {
+ bool l_flowCtrl = this->sbe_get_ffdc_handler(i_target);
+
+ if(l_flowCtrl)
+ {
+ break;
+ }
+ }
+ }
+ else if (l_errl)
+ {
+ SBE_TRACF("ERROR: call get_sbe_reg, PLID=0x%x", l_errl->plid() );
+
+ // capture the target data in the elog
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl );
+
+ // Commit error log
+ errlCommit( l_errl, HWPF_COMP_ID );
+ }
+ // No error and still functional
+ else if(i_target->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+ // Set attribute indicating that SBE is started
+ i_target->setAttr<TARGETING::ATTR_SBE_IS_STARTED>(1);
+ this->iv_sbeRestarted = true;
+
+ SBE_TRACF("SUCCESS: get_sbe_reg completed okay for proc 0x%.8X",
+ TARGETING::get_huid(i_target));
+ }
+ //@TODO-RTC:100963 - this should match the logic in
+ //call_proc_check_slave_sbe_seeprom.C
+ } while(0);
+
+ SBE_TRACF(EXIT_MRK "get_sbe_reg()");
+
+}
+
+void SbeRetryHandler::handle_sbe_reg_value(TARGETING::Target * i_target)
+{
+ errlHndl_t l_errl = NULL;
+
+ SBE_TRACF(ENTER_MRK "handle_sbe_reg_value()");
+
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ l_fapi2_proc_target(i_target);
+
+ switch(this->iv_currentSBEState)
+ {
+ case SbeRetryHandler::SBE_REG_RETURN::HWP_ERROR:
+ {
+ SBE_TRACF("handle_sbe_reg_value(): case FUNCTION_ERROR");
+ // There has been a failure getting the SBE register
+ // We cannot continue any further, return failure.
+ this->iv_currentAction = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
+ break;
+ }
+ case SbeRetryHandler::SBE_REG_RETURN::SBE_AT_RUNTIME:
+ {
+ SBE_TRACF("handle_sbe_reg_value(): case SBE_AT_RUNTIME");
+ // The SBE has successfully booted at runtime
+ this->iv_currentAction = P9_EXTRACT_SBE_RC::ERROR_RECOVERED;
+ break;
+ }
+ case SbeRetryHandler::SBE_REG_RETURN::SBE_FAILED_TO_BOOT:
+ {
+ SBE_TRACF("handle_sbe_reg_value(): case SBE_FAILED_TO_BOOT");
+ if((this->iv_currentAction == P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM)
+ && (!iv_retriggeredMain))
+
+ {
+ iv_retriggeredMain = true;
+#ifdef CONFIG_BMC_IPMI
+#ifndef __HOSTBOOT_RUNTIME
+ // This could potentially take awhile, reset watchdog
+ l_errl = IPMIWATCHDOG::resetWatchDogTimer();
+ if(l_errl)
+ {
+ SBE_TRACF("Inside handle_sbe_reg_value before sbe_handler "
+ "Resetting watchdog");
+ l_errl->collectTrace("ISTEPS_TRACE",256);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl,ISTEP_COMP_ID);
+ }
+#endif
+#endif
+ SBE_TRACF("handle_sbe_reg_value(): Attempting "
+ "REIPL_UPD_SEEPROM failed. Recalling with BKP_SEEPROM");
+ // If we were trying to reipl and hit the error, we need
+ // to start with a new seeprom before hitting the threshold
+ this->iv_currentAction =
+ P9_EXTRACT_SBE_RC::RETURN_ACTION::REIPL_BKP_SEEPROM;
+ this->iv_sbeMode = SBE_MODE_OF_OPERATION::SBE_ACTION_SET;
+ main_sbe_handler(i_target);
+ break;
+ }
+
+ // Failed to boot, setting the final action for debugging.
+ SBE_TRACF("Inside handle_sbe_reg_value, calling "
+ "p9_extract_sbe_rc HWP");
+ // Get SBE extract rc
+ 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_fapi2_proc_target, l_rcAction);
+ this->iv_currentAction = l_rcAction;
+
+ SBE_TRACF("handle_sbe_reg_value(): SBE failed to boot. Final "
+ "action is %llx", l_rcAction);
+
+ if(l_errl)
+ {
+ SBE_TRACF("ERROR : p9_extract_sbe_rc HWP returning errorlog "
+ "PLID-0x%x", l_errl->plid());
+
+ // capture the target data in the elog
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+
+ // Cache PLID of error log
+ iv_errorLogPLID = l_errl->plid();
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ // Commit error log
+ errlCommit( l_errl, HWPF_COMP_ID );
+ }
+
+ break;
+ }
+ default:
+ {
+ // This should never happened
+ // error out, unexpected enum value returned.
+ //return P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
+ /*@
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid SBEIO_HANDLE_SBE_REG_VALUE
+ * @reasoncode SBEIO_INCORRECT_FCN_CALL
+ * @userdata1 HUID of target
+ * @userdata2 SBE current state
+ * @devdesc This function was called incorrectly or
+ * there is a new enum that is not handled yet.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ SBEIO_HANDLE_SBE_REG_VALUE,
+ SBEIO_INCORRECT_FCN_CALL,
+ get_huid(i_target),this->iv_currentSBEState);
+ l_errl->collectTrace("ISTEPS_TRACE",256);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl, ISTEP_COMP_ID);
+ this->iv_currentAction = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
+ break;
+ }
+ }
+ SBE_TRACF(EXIT_MRK "handle_sbe_reg_value()");
+}
+
+errlHndl_t SbeRetryHandler::sbe_timeout_handler(TARGETING::Target * i_target)
+{
+ SBE_TRACF(ENTER_MRK "sbe_timeout_handler()");
+
+ errlHndl_t l_errl = NULL;
+
+ this->iv_currentSBEState =
+ SbeRetryHandler::SBE_REG_RETURN::SBE_FAILED_TO_BOOT;
+
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ l_fapi2_proc_target(i_target);
+
+ // Each slave sbe gets 60s to respond with the fact that it's
+ // booted and at runtime (stable state)
+ uint64_t SBE_TIMEOUT_NSEC = 60*NS_PER_SEC; //60 sec
+ // Bump this up really high for simics, things are slow there
+ if( Util::isSimicsRunning() )
+ {
+ SBE_TIMEOUT_NSEC *= 10;
+ }
+ const uint64_t SBE_NUM_LOOPS = 100;
+ const uint64_t SBE_WAIT_SLEEP = (SBE_TIMEOUT_NSEC/SBE_NUM_LOOPS);
+
+ SBE_TRACF("Running p9_get_sbe_msg_register HWP on proc target %.8X",
+ TARGETING::get_huid(i_target));
+
+ for( uint64_t l_loops = 0; l_loops < SBE_NUM_LOOPS; l_loops++ )
+ {
+ sbeMsgReg_t l_reg;
+ FAPI_INVOKE_HWP(l_errl, p9_get_sbe_msg_register,
+ l_fapi2_proc_target, l_reg);
+ this->iv_sbeRegister = l_reg;
+ if (l_errl)
+ {
+ SBE_TRACF("ERROR : call p9_get_sbe_msg_register, PLID=0x%x, "
+ "on loop %d",
+ l_errl->plid(),
+ l_loops );
+ this->iv_currentSBEState =
+ SbeRetryHandler::SBE_REG_RETURN::HWP_ERROR;
+ break;
+ }
+ else if ((this->iv_sbeRegister).currState == SBE_STATE_RUNTIME)
+ {
+ SBE_TRACF("SBE 0x%.8X booted and at runtime, "
+ "iv_sbeRegister=0x%.8X, on loop %d",
+ TARGETING::get_huid(i_target),
+ (this->iv_sbeRegister).reg,
+ l_loops);
+ this->iv_currentSBEState =
+ SbeRetryHandler::SBE_REG_RETURN::SBE_AT_RUNTIME;
+ break;
+ }
+ else if ((this->iv_sbeRegister).asyncFFDC)
+ {
+ SBE_TRACF("SBE 0x%.8X has async FFDC bit set, "
+ "iv_sbeRegister=0x%.8X",TARGETING::get_huid(i_target),
+ (this->iv_sbeRegister).reg);
+ // Async FFDC is indicator that SBE is failing to boot, and if
+ // in DUMP state, that SBE is done dumping, so leave loop
+ break;
+ }
+ else
+ {
+ if( !(l_loops % 10) )
+ {
+ SBE_TRACF("%d> SBE 0x%.8X NOT booted yet, "
+ "iv_sbeRegister=0x%.8X", l_loops,
+ TARGETING::get_huid(i_target),
+ (this->iv_sbeRegister).reg);
+ }
+ l_loops++;
+ nanosleep(0,SBE_WAIT_SLEEP);
+ }
+ }
+
+ if ((this->iv_sbeRegister).currState != SBE_STATE_RUNTIME)
+ {
+ // Switch to using FSI SCOM
+ TARGETING::ScomSwitches l_switches =
+ i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ TARGETING::ScomSwitches l_switches_before = l_switches;
+
+ // Turn off SBE SCOM and turn on FSI SCOM.
+ l_switches.useFsiScom = 1;
+ l_switches.useSbeScom = 0;
+
+ SBE_TRACF("sbe_timeout_handler: changing SCOM switches from 0x%.2X "
+ "to 0x%.2X for proc 0x%.8X",
+ l_switches_before,
+ l_switches,
+ TARGETING::get_huid(i_target));
+ i_target->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(l_switches);
+ }
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (l_errl && iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ SBE_TRACF(EXIT_MRK "sbe_timeout_handler()");
+ return l_errl;
+}
+
+P9_EXTRACT_SBE_RC::RETURN_ACTION SbeRetryHandler::action_for_ffdc_rc(
+ uint32_t i_rc)
+{
+ SBE_TRACF(ENTER_MRK "action_for_ffdc_rc()");
+
+ P9_EXTRACT_SBE_RC::RETURN_ACTION l_action;
+
+ switch(i_rc)
+ {
+ case fapi2::RC_EXTRACT_SBE_RC_RUNNING:
+ case fapi2::RC_EXTRACT_SBE_RC_NEVER_STARTED:
+ case fapi2::RC_EXTRACT_SBE_RC_PROGRAM_INTERRUPT:
+ case fapi2::RC_EXTRACT_SBE_RC_ADDR_NOT_RECOGNIZED:
+ case fapi2::RC_EXTRACT_SBE_RC_PIBMEM_ECC_ERR:
+ case fapi2::RC_EXTRACT_SBE_RC_FI2CM_BIT_RATE_ERR_NONSECURE_MODE:
+
+ l_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
+
+ break;
+
+ case fapi2::RC_EXTRACT_SBE_RC_MAGIC_NUMBER_MISMATCH:
+ case fapi2::RC_EXTRACT_SBE_RC_FI2C_ECC_ERR:
+ case fapi2::RC_EXTRACT_SBE_RC_FI2C_ECC_ERR_NONSECURE_MODE:
+
+ l_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
+
+ break;
+
+ case fapi2::RC_EXTRACT_SBE_RC_FI2C_TIMEOUT:
+ case fapi2::RC_EXTRACT_SBE_RC_SBE_L1_LOADER_FAIL:
+ case fapi2::RC_EXTRACT_SBE_RC_SBE_L2_LOADER_FAIL:
+ case fapi2::RC_EXTRACT_SBE_RC_UNKNOWN_ERROR:
+
+ l_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM;
+
+ break;
+
+ case fapi2::RC_EXTRACT_SBE_RC_OTP_TIMEOUT:
+ case fapi2::RC_EXTRACT_SBE_RC_OTP_PIB_ERR:
+ case fapi2::RC_EXTRACT_SBE_RC_PIBMEM_PIB_ERR:
+ case fapi2::RC_EXTRACT_SBE_RC_FI2C_SPRM_CFG_ERR:
+ case fapi2::RC_EXTRACT_SBE_RC_FI2C_PIB_ERR:
+
+ l_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
+
+ break;
+
+ case fapi2::RC_EXTRACT_SBE_RC_BRANCH_TO_SEEPROM_FAIL:
+ case fapi2::RC_EXTRACT_SBE_RC_UNEXPECTED_OTPROM_HALT:
+ case fapi2::RC_EXTRACT_SBE_RC_OTP_ECC_ERR:
+ default:
+
+ l_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
+
+ break;
+ }
+
+ SBE_TRACF(EXIT_MRK "action_for_ffdc_rc()");
+ return l_action;
+}
+
+bool SbeRetryHandler::sbe_get_ffdc_handler(TARGETING::Target * i_target)
+{
+ SBE_TRACF(ENTER_MRK "sbe_get_ffdc_handler()");
+
+ bool l_flowCtrl = false;
+ uint32_t l_responseSize = SbeFifoRespBuffer::MSG_BUFFER_SIZE;
+ uint32_t *l_pFifoResponse =
+ reinterpret_cast<uint32_t *>(malloc(l_responseSize));
+
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t l_errl = nullptr;
+ l_errl = getFifoSBEFFDC(i_target,
+ l_pFifoResponse,
+ l_responseSize);
+
+ // Check if there was an error log created
+ if(l_errl)
+ {
+ // Trace but otherwise silently ignore error
+ SBE_TRACF("sbe_get_ffdc_handler: ignoring error PLID=0x%x from "
+ "get SBE FFDC FIFO request to proc 0x%.8X",
+ l_errl->plid(),
+ TARGETING::get_huid(i_target));
+ delete l_errl;
+ l_errl = nullptr;
+ }
+ else
+ {
+ // Parse the FFDC package(s) in the response
+ SbeFFDCParser * l_ffdc_parser =
+ new SbeFFDCParser();
+ l_ffdc_parser->parseFFDCData(reinterpret_cast<void *>(l_pFifoResponse));
+
+ uint8_t l_pkgs = l_ffdc_parser->getTotalPackages();
+ P9_EXTRACT_SBE_RC::RETURN_ACTION l_action;
+
+ // If there are FFDC packages, make a log for FFDC from SBE
+ if(l_pkgs > 0)
+ {
+ /*@
+ * @errortype
+ * @moduleid SBEIO_GET_FFDC_HANDLER
+ * @reasoncode SBEIO_RETURNED_FFDC
+ * @userdata1 Processor Target
+ * @userdata2 Number of FFDC packages
+ * @devdesc FFDC returned by SBE after failing to reach runtime
+ * @custdesc FFDC associated with boot device failing to boot
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ SBEIO_GET_FFDC_HANDLER,
+ SBEIO_RETURNED_FFDC,
+ TARGETING::get_huid(i_target),
+ l_pkgs);
+
+ // Also log the failing proc as FFDC
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ }
+
+ // Process each FFDC package
+ for(auto i=0; i<l_pkgs; i++)
+ {
+ // Add each package to the log
+ l_errl->addFFDC( SBEIO_COMP_ID,
+ l_ffdc_parser->getFFDCPackage(i),
+ l_ffdc_parser->getPackageLength(i),
+ 0,
+ SBEIO_UDT_PARAMETERS,
+ false );
+
+ // Get the RC from the FFDC package
+ uint32_t l_rc = l_ffdc_parser->getPackageRC(i);
+
+ // Determine an action for the RC
+ l_action = action_for_ffdc_rc(l_rc);
+
+ // Handle that action
+ this->iv_currentAction = l_action;
+ this->iv_retriggeredMain = true;
+ this->iv_sbeMode = SBE_MODE_OF_OPERATION::SBE_ACTION_SET;
+ main_sbe_handler(i_target);
+ }
+
+ // If there are FFDC packages, commit the log
+ if(l_pkgs > 0)
+ {
+ l_errl->collectTrace( SBEIO_COMP_NAME, KILOBYTE/4);
+ l_errl->collectTrace( "ISTEPS_TRACE", KILOBYTE/4);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl, ISTEP_COMP_ID);
+ }
+
+ delete l_ffdc_parser;
+ l_ffdc_parser = nullptr;
+
+ l_flowCtrl = true;
+ }
+#endif
+
+ free(l_pFifoResponse);
+ l_pFifoResponse = nullptr;
+
+ SBE_TRACF(EXIT_MRK "sbe_get_ffdc_handler()");
+ return l_flowCtrl;
+}
+
+//By default we want to call the 2 param version of the func w/ "true"
+//passed in to tell the function we want to hide the mandatory errlog
+bool SbeRetryHandler::sbe_boot_fail_handler(TARGETING::Target * i_target)
+{
+ return SbeRetryHandler::sbe_boot_fail_handler(i_target, false);
+}
+
+bool SbeRetryHandler::sbe_boot_fail_handler(TARGETING::Target * i_target,
+ bool i_exposeLog)
+{
+ SBE_TRACF(ENTER_MRK "sbe_boot_fail_handler()");
+
+ errlHndl_t l_errl = nullptr;
+ fapi2::ReturnCode l_rc;
+ bool o_needRetry = false;
+
+ SBE_TRACF("SBE 0x%.8X never started, sbeReg=0x%.8X",
+ TARGETING::get_huid(i_target),(this->iv_sbeRegister).reg );
+ /*@
+ * @errortype
+ * @reasoncode SBEIO_SLAVE_TIMEOUT
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid SBEIO_EXTRACT_RC_HANDLER
+ * @userdata1 HUID of proc which had SBE timeout
+ * @userdata2 SBE MSG Register
+ *
+ * @devdesc Slave SBE did not get to ready state within
+ * allotted time
+ *
+ * @custdesc A processor in the system has failed to initialize
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ SBEIO_EXTRACT_RC_HANDLER,
+ SBEIO_SLAVE_TIMEOUT,
+ TARGETING::get_huid(i_target),
+ (this->iv_sbeRegister).reg);
+
+ l_errl->collectTrace( "ISTEPS_TRACE", KILOBYTE/4);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ if(i_exposeLog)
+ {
+ l_errl->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+
+ }
+
+ // Commit error and continue, this is not terminating since
+ // we can still at least boot with master proc
+ errlCommit(l_errl,ISTEP_COMP_ID);
+
+ SBE_TRACF("Inside sbe_boot_fail_handler, calling p9_extract_sbe_rc HWP");
+
+ // Setup for the HWP
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi2ProcTarget(
+ const_cast<TARGETING::Target*> (i_target));
+
+ P9_EXTRACT_SBE_RC::RETURN_ACTION l_ret =
+ P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
+
+ //Note that we are calling this while we are already inside
+ //of a FAPI_INVOKE_HWP call. This might cause issue w/ current_err
+ //but unsure how to get around it.
+ FAPI_EXEC_HWP(l_rc, p9_extract_sbe_rc, l_fapi2ProcTarget,
+ l_ret, iv_useSDB, iv_secureModeDisabled);
+
+ l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE);
+ this->iv_currentAction = l_ret;
+
+ if(this->iv_currentAction != P9_EXTRACT_SBE_RC::ERROR_RECOVERED)
+ {
+
+ if(l_errl)
+ {
+ SBE_TRACF("p9_extract_sbe_rc HWP returned action %d and errorlog "
+ "PLID=0x%x, rc=0x%.4X", this->iv_currentAction,
+ l_errl->plid(), l_errl->reasonCode() );
+ delete l_errl;
+ l_errl = nullptr;
+ }
+
+ if(INITSERVICE::spBaseServicesEnabled())
+ {
+#ifndef __HOSTBOOT_RUNTIME
+ // 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(SBEIO_HWSV_COLLECT_SBE_RC,
+ TARGETING::get_huid(i_target));
+#endif
+ }
+
+#ifdef CONFIG_BMC_IPMI
+#ifndef __HOSTBOOT_RUNTIME
+ // This could potentially take awhile, reset watchdog
+ l_errl = IPMIWATCHDOG::resetWatchDogTimer();
+ if(l_errl)
+ {
+ SBE_TRACF("sbe_boot_fail_handler "
+ "Resetting watchdog before sbe_handler");
+ l_errl->collectTrace("ISTEPS_TRACE",KILOBYTE/4);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ errlCommit(l_errl,ISTEP_COMP_ID);
+ }
+#endif
+#endif
+ SBE_TRACF("sbe_boot_fail_handler. iv_switchSides count is %llx",
+ iv_switchSidesCount);
+ if((this->iv_currentAction == P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION) &&
+ (iv_switchSidesCount < MAX_SWITCH_SIDE_COUNT))
+ {
+ this->iv_currentAction = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM;
+ o_needRetry = true;
+ }
+ else if(iv_switchSidesCount >= MAX_SWITCH_SIDE_COUNT)
+ {
+ o_needRetry = false;
+ }
+ else
+ {
+ o_needRetry = true;
+ }
+
+ }
+ if(l_errl)
+ {
+ SBE_TRACF("Error: sbe_boot_fail_handler : p9_extract_sbe_rc HWP "
+ " returned action %d and errorlog PLID=0x%x, rc=0x%.4X",
+ this->iv_currentAction, l_errl->plid(), l_errl->reasonCode());
+
+ // Capture the target data in the elog
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl );
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ // Commit error log
+ errlCommit( l_errl, HWPF_COMP_ID );
+ }
+
+ SBE_TRACF(EXIT_MRK "sbe_boot_fail_handler() current action is %llx",
+ this->iv_currentAction);
+ return o_needRetry;
+}
+
+errlHndl_t SbeRetryHandler::switch_sbe_sides(TARGETING::Target * i_target)
+{
+ SBE_TRACF(ENTER_MRK "switch_sbe_sides()");
+
+ errlHndl_t l_errl = NULL;
+ const uint32_t l_sbeBootSelectMask = SBE::SBE_BOOT_SELECT_MASK >> 32;
+
+ do{
+
+ // Read PERV_SB_CS_FSI_BYTE 0x2820 for target proc
+ uint32_t l_read_reg = 0;
+ size_t l_opSize = sizeof(uint32_t);
+ l_errl = DeviceFW::deviceOp(
+ DeviceFW::READ,
+ i_target,
+ &l_read_reg,
+ l_opSize,
+ DEVICE_FSI_ADDRESS(PERV_SB_CS_FSI_BYTE) );
+ if( l_errl )
+ {
+ SBE_TRACF( ERR_MRK"switch_sbe_sides: FSI device read "
+ "PERV_SB_CS_FSI_BYTE (0x%.4X), proc target = %.8X, "
+ "RC=0x%X, PLID=0x%lX",
+ PERV_SB_CS_FSI_BYTE, // 0x2820
+ TARGETING::get_huid(i_target),
+ ERRL_GETRC_SAFE(l_errl),
+ ERRL_GETPLID_SAFE(l_errl));
+ break;
+ }
+
+ // Determine how boot side is currently set
+ if(l_read_reg & l_sbeBootSelectMask) // Currently set for Boot Side 1
+ {
+ // Set Boot Side 0 by clearing bit for side 1
+ SBE_TRACF( "switch_sbe_sides #%d: Set Boot Side 0 for HUID 0x%08X",
+ iv_switchSidesCount,
+ TARGETING::get_huid(i_target));
+ l_read_reg &= ~l_sbeBootSelectMask;
+ this->iv_sbeSide = 1;
+ }
+ else // Currently set for Boot Side 0
+ {
+ // Set Boot Side 1 by setting bit for side 1
+ SBE_TRACF( "switch_sbe_sides #%d: Set Boot Side 1 for HUID 0x%08X",
+ iv_switchSidesCount,
+ TARGETING::get_huid(i_target));
+ l_read_reg |= l_sbeBootSelectMask;
+ this->iv_sbeSide = 0;
+ }
+
+ SBE_TRACF("switch_sbe_sides(): iv_switchSidesCount is %llx",
+ iv_switchSidesCount);
+ // Increment switch sides count
+ ++iv_switchSidesCount;
+
+ // Write updated PERV_SB_CS_FSI 0x2820 back into target proc
+ l_errl = DeviceFW::deviceOp(
+ DeviceFW::WRITE,
+ i_target,
+ &l_read_reg,
+ l_opSize,
+ DEVICE_FSI_ADDRESS(PERV_SB_CS_FSI_BYTE) );
+ if( l_errl )
+ {
+ SBE_TRACF( ERR_MRK"switch_sbe_sides: FSI device write "
+ "PERV_SB_CS_FSI_BYTE (0x%.4X), proc target = %.8X, "
+ "RC=0x%X, PLID=0x%lX",
+ PERV_SB_CS_FSI_BYTE, // 0x2820
+ TARGETING::get_huid(i_target),
+ ERRL_GETRC_SAFE(l_errl),
+ ERRL_GETPLID_SAFE(l_errl));
+ break;
+ }
+ }while(0);
+
+ // Set the PLID of the error log to caller's PLID,
+ // if provided
+ if (l_errl && iv_callerErrorLogPLID)
+ {
+ l_errl->plid(iv_callerErrorLogPLID);
+ }
+
+ SBE_TRACF(EXIT_MRK "switch_sbe_sides()");
+ return l_errl;
+}
+
+} // End of namespace SBEIO
OpenPOWER on IntegriCloud