summaryrefslogtreecommitdiffstats
path: root/src/usr/sbe
diff options
context:
space:
mode:
authorMike Baiocchi <baiocchi@us.ibm.com>2015-02-17 13:07:13 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-03-01 16:22:19 -0600
commit19b0400e8e2123bdfe1231616bfdaf2fc0d1f3e2 (patch)
tree52b29b9d9cf4e40ef379fff36a47a5af6531d6a6 /src/usr/sbe
parentf8ff70afe17963e03abdbc113cf8c1f6198857c3 (diff)
downloadtalos-hostboot-19b0400e8e2123bdfe1231616bfdaf2fc0d1f3e2.tar.gz
talos-hostboot-19b0400e8e2123bdfe1231616bfdaf2fc0d1f3e2.zip
GOLDEN SBE Update Support - Reconcile SBE images and PNOR sides
This code adds a new function at istep 6 to reconcile the two SBE Seeproms with the PNOR side and mode (ie, 2-sided, golden, etc). It also updates what happens in istep 9 in SBE_UPDATE_INDEPENDENT mode. Change-Id: If71ca52338a179b8cf38cfa336d9790737844715 RTC: 120734 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15790 Tested-by: Jenkins Server Reviewed-by: PRACHI GUPTA <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Richard J. Knight <rjknight@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/sbe')
-rw-r--r--src/usr/sbe/HBconfig6
-rw-r--r--src/usr/sbe/makefile5
-rw-r--r--src/usr/sbe/sbe_resolve_sides.C1363
-rw-r--r--src/usr/sbe/sbe_resolve_sides.H259
-rw-r--r--src/usr/sbe/sbe_update.C124
5 files changed, 1720 insertions, 37 deletions
diff --git a/src/usr/sbe/HBconfig b/src/usr/sbe/HBconfig
index 0fa24413d..fd2a8d07b 100644
--- a/src/usr/sbe/HBconfig
+++ b/src/usr/sbe/HBconfig
@@ -20,9 +20,9 @@ config SBE_UPDATE_INDEPENDENT
depends on !SBE_UPDATE_SEQUENTIAL && !SBE_UPDATE_SIMULTANEOUS
help
If an update is necessary, and if the "current" SBE SEEPROM of this
- IPL is not the 'GOLDEN' SBE SEEPROM, then only the current SBE SEEPROM
- will be updated. After the update a re-IPL request will be issued.
- The other SBE SEEPROM, whether 'GOLDEN' or not, will not be updated.
+ IPL is not pointing at PNOR's 'GOLDEN' side, then only the current SBE
+ SEEPROM will be updated. After the update a re-IPL request will be
+ issued. The other SBE SEEPROM will not be updated.
config NO_SBE_UPDATES
default n
diff --git a/src/usr/sbe/makefile b/src/usr/sbe/makefile
index 06159ff01..c45206e1e 100644
--- a/src/usr/sbe/makefile
+++ b/src/usr/sbe/makefile
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2013,2014
+# Contributors Listed Below - COPYRIGHT 2013,2015
+# [+] 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.
@@ -36,6 +38,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include
EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build
OBJS += sbe_update.o
+OBJS += sbe_resolve_sides.o
SUBDIRS += test.d
diff --git a/src/usr/sbe/sbe_resolve_sides.C b/src/usr/sbe/sbe_resolve_sides.C
new file mode 100644
index 000000000..df9958d65
--- /dev/null
+++ b/src/usr/sbe/sbe_resolve_sides.C
@@ -0,0 +1,1363 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbe/sbe_resolve_sides.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 */
+
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errlreasoncodes.H>
+#include <errl/hberrltypes.H>
+#include <targeting/common/predicates/predicatectm.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/targetservice.H>
+#include <util/misc.H>
+#include <pnor/pnorif.H>
+#include <pnor/ecc.H>
+#include <devicefw/driverif.H>
+#include <sys/mm.h>
+#include <sys/misc.h>
+#include <hwas/common/deconfigGard.H>
+#include <initservice/initserviceif.H>
+#include <config.h>
+#include <ipmi/ipmiwatchdog.H>
+#include <ipmi/ipmisensor.H>
+#include <sbe/sbeif.H>
+#include <sbe/sbereasoncodes.H>
+#include "sbe_resolve_sides.H"
+#include "sbe_update.H"
+
+// fapi support
+#include <fapi.H>
+#include <fapiHwpExecutor.H>
+#include <hwpf/plat/fapiPlatHwpInvoker.H>
+#include <hwpf/plat/fapiPlatTrace.H>
+
+//Procedures
+#include <p8_xip_customize.H>
+#include <sbe_xip_image.h>
+#include <p8_image_help_base.H>
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_sbe;
+
+// ------------------------
+// Macros for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+
+using namespace ERRORLOG;
+using namespace TARGETING;
+
+namespace SBE
+{
+ enum {
+ SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE,
+ RING_BUF1_VADDR = FIXED_SEEPROM_WORK_SPACE + SBE_IMG_VADDR,
+ RING_BUF2_VADDR = RING_BUF1_VADDR + FIXED_RING_BUF_SIZE,
+ //NOTE: recycling the same memory space for different
+ //steps in the process.
+ SBE_ECC_IMG_VADDR = RING_BUF1_VADDR,
+ SBE_ECC_IMG_MAX_SIZE = VMM_VADDR_SBE_UPDATE_END - SBE_ECC_IMG_VADDR,
+ };
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t resolveProcessorSbeSeeproms()
+{
+ errlHndl_t err = NULL;
+ errlHndl_t err_cleanup = NULL;
+ sbeResolveState_t sideState;
+ bool l_cleanupVmmSpace = false;
+ bool l_restartNeeded = false;
+
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"resolveProcessorSbeSeeproms()" );
+
+ do{
+
+#ifdef CONFIG_NO_SBE_UPDATES
+ TRACFCOMP( g_trac_sbe, INFO_MRK"resolveProcessorSbeSeeproms() - "
+ "SBE updates not configured");
+ break;
+#endif
+
+#ifdef CONFIG_SBE_UPDATE_SIMULTANEOUS
+ TRACFCOMP( g_trac_sbe, INFO_MRK"resolveProcessorSbeSeeproms() - "
+ "Do Nothing in SBE_UPDATE_SIMULTANEOUS mode");
+ break;
+#endif
+
+#ifdef CONFIG_SBE_UPDATE_SEQUENTIAL
+ // Check if FSP-services are enabled and if we're running in simics
+ if ( !INITSERVICE::spBaseServicesEnabled() &&
+ !Util::isSimicsRunning() )
+ {
+ assert (false, "resolveProcessorSbeSeeproms() - "
+ "SBE_UPDATE_SEQUENTIAL mode, but FSP-services are not "
+ "enabled - Invalid Configuration");
+ }
+ else
+ {
+ TRACUCOMP( g_trac_sbe, INFO_MRK"resolveProcessorSbeSeeproms() - "
+ "Do Nothing in SBE_UPDATE_INDEPENDENT mode with FSP-"
+ "services enabled or running in simics");
+ break;
+ }
+#endif
+
+ // Get Target Service, and the system target.
+ TargetService& tS = targetService();
+ TARGETING::Target* sys = NULL;
+ (void) tS.getTopLevelTarget( sys );
+ assert(sys, "resolveProcessorSbeSeeproms() system target is NULL");
+
+
+ //Make sure procedure constants keep within expected range.
+ assert((FIXED_SEEPROM_WORK_SPACE <= VMM_SBE_UPDATE_SIZE/2),
+ "resolveProcessorSbeSeeproms() FIXED_SEEPROM_WORK_SPACE "
+ "too large");
+ assert((FIXED_RING_BUF_SIZE <= VMM_SBE_UPDATE_SIZE/4),
+ "resolveProcessorSbeSeeproms() FIXED_RING_BUF_SIZE too "
+ "large");
+
+ // Create VMM space for p8_xip_customize() procedure
+ err = createSbeImageVmmSpace();
+ if (err)
+ {
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeproms: "
+ "createSbeImageVmmSpace() Failed. ",
+ "rc=0x%.4X", err->reasonCode() );
+
+ break;
+ }
+ else
+ {
+ // Make sure cleanup gets called
+ l_cleanupVmmSpace = true;
+ }
+
+ /*****************************************************************/
+ /* Iterate over all the functional processors and do for each: */
+ /*****************************************************************/
+ TARGETING::TargetHandleList procList;
+ TARGETING::getAllChips(procList,
+ TARGETING::TYPE_PROC,
+ true); // true: return functional targets
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"resolveProcessorSbeSeeproms() - "
+ "No functional processors Found!" );
+ break;
+ }
+
+ for(uint32_t i=0; i<procList.size(); i++)
+ {
+ /***********************************************/
+ /* Get Side This Processor did/will boot from */
+ /***********************************************/
+ memset(&sideState, 0, sizeof(sideState));
+ sideState.tgt = procList[i];
+
+ err = getSideState(sideState);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "resolveProcessorSbeSeeproms: Error returned "
+ "from getSideState() "
+ "rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(sideState.tgt));
+ // Don't break - handle error at the end of the loop
+ }
+
+
+ /**********************************************/
+ /* Determine the necessary actions */
+ /**********************************************/
+ // Skip if we got an error previously
+ if ( err == NULL )
+ {
+ err = getSideActions(sideState);
+ if (err)
+ {
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeproms: "
+ "getSideActions() Failed "
+ "rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(sideState.tgt));
+
+ // Don't break - handle error at the end of the loop,
+ }
+ }
+
+ /**********************************************/
+ /* Perform the necessary actions */
+ /**********************************************/
+ // Skip if we got an error previously
+ if ( err == NULL )
+ {
+ err = performSideActions(sideState);
+ if (err)
+ {
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeproms: "
+ "performSideActions() Failed "
+ "rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(sideState.tgt));
+
+ // Don't break - handle error at the end of the loop,
+ }
+ else
+ {
+ // Target updated without failure, so set IPL_RESTART
+ // flag, if necessary
+ if (sideState.actions & REIPL)
+ {
+ l_restartNeeded = true;
+ }
+ }
+ }
+
+ /**********************************************/
+ /* Handle Errors */
+ /**********************************************/
+
+ if ( err )
+ {
+ // Something failed for this target.
+
+ // Commit the error here and move on to the next target,
+ // or if no targets left, will just continue the IPL
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeproms: "
+ "Committing Error Log rc=0x%.4X eid=0x%.8X "
+ "plid=0x%.8X for Target UID=0x%X, but "
+ "continuing procedure",
+ err->reasonCode(),
+ err->eid(),
+ err->plid(),
+ TARGETING::get_huid(sideState.tgt));
+ errlCommit( err, SBE_COMP_ID );
+ }
+
+
+ } //end of Target for loop collecting each target's SBE State
+
+
+ /**************************************************************/
+ /* Perform System Operation */
+ /**************************************************************/
+ // Restart IPL if SBE Update requires it
+ if ( l_restartNeeded == true )
+ {
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeprom: Restart "
+ "Needed (%d).",
+ l_restartNeeded);
+
+#ifdef CONFIG_BMC_IPMI
+ sbePreShutdownIpmiCalls();
+#endif
+
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"resolveProcessorSbeSeeproms: Calling "
+ "INITSERVICE::doShutdown() with "
+ "SBE_UPDATE_REQUEST_REIPL = 0x%X",
+ SBE_UPDATE_REQUEST_REIPL );
+ INITSERVICE::doShutdown(SBE_UPDATE_REQUEST_REIPL);
+ }
+
+ }while(0);
+
+
+ // Cleanup VMM Workspace
+ if ( l_cleanupVmmSpace == true )
+ {
+ err_cleanup = cleanupSbeImageVmmSpace();
+ if ( err_cleanup != NULL )
+ {
+
+ if ( err != NULL )
+ {
+ // 2 error logs, so commit the cleanup log here
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"resolveProcessorSbeSeeproms: Previous "
+ "error (rc=0x%X) before cleanupSbeImageVmmSpace"
+ "() failed. Committing cleanup error (rc=0x%X) "
+ "and returning original error",
+ err->reasonCode(), err_cleanup->reasonCode() );
+
+ errlCommit( err_cleanup, SBE_COMP_ID );
+ }
+ else
+ {
+ // no previous error, so returning cleanup error
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"resolveProcessorSbeSeeproms: "
+ "cleanupSbeImageVmmSpace() failed.",
+ "rc=0x%.4X", err_cleanup->reasonCode() );
+ err = err_cleanup;
+ }
+ }
+ }
+
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"resolveProcessorSbeSeeproms()" );
+
+ return err;
+}
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t getSideState(sbeResolveState_t& io_sideState)
+{
+ errlHndl_t err = NULL;
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"getSideState()" );
+
+ do{
+
+ /***********************************************/
+ /* Get Side This Processor did/will boot from */
+ /***********************************************/
+ PNOR::sbeSeepromSide_t tmp_cur_side = PNOR::SBE_SEEPROM_INVALID;
+ err = PNOR::getSbeBootSeeprom(io_sideState.tgt, tmp_cur_side);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "resolveProcessorSbeSeeproms() - Error returned "
+ "from PNOR::getSbeBootSeeprom() "
+ "rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt));
+ break;
+ }
+
+ io_sideState.cur_side = tmp_cur_side;
+
+ io_sideState.alt_side = (tmp_cur_side == PNOR::SBE_SEEPROM0)
+ ? PNOR::SBE_SEEPROM1 : PNOR::SBE_SEEPROM0;
+
+ /**********************************************/
+ /* Get PNOR Side Information */
+ /**********************************************/
+ PNOR::SideId tmp_side = PNOR::WORKING;
+ PNOR::SideInfo_t tmp_side_info;
+ err = PNOR::getSideInfo (tmp_side, tmp_side_info);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "resolveProcessorSbeSeeproms() - Error returned "
+ "from PNOR::getSideInfo() "
+ "rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt));
+ break;
+ }
+
+ io_sideState.pnor_sideId = tmp_side_info.id;
+ io_sideState.pnor_side = tmp_side_info.side;
+ io_sideState.pnor_isGolden = tmp_side_info.isGolden;
+ io_sideState.pnor_hasOtherSide = tmp_side_info.hasOtherSide;
+
+ }while(0);
+
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"getSideState(): cur/alt=%d/%d. Side-%c(%d): "
+ "isGolden=%d, hasOtherSide=%d",
+ io_sideState.cur_side, io_sideState.alt_side,
+ io_sideState.pnor_side, io_sideState.pnor_sideId,
+ io_sideState.pnor_isGolden, io_sideState.pnor_hasOtherSide );
+
+ return err;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t getSideActions(sbeResolveState_t& io_sideState)
+{
+ errlHndl_t err = NULL;
+ uint32_t l_actions = NO_ACTIONS;
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"getSideActions()" );
+
+ do{
+
+ // Check if PNOR is running from its GOLDEN side
+ if ( io_sideState.pnor_isGolden == true )
+ {
+
+ // If Booting From Seeprom that is pointing to PNOR's GOLDEN Side
+ // and is possibly the READ_ONLY_SEEPROM - No Re-IPL
+ if ( io_sideState.cur_side == READ_ONLY_SEEPROM )
+ {
+ l_actions |= COPY_READ_ONLY_TO_WORKING;
+ io_sideState.update_side = io_sideState.alt_side;
+#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ // Need info from PNOR's non-working side for update side
+ l_actions |= USE_PNOR_ALT_SIDE;
+ TRACUCOMP( g_trac_sbe, "getSideActions(): Asking for "
+ "USE_PNOR_ALT_SIDE: actions=0x%X", l_actions);
+#endif
+ }
+ else
+ {
+ // non-READ_ONLY_SEEPROM is pointing to PNOR's GOLDEN side
+ // This requires an update and re-IPL (Possibly Genesis Mode)
+ l_actions |= COPY_READ_ONLY_TO_WORKING;
+ l_actions |= REIPL;
+ io_sideState.update_side = io_sideState.cur_side;
+
+#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ // Need info from PNOR's non-working side for update side
+ l_actions |= USE_PNOR_ALT_SIDE;
+ TRACUCOMP( g_trac_sbe, "getSideActions(): Asking for "
+ "USE_PNOR_ALT_SIDE: actions=0x%X", l_actions);
+#endif
+
+ }
+ }
+
+ // Even though READ_ONLY_SEEPROM is not pointing to PNOR's GOLDEN side,
+ // treat like it is if there is only 1 side (ie, Palmetto configuration)
+ else if ( ( io_sideState.pnor_hasOtherSide == false ) &&
+ ( io_sideState.cur_side == READ_ONLY_SEEPROM ) )
+ {
+ l_actions |= COPY_READ_ONLY_TO_WORKING;
+ io_sideState.update_side = io_sideState.alt_side;
+ }
+
+ else // current Seeprom not pointing to PNOR's GOLDEN side
+ {
+ l_actions |= CHECK_WORKING_HBB;
+ io_sideState.update_side = io_sideState.cur_side;
+ // REIPL action will be determined later
+ }
+
+ io_sideState.actions = l_actions;
+
+ TRACUCOMP( g_trac_sbe, "getSideActions() Tgt=0x%X: "
+ "pnor_isGolden/hasOtherSide=%d/%d, actions=0x%.8X, "
+ "Update Side=0x%X, cur=%d",
+ TARGETING::get_huid(io_sideState.tgt),
+ io_sideState.pnor_isGolden, io_sideState.pnor_hasOtherSide,
+ io_sideState.actions,
+ io_sideState.update_side,
+ io_sideState.cur_side);
+
+ }while(0);
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"getSideActions()" );
+
+ return err;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t performSideActions(sbeResolveState_t& io_sideState)
+{
+ errlHndl_t err = NULL;
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"performSideActions()" );
+
+ bool updateForHBB = false;
+ size_t image_size = 0;
+ sbeSeepromVersionInfo_t image_version;
+
+ do{
+ if ( io_sideState.actions & COPY_READ_ONLY_TO_WORKING )
+ {
+ // Copy READ_ONLY SBE Seeprom Image to Memory
+ err = readSbeImage(io_sideState.tgt,
+ reinterpret_cast<void*>(SBE_IMG_VADDR),
+ READ_ONLY_SEEPROM,
+ image_size,
+ image_version);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "performSideActions: Error returned from "
+ "getSetSbeImage() rc=0x%.4X, Target UID=0x%X, "
+ "actions = 0x%X, image_size=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt),
+ io_sideState.actions, image_size);
+ break;
+ }
+ }
+
+ if ( io_sideState.actions & CHECK_WORKING_HBB )
+ {
+
+ // Copy current SBE Seeprom Image to Memory
+ // NOTE: Seprate section from above because of possible future
+ // improvement to use MBPD SB Keyword bit to keep track of HBB
+
+ err = readSbeImage(io_sideState.tgt,
+ reinterpret_cast<void*>(SBE_IMG_VADDR),
+ io_sideState.update_side,
+ image_size,
+ image_version);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "performSideActions: Error returned from "
+ "getSetSbeImage() rc=0x%.4X, Target UID=0x%X, "
+ "actions = 0x%X, image_size=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt),
+ io_sideState.actions, image_size);
+ break;
+ }
+
+ }
+
+
+ if ( ( io_sideState.actions & COPY_READ_ONLY_TO_WORKING ) ||
+ ( io_sideState.actions & CHECK_WORKING_HBB ) )
+ {
+ // verify HBB
+ PNOR::SideId pnor_side = PNOR::WORKING;
+
+#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ // In certain situations need info from Alternate PNOR
+ if ( io_sideState.actions & USE_PNOR_ALT_SIDE)
+ {
+ pnor_side = PNOR::ALTERNATE;
+ }
+#endif
+
+
+
+ err = resolveImageHBBaddr(io_sideState.tgt,
+ reinterpret_cast<void*>(SBE_IMG_VADDR),
+ io_sideState.update_side,
+ pnor_side,
+ updateForHBB);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "performSideActions: Error returned from "
+ "resolveImageHBBaddr() rc=0x%.4X, Target UID=0x%X, "
+ "actions = 0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt),
+ io_sideState.actions);
+ break;
+ }
+
+ // Since HBB was updated, we need to re-IPL if not booting on
+ // READ_ONLY seeprom
+ if ( ( updateForHBB == true ) &&
+ ( io_sideState.cur_side != READ_ONLY_SEEPROM ) )
+ {
+ io_sideState.actions |= REIPL;
+ TRACUCOMP( g_trac_sbe, ERR_MRK
+ "performSideActions: resolveImageHBBaddr returned "
+ "updateForHBB=%d, and not on READ_ONLY_SEEPROM so "
+ "REIPL (actions=0x%X)",
+ updateForHBB, io_sideState.actions);
+ }
+ }
+
+ if ( ( io_sideState.actions & COPY_READ_ONLY_TO_WORKING ) ||
+ ( updateForHBB == true ) )
+ {
+ // Write Seeprom Image from memory to Seeprom
+ err = writeSbeImage(io_sideState.tgt,
+ reinterpret_cast<void*>(SBE_IMG_VADDR),
+ io_sideState.update_side,
+ image_size,
+ image_version);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "performSideActions: Error returned from "
+ "getSetSbeImage() rc=0x%.4X, Target UID=0x%X, "
+ "actions = 0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sideState.tgt),
+ io_sideState.actions);
+ break;
+ }
+ }
+
+ }while(0);
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"performSideActions()" );
+
+ return err;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t readSbeImage(TARGETING::Target* i_target,
+ void* o_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t& o_image_size,
+ sbeSeepromVersionInfo_t& o_image_version)
+{
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"readSbeImage(): tgt=0x%X, i_side=%d "
+ "o_imgPtr=%p, o_image_size=0x%X",
+ TARGETING::get_huid(i_target), i_side, o_imgPtr, o_image_size);
+
+ errlHndl_t err = NULL;
+ int64_t rc = 0;
+ PNOR::ECC::eccStatus eccStatus = PNOR::ECC::CLEAN;
+ EEPROM::eeprom_chip_types_t l_seeprom = sbe_side_sync[i_side];
+ size_t image_size_ECC = 0;
+
+ // Need to ensure that io_imgPtr is at SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE
+ // since we need to use the VMM_VADDR_SBE_UPDATE space
+ assert ( o_imgPtr == reinterpret_cast<void*>(SBE_IMG_VADDR),
+ "getSetSbeImage() - o_imgPtr is not at SBE_IMG_VADDR");
+
+ do{
+
+ // Clear out back half of page block to use as temp space
+ // for ECC injected SBE Image.
+ rc = mm_remove_pages(RELEASE,
+ reinterpret_cast<void*>
+ (SBE_ECC_IMG_VADDR),
+ SBE_ECC_IMG_MAX_SIZE);
+ if( rc )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSetSbeImage() - Error "
+ "from mm_remove_pages : rc=%d, HUID=0x%.8X.",
+ rc, TARGETING::get_huid(i_target) );
+ /*@
+ * @errortype
+ * @moduleid SBE_READ_SBE_IMAGE
+ * @reasoncode SBE_REMOVE_PAGES_FOR_EC
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc updateProcessorSbeSeeproms> mm_remove_pages
+ * RELEASE failed
+ * @custdesc A problem occurred while updating processor
+ * boot code.
+ */
+ err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ SBE_READ_SBE_IMAGE,
+ SBE_REMOVE_PAGES_FOR_EC,
+ TO_UINT64(SBE_ECC_IMG_VADDR),
+ TO_UINT64(rc),
+ true /*Add HB SW Callout*/ );
+
+ //Target isn't directly related to fail, but could be useful
+ // to see how far we got before failing.
+ ErrlUserDetailsTarget(i_target).addToLog(err);
+ err->collectTrace(SBE_COMP_NAME);
+ break;
+ }
+
+ /*****************************************/
+ /* Get Image Size */
+ /*****************************************/
+ err = getSbeImageSize(i_target,
+ o_imgPtr,
+ i_side,
+ o_image_size);
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"readSbeImage: - Error from "
+ "getSbeImageSize(): rc=0x%.4X, side=%d, HUID=0x%.8X.",
+ err->reasonCode(),
+ i_side, TARGETING::get_huid(i_target));
+ break;
+ }
+
+
+ /*****************************************/
+ /* Do Actual Read */
+ /*****************************************/
+ image_size_ECC = ALIGN_8((o_image_size*9)/8);
+
+ assert(image_size_ECC <= SBE_ECC_IMG_MAX_SIZE,
+ "getSetSbeImage() SBE Image with ECC too large");
+
+ // Read image to memory space
+ err = DeviceFW::deviceOp(
+ DeviceFW::READ,
+ i_target,
+ reinterpret_cast<void*>
+ (SBE_ECC_IMG_VADDR),
+ image_size_ECC,
+ DEVICE_EEPROM_ADDRESS(
+ l_seeprom,
+ SBE_IMAGE_SEEPROM_ADDRESS));
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"readSbeImage: - Error "
+ "from EEPROM op: rc=0x%.4X, seeprom=%d (side=%d). "
+ "HUID=0x%.8X. SBE_VADDR=0x%.16X, ECC_VADDR=0x%.16X, "
+ "size=0x%.8X, eccSize=0x%.8X, EEPROM offset=0x%X",
+ err->reasonCode(), l_seeprom, i_side,
+ TARGETING::get_huid(i_target),
+ SBE_IMG_VADDR, SBE_ECC_IMG_VADDR, o_image_size,
+ image_size_ECC, SBE_IMAGE_SEEPROM_ADDRESS);
+ break;
+ }
+
+ /*****************************************/
+ /* Remove ECC From Image */
+ /*****************************************/
+
+ // Clear destination
+ memset( o_imgPtr, 0, MAX_SEEPROM_IMAGE_SIZE );
+
+ // Remove ECC
+ eccStatus = PNOR::ECC::removeECC(reinterpret_cast<uint8_t*>
+ (SBE_ECC_IMG_VADDR),
+ reinterpret_cast<uint8_t*>
+ (o_imgPtr),
+ image_size_ECC);
+
+ // Fail if uncorrectable ECC
+ if ( eccStatus == PNOR::ECC::UNCORRECTABLE )
+ {
+ // There is an ECC issue with this SEEPROM
+
+ TRACFCOMP( g_trac_sbe,ERR_MRK"readSbeImage: ECC Error "
+ "On SBE Image Read eccStatus=%d sI=%d, sI_ECC="
+ "%d, HUID=0x%.8X, Seeprom %d (side=%d)",
+ eccStatus, o_image_size, image_size_ECC,
+ TARGETING::get_huid(i_target),
+ l_seeprom, i_side );
+
+ /*@
+ * @errortype
+ * @moduleid SBE_READ_SBE_IMAGE
+ * @reasoncode SBE_ECC_FAIL
+ * @userdata1[0:15] ECC Status
+ * @userdata1[16:31] SEEPROM Side
+ * @userdata1[32:63] Target HUID
+ * @userdata2[0:31] Size - No Ecc
+ * @userdata2[32:63] Size - ECC
+ * @devdesc ECC Fail Reading SBE Image
+ */
+ err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ SBE_READ_SBE_IMAGE,
+ SBE_ECC_FAIL,
+ TWO_UINT32_TO_UINT64(
+ ( (eccStatus << 16 ) |
+ l_seeprom ),
+ TARGETING::get_huid(i_target)),
+ TWO_UINT32_TO_UINT64(o_image_size,
+ image_size_ECC));
+
+ err->collectTrace(SBE_COMP_NAME);
+
+ err->addPartCallout(
+ i_target,
+ HWAS::SBE_SEEPROM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ ErrlUserDetailsTarget(i_target).addToLog(err);
+
+ break;
+
+ } // ECC check
+
+
+ // Read out SBE Version Info
+ bool seeprom_ver_ECC_fail = false;
+ err = getSeepromSideVersion(i_target,
+ l_seeprom,
+ o_image_version,
+ seeprom_ver_ECC_fail);
+
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"readSbeImage: - Error "
+ "from getSeepromSideVersion: rc=0x%.4X, seeprom=%d "
+ "(side=%d). HUID=0x%.8X",
+ err->reasonCode(), l_seeprom, i_side,
+ TARGETING::get_huid(i_target));
+ break;
+ }
+
+ else if (seeprom_ver_ECC_fail == true)
+ {
+ // For now, any issues will be addressed in SBE Update
+ // later in the IPL
+ TRACFCOMP( g_trac_sbe, ERR_MRK"readSbeImage: ECC fail=%d "
+ "Reading Seeprom Version seeprom=%d "
+ "(side=%d). HUID=0x%.8X",
+ seeprom_ver_ECC_fail, l_seeprom, i_side,
+ TARGETING::get_huid(i_target));
+ }
+
+ TRACDBIN(g_trac_sbe, "readSbeImage: SBE Info Version",
+ reinterpret_cast<uint8_t*>(&o_image_version),
+ sizeof(o_image_version));
+
+ }while(0);
+
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"readSbeImage() - eccStatus=%d, "
+ "size=0x%X, size_ECC=0x%X",
+ eccStatus, o_image_size, image_size_ECC);
+
+
+ return err;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t writeSbeImage(TARGETING::Target* i_target,
+ void* i_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t i_image_size,
+ sbeSeepromVersionInfo_t& io_version)
+
+{
+ TRACFCOMP( g_trac_sbe,
+ ENTER_MRK"writeSbeImage(): tgt=0x%X, i_side=%d "
+ "i_imgPtr=%p, i_image_size=0x%X",
+ TARGETING::get_huid(i_target), i_side, i_imgPtr, i_image_size);
+
+ errlHndl_t err = NULL;
+ int64_t rc = 0;
+ EEPROM::eeprom_chip_types_t l_seeprom = sbe_side_sync[i_side];
+ size_t image_size_ECC = 0;
+
+ // For Version Information
+ size_t sbeInfoSize = sizeof(sbeSeepromVersionInfo_t);
+ size_t sbeInfoSize_ECC = (sbeInfoSize*9)/8;
+
+ uint8_t * sbeInfo_data_ECC = static_cast<uint8_t*>
+ (malloc(sbeInfoSize_ECC));
+
+
+ // Need to ensure that io_imgPtr is at SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE
+ // since we need to use the VMM_VADDR_SBE_UPDATE space
+ assert ( i_imgPtr == reinterpret_cast<void*>(SBE_IMG_VADDR),
+ "writeSbeImage() - io_imgPtr is not at SBE_IMG_VADDR");
+
+ do{
+
+ // Clear out back half of page block to use as temp space
+ // for ECC injected SBE Image.
+ rc = mm_remove_pages(RELEASE,
+ reinterpret_cast<void*>
+ (SBE_ECC_IMG_VADDR),
+ SBE_ECC_IMG_MAX_SIZE);
+ if( rc )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"writeSbeImage() - Error "
+ "from mm_remove_pages : rc=%d, HUID=0x%.8X.",
+ rc, TARGETING::get_huid(i_target) );
+ /*@
+ * @errortype
+ * @moduleid SBE_WRITE_SBE_IMAGE
+ * @reasoncode SBE_REMOVE_PAGES_FOR_EC
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc updateProcessorSbeSeeproms> mm_remove_pages
+ * RELEASE failed
+ * @custdesc A problem occurred while updating processor
+ * boot code.
+ */
+
+ err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ SBE_WRITE_SBE_IMAGE,
+ SBE_REMOVE_PAGES_FOR_EC,
+ TO_UINT64(SBE_ECC_IMG_VADDR),
+ TO_UINT64(rc),
+ true /*Add HB SW Callout*/ );
+
+ //Target isn't directly related to fail, but could be useful
+ //to see how far we got before failing.
+ ErrlUserDetailsTarget(i_target).addToLog(err);
+ err->collectTrace(SBE_COMP_NAME);
+ break;
+ }
+
+ // Inject ECC
+ PNOR::ECC::injectECC(reinterpret_cast<uint8_t*>(i_imgPtr),
+ ALIGN_8(i_image_size),
+ reinterpret_cast<uint8_t*>
+ (SBE_ECC_IMG_VADDR));
+
+ /*****************************************/
+ /* Do Actual Write of Image */
+ /*****************************************/
+ image_size_ECC = ALIGN_8((i_image_size*9)/8);
+
+ assert(image_size_ECC <= SBE_ECC_IMG_MAX_SIZE,
+ "writeSbeImage() SBE Image with ECC too large");
+
+ err = deviceWrite(i_target,
+ reinterpret_cast<void*>
+ (SBE_ECC_IMG_VADDR),
+ image_size_ECC,
+ DEVICE_EEPROM_ADDRESS(
+ l_seeprom,
+ SBE_IMAGE_SEEPROM_ADDRESS));
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"writeSbeImage: - Error "
+ "from EEPROM op: rc=0x%.4X, seeprom=%d (side=%d). "
+ "HUID=0x%.8X. SBE_VADDR=0x%.16X, ECC_VADDR=0x%.16X, "
+ "size=0x%.8X, eccSize=0x%.8X, EEPROM offset=0x%X",
+ err->reasonCode(), l_seeprom, i_side,
+ TARGETING::get_huid(i_target),
+ SBE_IMG_VADDR, SBE_ECC_IMG_VADDR, i_image_size,
+ image_size_ECC, SBE_IMAGE_SEEPROM_ADDRESS);
+ break;
+ }
+
+ /********************************************/
+ /* Do Actual Write of Version Information */
+ /********************************************/
+
+ // Update the image crc in the version information
+ uint32_t image_crc = Util::crc32_calc(i_imgPtr, i_image_size);
+
+ memcpy( &(io_version.data_crc),
+ &image_crc,
+ sizeof(image_crc));
+
+ TRACDBIN( g_trac_sbe, "writeSbeImage: Version no ECC",
+ reinterpret_cast<uint8_t*>(&io_version), sizeof(io_version));
+
+ // Inject ECC
+ memset( sbeInfo_data_ECC, 0, sbeInfoSize_ECC);
+ PNOR::ECC::injectECC(reinterpret_cast<uint8_t*>(&io_version),
+ sbeInfoSize, sbeInfo_data_ECC);
+
+ TRACDBIN( g_trac_sbe, "writeSbeImage: Version with ECC",
+ sbeInfo_data_ECC, sbeInfoSize_ECC);
+
+ err = deviceWrite( i_target,
+ sbeInfo_data_ECC,
+ sbeInfoSize_ECC,
+ DEVICE_EEPROM_ADDRESS(
+ l_seeprom,
+ SBE_VERSION_SEEPROM_ADDRESS));
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"writeSbeImage: - Error "
+ "Writing SBE Version Info: rc=0x%.4X, "
+ "HUID=0x%.8X, seeprom=%d, side=%d",
+ err->reasonCode(),
+ TARGETING::get_huid(i_target), l_seeprom, i_side);
+ break;
+ }
+
+ }while(0);
+
+ // Free allocated memory
+ free(sbeInfo_data_ECC);
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"writeSetSbeImage()" );
+
+ return err;
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t getSbeImageSize(TARGETING::Target* i_target,
+ void* i_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t& o_image_size)
+{
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"geSbeImageSize(): tgt=0x%X, i_side=%d "
+ "i_imgPtr=%p, o_image_size=0x%X",
+ TARGETING::get_huid(i_target), i_side, i_imgPtr, o_image_size);
+
+ errlHndl_t err = NULL;
+ PNOR::ECC::eccStatus eccStatus = PNOR::ECC::CLEAN;
+ EEPROM::eeprom_chip_types_t l_seeprom = sbe_side_sync[i_side];
+ size_t image_size_ECC = 0;
+
+ // Need to ensure that i_imgPtr is at SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE
+ // since we need to use the VMM_VADDR_SBE_UPDATE space
+
+ assert ( i_imgPtr == reinterpret_cast<void*>(SBE_IMG_VADDR),
+ "getSbeImageSize() - i_imgPtr is not at SBE_IMG_VADDR");
+
+ do{
+ // Need to read the SbeXipHeader of the image to determine size
+ // of the image to read out.
+ // Using io_imgPtr space. First read our header+ECC from SBE
+ // Seeprom and then use space after that to put header without ECC
+
+
+ size_t hdr_size = ALIGN_8(sizeof(SbeXipHeader));
+ size_t hdr_size_ECC = (hdr_size * 9)/8;
+
+ uint8_t* hdr_ptr = reinterpret_cast<uint8_t*>(i_imgPtr) + hdr_size_ECC;
+
+ memset( i_imgPtr, 0, hdr_size_ECC + hdr_size );
+
+ TRACUCOMP( g_trac_sbe, INFO_MRK"getSetSbeImage() Reading "
+ "SbeXipHeader for Target 0x%X, Seeprom %d "
+ "(side=%d), size_ECC=0x%X (size=0x%X)",
+ TARGETING::get_huid(i_target),
+ l_seeprom, i_side, hdr_size_ECC, hdr_size );
+
+ err = DeviceFW::deviceOp( DeviceFW::READ,
+ i_target,
+ i_imgPtr,
+ hdr_size_ECC,
+ DEVICE_EEPROM_ADDRESS(
+ l_seeprom,
+ SBE_IMAGE_SEEPROM_ADDRESS));
+
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeImageSize: - Error "
+ "Reading SbeXipHeader: rc=0x%.4X, seeprom=%d (side=%d). "
+ "HUID=0x%.8X. size=0x%.8X, EEPROM offset=0x%X",
+ err->reasonCode(), l_seeprom, i_side,
+ TARGETING::get_huid(i_target), sizeof(SbeXipHeader),
+ SBE_IMAGE_SEEPROM_ADDRESS);
+ break;
+ }
+
+
+ TRACDBIN( g_trac_sbe,
+ "Data with ECC read from Seeprom",
+ i_imgPtr,
+ hdr_size_ECC );
+
+ // Remove ECC
+ eccStatus = PNOR::ECC::removeECC(
+ reinterpret_cast<uint8_t*>(i_imgPtr),
+ hdr_ptr,
+ hdr_size);
+
+ // Fail if uncorrectable ECC
+ if ( eccStatus == PNOR::ECC::UNCORRECTABLE )
+ {
+ TRACFCOMP( g_trac_sbe,ERR_MRK"getSbeImageSize: ECC Error "
+ "On SBE Image Read eccStatus=%d sI=%d, sI_ECC="
+ "%d, HUID=0x%.8X, Seeprom %d (side=%d)",
+ eccStatus, o_image_size, image_size_ECC,
+ TARGETING::get_huid(i_target),
+ l_seeprom, i_side );
+ /*@
+ * @errortype
+ * @moduleid SBE_GET_SBE_IMAGE_SIZE
+ * @reasoncode SBE_ECC_FAIL
+ * @userdata1[0:15] ECC Status
+ * @userdata1[16:31] SEEPROM Side
+ * @userdata1[32:63] Target HUID
+ * @userdata2[0:31] Size - No Ecc
+ * @userdata2[32:63] Size - ECC
+ * @devdesc ECC Fail Reading SBE Image
+ */
+ err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ SBE_GET_SBE_IMAGE_SIZE,
+ SBE_ECC_FAIL,
+ TWO_UINT32_TO_UINT64(
+ ( (eccStatus << 16 ) |
+ l_seeprom ),
+ TARGETING::get_huid(i_target)),
+ TWO_UINT32_TO_UINT64(o_image_size,
+ image_size_ECC));
+ err->collectTrace(SBE_COMP_NAME);
+ err->addPartCallout(
+ i_target,
+ HWAS::SBE_SEEPROM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ ErrlUserDetailsTarget(i_target).addToLog(err);
+
+ break;
+ }
+
+ TRACDBIN( g_trac_sbe,
+ "Data without ECC read from Seeprom",
+ hdr_ptr,
+ hdr_size );
+
+ o_image_size = (((SbeXipHeader*)hdr_ptr)->iv_imageSize);
+
+ }while(0);
+
+ TRACFCOMP( g_trac_sbe,
+ EXIT_MRK"getSbeImageSize(): o_image_size=0x%X", o_image_size );
+
+ return err;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+errlHndl_t resolveImageHBBaddr(TARGETING::Target* i_target,
+ void* io_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ PNOR::SideId i_pnorSideId,
+ bool& o_imageWasUpdated )
+{
+ errlHndl_t err = NULL;
+ uint64_t data = 0;
+ int rc = 0;
+ bool rc_fail_on_get = false; // 1=get failed, 0=set failed
+
+ o_imageWasUpdated = false;
+
+ TRACUCOMP( g_trac_sbe,
+ ENTER_MRK"resolveImageHBBaddr() - tgt=0x%X, i_side=%d, "
+ "i_pnorSideId=%d",
+ TARGETING::get_huid(i_target), i_side, i_pnorSideId);
+
+ do{
+
+ // Get info from PNOR
+ PNOR::SideInfo_t pnor_side_info;
+ err = PNOR::getSideInfo (i_pnorSideId, pnor_side_info);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "resolveImageHBBaddr() - Error returned "
+ "from PNOR::getSideInfo() rc=0x%.4X, Target UID=0x%X "
+ "i_pnorSideId",
+ err->reasonCode(),
+ TARGETING::get_huid(i_target), i_pnorSideId);
+ break;
+ }
+
+
+ // Only Need to Check/Update if PNOR has Other Side
+ // and Seeprom isn't pointing at PNOR's GOLDEN side
+ if ( ( pnor_side_info.hasOtherSide == true ) &&
+ ( pnor_side_info.isGolden == false ) )
+ {
+
+ // Read the MMIO offset associated with the HBB address
+ // from the image
+ rc = sbe_xip_get_scalar( io_imgPtr,
+ "standalone_mbox2_value",
+ &data);
+ if ( rc != 0 )
+ {
+ rc_fail_on_get = true; // get failed
+
+ TRACFCOMP( g_trac_sbe, ERR_MRK"resolveImageHBBaddr() - "
+ "sbe_xip_get_scalar() failed rc = 0x%X (%d)",
+ rc, rc_fail_on_get);
+ break;
+ }
+
+ if ( pnor_side_info.hbbMmioOffset == data )
+ {
+ TRACUCOMP( g_trac_sbe, "resolveImageHBBaddr: Image has MMIO "
+ "offset = 0x%X that matches PNOR MMIO="
+ "0x%X for HBB Address=0x%X",
+ data, pnor_side_info.hbbMmioOffset,
+ pnor_side_info.hbbAddress);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_sbe, "resolveImageHBBaddr: Image has MMIO "
+ "offset = 0x%X does NOT match PNOR MMIO="
+ "0x%X for HBB Address=0x%X. Updating Image",
+ data, pnor_side_info.hbbMmioOffset,
+ pnor_side_info.hbbAddress);
+
+ TRACDBIN (g_trac_sbe, "resolveImageHBBaddr: data", &data, 8 );
+
+ TRACDBIN (g_trac_sbe, "resolveImageHBBaddr: hbbMmioOffset",
+ &pnor_side_info.hbbMmioOffset, 8 );
+ TRACDBIN (g_trac_sbe, "resolveImageHBBaddr: hbbAddress",
+ &pnor_side_info.hbbAddress, 8);
+
+ rc = sbe_xip_set_scalar( io_imgPtr, "standalone_mbox2_value",
+ pnor_side_info.hbbMmioOffset);
+
+ if ( rc != 0 )
+ {
+ rc_fail_on_get = false; // set failed
+
+ TRACFCOMP( g_trac_sbe, ERR_MRK"resolveImageHBBaddr() - "
+ "sbe_xip_set_scalar() failed rc = 0x%X (%d)",
+ rc, rc_fail_on_get);
+ break;
+ }
+ o_imageWasUpdated = true;
+ }
+
+ }
+ else
+ {
+ // pnor_side_info.hasOtherSide is false
+ TRACUCOMP( g_trac_sbe, "resolveImageHBBaddr: PNOR only has "
+ "1 side - No Update Required");
+ }
+
+ }while(0);
+
+
+ if ( ( err == NULL ) && ( rc != 0) )
+ {
+ // We failed on get/set cmd above (already traced)
+
+ /*@
+ * @errortype
+ * @moduleid SBE_RESOLVE_HBB_ADDR
+ * @reasoncode SBE_IMAGE_GET_SET_SCALAR_FAIL
+ * @userdata1 Return Code of failed operation
+ * @userdata2 True/False if Get (true) or Set (false) Op failed
+ * @devdesc sbe_xip_get/set_scalar() failed when accessing the
+ HBB Address MMIO offset in 'standalone_mbox2_value'
+ * @custdesc A problem occurred while updating processor
+ * boot code.
+ */
+ err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ SBE_RESOLVE_HBB_ADDR,
+ SBE_IMAGE_GET_SET_SCALAR_FAIL,
+ TO_UINT64(rc),
+ TO_UINT64(rc_fail_on_get),
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace(SBE_COMP_NAME);
+ }
+
+
+ TRACUCOMP( g_trac_sbe,
+ EXIT_MRK"resolveImageHBBaddr() - o_imageWasUpdated = %d",
+ o_imageWasUpdated);
+
+ return err;
+}
+
+#ifdef CONFIG_BMC_IPMI
+/////////////////////////////////////////////////////////////////////
+void sbePreShutdownIpmiCalls( void )
+{
+ errlHndl_t err = NULL;
+
+ TRACFCOMP( g_trac_sbe, ENTER_MRK"sbePreShutdownIpmiCalls");
+
+ do{
+ uint16_t count = 0;
+ SENSOR::RebootCountSensor l_sensor;
+
+ // Read reboot count sensor
+ err = l_sensor.getRebootCount(count);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"sbePreShutdownIpmiCalls: "
+ "FAIL Reading Reboot Sensor Count. "
+ "Committing Error Log rc=0x%.4X eid=0x%.8X "
+ "plid=0x%.8X, but continuing shutdown",
+ err->reasonCode(),
+ err->eid(),
+ err->plid());
+ err->collectTrace(SBE_COMP_NAME);
+ errlCommit( err, SBE_COMP_ID );
+
+ // No Break - Still Do Watchdog Timer Call
+ }
+ else
+ {
+ // Increment Reboot Count Sensor
+ count++;
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"sbePreShutdownIpmiCalls: "
+ "Writing Reboot Sensor Count=%d", count);
+
+ err = l_sensor.setRebootCount( count );
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"sbePreShutdownIpmiCalls: "
+ "FAIL Writing Reboot Sensor Count to %d. "
+ "Committing Error Log rc=0x%.4X eid=0x%.8X "
+ "plid=0x%.8X, but continuing shutdown",
+ count,
+ err->reasonCode(),
+ err->eid(),
+ err->plid());
+ err->collectTrace(SBE_COMP_NAME);
+ errlCommit( err, SBE_COMP_ID );
+
+ // No Break - Still Do Watchdog Timer Call
+ }
+ }
+
+ // @todo RTC 124679 - Remove Once BMC Monitors Shutdown Attention
+ // Set Watchdog Timer To 10 seconds
+ const uint16_t SET_WD_TIMER_10_SECS = 10;
+ TRACFCOMP( g_trac_sbe,"sbePreShutdownIpmiCalls: "
+ "Set Watch Dog Timer To %d Seconds",
+ SET_WD_TIMER_10_SECS);
+
+ err = IPMIWATCHDOG::setWatchDogTimer(SET_WD_TIMER_10_SECS);
+ if(err)
+ {
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"sbePreShutdownIpmiCalls: "
+ "FAIL Setting Watch Dog Timer to %d seconds. "
+ "Committing Error Log rc=0x%.4X eid=0x%.8X "
+ "plid=0x%.8X, but continuing shutdown",
+ SET_WD_TIMER_10_SECS,
+ err->reasonCode(),
+ err->eid(),
+ err->plid());
+
+ err->collectTrace(SBE_COMP_NAME);
+ errlCommit(err, SBE_COMP_ID );
+ }
+
+ }while(0);
+
+ TRACFCOMP( g_trac_sbe, EXIT_MRK"sbePreShutdownIpmiCalls");
+
+ return;
+}
+#endif // CONFIG_BMC_IPMI
+
+
+} //end SBE Namespace
diff --git a/src/usr/sbe/sbe_resolve_sides.H b/src/usr/sbe/sbe_resolve_sides.H
new file mode 100644
index 000000000..42f727ae6
--- /dev/null
+++ b/src/usr/sbe/sbe_resolve_sides.H
@@ -0,0 +1,259 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbe/sbe_resolve_sides.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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_SBE_RESOLVE_SIDES_H
+#define __SBE_SBE_RESOLVE_SIDES_H
+
+
+#include <stdint.h>
+#include <builtins.h>
+#include <errl/errlentry.H>
+#include <pnor/pnorif.H>
+#include <util/align.H>
+#include <vmmconst.h>
+#include <targeting/common/targetservice.H>
+#include <i2c/eepromif.H>
+#include "sbe_update.H"
+
+namespace SBE
+{
+ /******************************************/
+ /* Constants */
+ /******************************************/
+
+ // This seeprom is a candidate to be READ_ONLY (ie, not updated)
+ const PNOR::sbeSeepromSide_t READ_ONLY_SEEPROM = PNOR::SBE_SEEPROM1;
+
+ // Used to keep SBE Seeproms in sync with EEPROM::eeprom_chip_types_t
+ const EEPROM::eeprom_chip_types_t sbe_side_sync[2] =
+ { EEPROM::SBE_PRIMARY,
+ EEPROM::SBE_BACKUP };
+
+ /******************************************/
+ /* Enums */
+ /******************************************/
+
+ // Actions can be combined
+ enum
+ {
+ NO_ACTIONS = 0x00000000,
+ REIPL = 0x00000001,
+
+ // Use PNOR::ALTERNATE SideId for HBB Address info
+ USE_PNOR_ALT_SIDE = 0x00000002,
+
+ // NOTE: These next 2 values are mutually exclusive
+ CHECK_WORKING_HBB = 0x00000010,
+ COPY_READ_ONLY_TO_WORKING = 0x00000020,
+ };
+
+ /******************************************/
+ /* Structs */
+ /******************************************/
+ struct sbeResolveState_t
+ {
+
+ // Target Information
+ TARGETING::Target* tgt;
+
+ PNOR::sbeSeepromSide_t cur_side; // aka 'booted' side
+ PNOR::sbeSeepromSide_t alt_side; // non-booted/non-cur side
+ PNOR::sbeSeepromSide_t update_side; // side to be updated
+
+ // Info from PNOR
+ PNOR::SideId pnor_sideId;
+ char pnor_side; /**< name of the side either A or B */
+ bool pnor_isGolden; /**< True if side is golden */
+ bool pnor_hasOtherSide; /**< True if a valid alternate side exists*/
+
+ uint32_t actions;
+
+ // Constructor to default certain values
+ sbeResolveState_t() :
+ tgt(NULL), cur_side(PNOR::SBE_SEEPROM_INVALID),
+ alt_side(PNOR::SBE_SEEPROM_INVALID),
+ update_side(PNOR::SBE_SEEPROM_INVALID),
+ pnor_sideId(PNOR::WORKING),
+ pnor_side(NULL),
+ pnor_isGolden(false), pnor_hasOtherSide(false),
+ actions(NO_ACTIONS)
+ {}
+
+ };
+
+
+ /******************************************/
+ /* Functions -- High Level Functions */
+ /******************************************/
+
+ /**
+ * @brief Collects SBE Side Information for a specifc target
+ *
+ * @param[io/out] io_sideState Struct containing SBE State of the target
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t getSideState(sbeResolveState_t& io_sideState);
+
+ /**
+ * @brief Analyze and Determine Update Actions for a specific target
+ *
+ * @param[io/out] io_sideState Struct containing SBE State of the target
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t getSideActions(sbeResolveState_t& io_sideState);
+
+ /**
+ * @brief Performs the Update Actions for a specific target
+ *
+ * @param[io/out] io_sideState Struct containing SBE State of the target
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t performSideActions(sbeResolveState_t& io_sideState);
+
+
+
+ /******************************************/
+ /* Functions -- System Access */
+ /******************************************/
+
+
+ /**
+ * @brief Read SBE Image from SBE Seeprom
+ *
+ * @param[in] i_target Target processor
+ *
+ * @param[out] o_imgPtr Pointer to SBE image in memory
+ * Memory for this pointer is expected to be
+ * pre-alloacted
+ * NOTE: ECC is handled internally in this
+ * function. io_imgPtr points to non-ECC image
+ *
+ * @param[in] i_side Seeprom Side to access
+ *
+ * @param[in] o_image_size The size of the image (non-ECC)
+ *
+ * @param[in] o_version SBE Version struct from seeprom (non-ECC)
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t readSbeImage(TARGETING::Target* i_target,
+ void* o_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t& o_image_size,
+ sbeSeepromVersionInfo_t& o_version);
+
+ /**
+ * @brief Write SBE Image from SBE Seeprom
+ *
+ * @param[in] i_target Target processor
+ *
+ * @param[in] i_imgPtr Pointer to SBE image in memory
+ * Memory for this pointer is expected to be
+ * pre-alloacted
+ * NOTE: ECC is handled internally in this function
+ * i_imgPtr points to non-ECC image
+ *
+ * @param[in] i_side Seeprom Side to access
+ *
+ * @param[in] i_image_size Size of image to write (non-ECC)
+ *
+ * @param[in] io_version SBE Version struct to write (non-ECC)
+ * NOTE: data_crc updated in this function
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t writeSbeImage(TARGETING::Target* i_target,
+ void* i_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t i_image_size,
+ sbeSeepromVersionInfo_t& io_version);
+
+
+ /**
+ * @brief Read SBE Image Header from SBE Seeprom and gets the
+ * Image size from the heaser
+ *
+ * @param[in] i_target Target processor
+ *
+ * @param[out] i_imgPtr Pointer to pre-allocated memory to be used
+ * for different operations
+ *
+ * @param[in] i_side Seeprom Side to access
+ *
+ * @param[in] o_image_size The size of the image (non-ECC)
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t getSbeImageSize(TARGETING::Target* i_target,
+ void* i_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ size_t& o_image_size);
+
+
+
+
+ /******************************************/
+ /* Functions -- Helper Functions */
+ /******************************************/
+
+ /**
+ * @brief Check and Update (if necessary) the HBB Address MMIO offset
+ * in a customized SBE Image for the current Processor
+ *
+ * @param[in] i_target Target processor to customize
+ *
+ * @param[in/out] io_imgPtr Pointer to SBE image in memory
+ * Memory for this pointer is expected to be
+ * pre-alloacted
+ *
+ * @param[in] i_side Seeprom Side to access
+ *
+ * @param[in] i_pnorSideId PNOR side to get information for
+ *
+ * @param[out] o_imageWasUpdated Set to true if Image was updated;
+ * otherwise false
+ *
+ * @return errlHndl_t Error log handle on failure.
+ */
+ errlHndl_t resolveImageHBBaddr(TARGETING::Target* i_target,
+ void* io_imgPtr,
+ PNOR::sbeSeepromSide_t i_side,
+ PNOR::SideId i_pnorSideId,
+ bool& o_imageWasUpdated);
+
+#ifdef CONFIG_BMC_IPMI
+ /**
+ * @brief Performs any necessary IPMI calls before shutting down the system
+ *
+ * @return void Any generated Error Logs will be commited before the
+ * function returns
+ */
+ void sbePreShutdownIpmiCalls( void );
+#endif
+
+} //end namespace SBE
+#endif
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index 97a048426..562798b20 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -50,6 +50,7 @@
#include <sbe/sbeif.H>
#include <sbe/sbereasoncodes.H>
#include "sbe_update.H"
+#include "sbe_resolve_sides.H"
// fapi support
#include <fapi.H>
@@ -112,6 +113,25 @@ namespace SBE
do{
+#ifdef CONFIG_NO_SBE_UPDATES
+ TRACFCOMP( g_trac_sbe, INFO_MRK"updateProcessorSbeSeeproms() - "
+ "SBE updates not configured");
+ break;
+#endif
+
+#ifdef CONFIG_SBE_UPDATE_SEQUENTIAL
+ // Check if FSP-services are enabled and if we're running in simics
+ if ( !INITSERVICE::spBaseServicesEnabled() &&
+ !Util::isSimicsRunning() )
+ {
+ assert (false, "resolveProcessorSbeSeeproms() - "
+ "SBE_UPDATE_SEQUENTIAL mode, but FSP-services are not "
+ "enabled - Invalid Configuration");
+ }
+ // else - continue on
+#endif
+
+
// Get Target Service, and the system target.
TargetService& tS = targetService();
TARGETING::Target* sys = NULL;
@@ -204,11 +224,6 @@ namespace SBE
err = NULL;
}
-#ifdef CONFIG_NO_SBE_UPDATES
- TRACFCOMP( g_trac_sbe, INFO_MRK"updateProcessorSbeSeeproms() - "
- "SBE updates not configured");
- break;
-#endif
for(uint32_t i=0; i<procList.size(); i++)
{
@@ -277,7 +292,6 @@ namespace SBE
/**********************************************/
if ((err == NULL) && (sbeState.update_actions & DO_UPDATE))
{
-
err = performUpdateActions(sbeState);
if (err)
{
@@ -328,7 +342,6 @@ namespace SBE
} //end of Target for loop collecting each target's SBE State
-
/**************************************************************/
/* Perform System Operation */
/**************************************************************/
@@ -355,7 +368,7 @@ namespace SBE
}
#ifdef CONFIG_BMC_IPMI
- // @todo RTC 120734 reset system's reboot count via IPMI sensor
+ sbePreShutdownIpmiCalls();
#endif
TRACFCOMP( g_trac_sbe,
@@ -685,14 +698,15 @@ namespace SBE
do{
- // @todo RTC 120734 - before customizing, ensure correct HBB address
- // is set in the necessary attribute
-
// cast OUR type of target to a FAPI type of target.
const fapi::Target
l_fapiTarg(fapi::TARGET_TYPE_PROC_CHIP,
(const_cast<TARGETING::Target*>(i_target)));
+ // NOTE: The p8_xip_customize_procedure uses SBE_IMAGE_OFFSET
+ // attribute for HBB address value. Purpsely leaving this
+ // attribute as-is for now and will do the check for HBB address
+ // later.
// The p8_xip_customize() procedure tries to include as much core
// information as possible, but is limited by SBE Image size
@@ -871,7 +885,6 @@ namespace SBE
HWAS::SRCI_PRIORITY_HIGH );
}
-
}while(0);
TRACUCOMP( g_trac_sbe,
@@ -1715,6 +1728,26 @@ namespace SBE
// The Customized Image For This Target Still Resides In
// The SBE Update VMM Space: SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE
+#ifdef CONFIG_SBE_UPDATE_INDEPENDENT
+ // Ensure HBB address value in the customized image is correct
+ // for this side
+ bool imageWasUpdated=false;
+ err = resolveImageHBBaddr ( io_sbeState.target,
+ reinterpret_cast<void*>(SBE_IMG_VADDR),
+ ((io_sbeState.seeprom_side_to_update ==
+ EEPROM::SBE_PRIMARY ) ?
+ PNOR::SBE_SEEPROM0 :
+ PNOR::SBE_SEEPROM1 ),
+ PNOR::WORKING,
+ imageWasUpdated );
+
+ if (imageWasUpdated == true )
+ {
+ TRACUCOMP( g_trac_sbe, ERR_MRK"updateSeepromSide() - "
+ "HBB Address's MMIO Offset Updated in Image");
+ }
+
+#endif
// Inject ECC
// clear out back half of page block to use as temp space
@@ -1941,7 +1974,6 @@ namespace SBE
io_sbeState.seeprom_0_ver.data_crc, isSimics_check);
}
-
/**************************************************************/
/* Compare SEEPROM 1 with PNOR and Customized Image CRC -- */
/* -- dirty or clean? */
@@ -2153,22 +2185,55 @@ namespace SBE
#ifdef CONFIG_SBE_UPDATE_INDEPENDENT
// The 2 SBE SEEPROMs are independent of each other
- // Determine if PNOR is 1- or 2-sided and if there is a
- // GOLDEN boot involved
+ // Determine if PNOR is 1- or 2-sided and if the current
+ // Seeprom is pointing at PNOR's GOLDEN side
+
+ PNOR::SideId tmp_side = PNOR::WORKING;
+ PNOR::SideInfo_t pnor_side_info;
+ err = PNOR::getSideInfo (tmp_side, pnor_side_info);
+ if ( err )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "SBE Update() - Error returned from "
+ "PNOR::getSideInfo() rc=0x%.4X, Target UID=0x%X",
+ err->reasonCode(),
+ TARGETING::get_huid(io_sbeState.target));
+ break;
+ }
-#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT
+ TRACUCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: PNOR Info: "
+ "side-%c, sideId=0x%X, isGolden=%d, hasOtherSide=%d",
+ TARGETING::get_huid(io_sbeState.target),
+ pnor_side_info.side, pnor_side_info.id,
+ pnor_side_info.isGolden, pnor_side_info.hasOtherSide);
- // @todo RTC 120734 - ask PNOR if we are in "GOLDEN" mode,
- // which would mean that we are booting off the the GOLDEN
- // SBE SEEPROM which corresponds to the GOLDEN side of PNOR
-/*
- if (true)
+ if ( pnor_side_info.isGolden == true )
{
// If true, nothing to do (covered in istep 6 function)
l_actions = CLEAR_ACTIONS;
TRACFCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: "
- "Booting GOLDEN SBE SEEPROM in PNOR 2-sided Mode. "
+ "Booting READ_ONLY SEEPROM pointing at PNOR's "
+ "GOLDEN side. No updates for cur side=%d. Continue "
+ "IPL. (sit=0x%.2X, act=0x%.8X flags=0x%.2X)",
+ TARGETING::get_huid(io_sbeState.target),
+ io_sbeState.cur_seeprom_side,
+ i_system_situation, l_actions,
+ io_sbeState.mvpdSbKeyword.flags);
+ break;
+ }
+
+ else if ( ( pnor_side_info.hasOtherSide == false ) &&
+ ( io_sbeState.cur_seeprom_side == READ_ONLY_SEEPROM ) )
+ {
+ // Even though current seeprom is not pointing at PNOR's
+ // GOLDEN side, treat like READ_ONLY if booting from READ_ONLY
+ // seeprom and and PNOR does not have another side - No Update
+ // (ie, Palmetto configuration)
+ l_actions = CLEAR_ACTIONS;
+
+ TRACFCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: "
+ "Treating cur like READ_ONLY SBE SEEPROM. "
"No updates for cur side=%d. Continue IPL. "
"(sit=0x%.2X, act=0x%.8X flags=0x%.2X)",
TARGETING::get_huid(io_sbeState.target),
@@ -2179,22 +2244,14 @@ namespace SBE
}
else // proceed to update this side
{
+ // proceed to update this side
TRACUCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: "
- "NOT Booting GOLDEN SBE SEEPROM in PNOR 2-sided "
- "mode. Checking for update on cur side=%d ",
+ "NOT Booting READ_ONLY SEEPROM. Check for update "
+ "on cur side=%d ",
TARGETING::get_huid(io_sbeState.target),
io_sbeState.cur_seeprom_side)
}
-*/
-#else
- // @todo RTC 120734 - check this assumption
- // Assume that we're only checking/updating the current side
- TRACUCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: "
- "PNOR 1-sided so only check for update on cur side=%d",
- TARGETING::get_huid(io_sbeState.target),
- io_sbeState.cur_seeprom_side);
-#endif
// Check for clean vs. dirty only on cur side
if ( i_system_situation & SITUATION_CUR_IS_DIRTY )
@@ -2203,6 +2260,7 @@ namespace SBE
l_actions |= IPL_RESTART;
l_actions |= DO_UPDATE;
l_actions |= UPDATE_SBE;
+ l_actions |= UPDATE_MVPD; // even though flags byte not updated
// Set Update side to cur
io_sbeState.seeprom_side_to_update =
OpenPOWER on IntegriCloud