summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMike Baiocchi <mbaiocch@us.ibm.com>2018-04-19 06:34:23 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-05-07 09:54:48 -0400
commit22b6130039608d9cb68cd023130b17706a31d1aa (patch)
treec78d8fcb459f1868ac340df1e9ebdc20b9d828dc /src
parentfbea67f16d58a24d78797e1a080f21020e63b4a9 (diff)
downloadtalos-hostboot-22b6130039608d9cb68cd023130b17706a31d1aa.tar.gz
talos-hostboot-22b6130039608d9cb68cd023130b17706a31d1aa.zip
Rediscover I2C Targets after Host I2C Reset
It's possible that some targets that use I2C to detect if they are present might not be present after a system re-IPLs and performs a FSI I2C Reset. Therefore, later in the IPL, after a Host I2C Reset sequence an attempt to rediscover any of these targets is made. If any new targets are found, the system will re-IPL. Currently only supporting looking for DIMMs now on OpenPower systems with securemode enabled. Change-Id: I010135231f2f74869529a3dbc3344413b6d19dc9 RTC:178973 Backport:release-op920 CQ:SW427365 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57744 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: ILYA SMIRNOV <ismirno@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> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/isteps/istep_reasoncodes.H2
-rwxr-xr-xsrc/usr/i2c/i2c.C15
-rw-r--r--src/usr/isteps/istep10/call_host_slave_sbe_update.C204
3 files changed, 213 insertions, 8 deletions
diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H
index c0f30679a..01aa61bca 100644
--- a/src/include/usr/isteps/istep_reasoncodes.H
+++ b/src/include/usr/isteps/istep_reasoncodes.H
@@ -60,6 +60,7 @@ namespace ISTEP
MOD_SET_IPL_PARMS = 0x1D,
MOD_OCC_XSTOP_HANDLER = 0x1E,
MOD_VERIFY_AND_MOVE_PAYLOAD = 0x1F,
+ MOD_REDISCOVER_I2C_TARGETS = 0x20,
};
/**
@@ -115,6 +116,7 @@ namespace ISTEP
RC_PREVENT_REBOOT_IN_MFG_TERM_MODE = ISTEP_COMP_ID | 0x36,
RC_FAILED_WRITE_SPR = ISTEP_COMP_ID | 0x37,
RC_FAILED_TO_BOOT_SBE = ISTEP_COMP_ID | 0x38,
+ RC_REDISCOVERED_TARGETS = ISTEP_COMP_ID | 0x39,
};
};
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 950f7bbff..5749ba115 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -1120,10 +1120,11 @@ bool i2cPresence( TARGETING::Target * i_target,
uint64_t i_engine,
uint64_t i_devAddr )
{
- TRACUCOMP(g_trac_i2c, ENTER_MRK"i2cPresence(): tgt=0x%X: e/p/devAddr="
- "%d/%d/0x%X", TARGETING::get_huid(i_target), i_engine,
+ TRACUCOMP(g_trac_i2c, ENTER_MRK"i2cPresence(): tgt=0x%X: e%d/p%d/"
+ "devAddr=0x%X", TARGETING::get_huid(i_target), i_engine,
i_port, i_devAddr );
+
errlHndl_t err = NULL;
bool l_mutex_success = false;
bool l_present = false;
@@ -1324,9 +1325,9 @@ bool i2cPresence( TARGETING::Target * i_target,
if( err )
{
TRACFCOMP( g_trac_i2c,
- ERR_MRK"i2cPresence() Error!"
- "tgt=0x%X",
- TARGETING::get_huid(i_target));
+ ERR_MRK"i2cPresence() Error! "
+ "tgt=0x%X: e%d/p%d/devAddr=0x%X",
+ TARGETING::get_huid(i_target), i_engine, i_port, i_devAddr);
errlCommit(err,
I2C_COMP_ID);
@@ -1342,8 +1343,8 @@ bool i2cPresence( TARGETING::Target * i_target,
args.engine );
}
- TRACUCOMP(g_trac_i2c, EXIT_MRK"i2cPresence(): tgt=0x%X: e/p/devAddr="
- "%d/%d/0x%X: l_present=%d",
+ TRACUCOMP(g_trac_i2c, EXIT_MRK"i2cPresence(): tgt=0x%X: e%d/p%d/"
+ "devAddr=0x%X: l_present=%d",
TARGETING::get_huid(i_target), i_engine, i_port, i_devAddr,
l_present );
diff --git a/src/usr/isteps/istep10/call_host_slave_sbe_update.C b/src/usr/isteps/istep10/call_host_slave_sbe_update.C
index 147749da1..e8d436709 100644
--- a/src/usr/isteps/istep10/call_host_slave_sbe_update.C
+++ b/src/usr/isteps/istep10/call_host_slave_sbe_update.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,10 @@
#include <errl/errludtarget.H>
#include <errl/errlmanager.H>
#include <isteps/hwpisteperror.H>
+#include <isteps/istep_reasoncodes.H>
#include <initservice/isteps_trace.H>
+#include <initservice/istepdispatcherif.H>
+#include <initservice/initserviceif.H>
// targeting support
#include <targeting/common/commontargeting.H>
@@ -36,7 +39,17 @@
#include <sbe/sbeif.H>
#include <pnor/pnorif.H>
#include <i2c/i2cif.H>
+#include <console/consoleif.H>
+#include <config.h>
+#ifdef CONFIG_BMC_IPMI
+#include <ipmi/ipmisensor.H>
+#endif
+#include <sys/time.h>
+#include <hwas/common/hwasCommon.H>
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
using namespace ISTEP_ERROR;
using namespace ISTEP;
@@ -45,6 +58,187 @@ using namespace ERRORLOG;
namespace ISTEP_10
{
+
+errlHndl_t rediscoverI2CTargets(void)
+{
+ errlHndl_t err = nullptr;
+ size_t dimm_count_before = 0;
+ size_t dimm_count_after = 0;
+
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK
+ "rediscoverI2CTargets" );
+ do
+ {
+ if ((SECUREBOOT::enabled() == false ) ||
+ (INITSERVICE::spBaseServicesEnabled() == true ))
+ {
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "rediscoverI2CTargets: skipping because either security "
+ "(%d) is not enabled or FSP-based system (%d)",
+ SECUREBOOT::enabled(),
+ INITSERVICE::spBaseServicesEnabled());
+
+ break;
+ }
+
+ // find CLASS_SYS (the top level target)
+ Target* pSys = nullptr;
+ targetService().getTopLevelTarget(pSys);
+ assert(pSys, "rediscoverI2CTargets: pSys is nullptr");
+
+ // find list of all we need to call platPresenceDetect against
+ PredicateCTM predDimm(CLASS_LOGICAL_CARD, TYPE_DIMM);
+ PredicatePostfixExpr checkExpr;
+
+ // Look for the ones that are 'not present'
+ PredicateHwas notPresent;
+ notPresent.present(false);
+
+ checkExpr.push(&predDimm).push(&notPresent).And();
+
+ TargetHandleList pDimmList;
+ targetService().getAssociated( pDimmList, pSys,
+ TargetService::CHILD, TargetService::ALL, &checkExpr );
+
+ dimm_count_before = pDimmList.size();
+ if ( dimm_count_before == 0 )
+ {
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "rediscoverI2CTargets: pDimmList has size of %d meaning "
+ "no DIMMs to discover",
+ dimm_count_before);
+ break;
+ }
+
+ // Pass this list to the hwas platform-specific api to reevaluate if
+ // these targets are now present
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "rediscoverI2CTargets: pDimmList size before: %d",
+ dimm_count_before);
+ err = HWAS::platPresenceDetect(pDimmList);
+ if (err)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "rediscoverI2CTargets: HWAS::platPresenceDetect "
+ "returned err plid=0x%X, rc=0x%X",
+ err->plid(), err->reasonCode());
+ break;
+ }
+
+ // HWAS::platPresenceDetect only keeps present targets, so save that
+ // count here
+ dimm_count_after = pDimmList.size();
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "rediscoverI2CTargets: pDimmList size after: %d (was %d)",
+ dimm_count_after, dimm_count_before);
+
+ if ( dimm_count_after > 0 )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
+ "rediscoverI2CTargets: New DIMM(s) detected: pDimmList "
+ "size before=%d, after=%d. Requesting reboot",
+ dimm_count_before, dimm_count_after);
+
+ uint32_t huid0 = get_huid(pDimmList.at(0));
+ uint32_t huid1 = 0;
+ if ( dimm_count_after >= 2)
+ {
+ huid1 = get_huid(pDimmList.at(1));
+ }
+
+ // Create info log
+
+ /*@
+ * @errortype
+ * @moduleid ISTEP::MOD_REDISCOVER_I2C_TARGETS
+ * @reasoncode ISTEP::RC_REDISCOVERED_TARGETS
+ * @userdata1[0:31] HUID of 1st rediscovered target
+ * @userdata1[31:63] HUID of 2nd rediscovered target, if applicable
+ * @userdata2[0:31] Target Count Before Rediscover Attempt
+ * @userdata2[31:63] Target Count After Rediscover Attempt
+ * @devdesc Targets detected via I2C were rediscovered
+ * after an I2C reset. Reboot to add to config
+ * @custdesc A problem occurred during the IPL of the
+ * system and the system will reboot.
+ */
+ err = new ErrlEntry(ERRL_SEV_INFORMATIONAL,
+ ISTEP::MOD_REDISCOVER_I2C_TARGETS,
+ ISTEP::RC_REDISCOVERED_TARGETS,
+ TWO_UINT32_TO_UINT64(huid0,
+ huid1),
+ TWO_UINT32_TO_UINT64(dimm_count_before,
+ dimm_count_after));
+ err->collectTrace(ISTEP_COMP_NAME);
+ err->collectTrace(HWAS_COMP_NAME);
+
+ // Add Rediscovered Targets To The Error Log
+ for ( auto l_tgt : pDimmList )
+ {
+ ErrlUserDetailsTarget(l_tgt).addToLog(err);
+ }
+
+ // Commit Error Log here since requesting reboot and not returning
+ // error log to the caller
+ errlCommit(err, ISTEP_COMP_ID);
+
+#ifdef CONFIG_CONSOLE
+ CONSOLE::displayf(ISTEP_COMP_NAME,"Requesting Reboot after DIMM(s) "
+ "were rediscovered after I2C Reset");
+ CONSOLE::flush();
+#endif
+
+#ifdef CONFIG_BMC_IPMI
+ uint16_t count = SENSOR::DEFAULT_REBOOT_COUNT;
+ SENSOR::RebootCountSensor l_sensor;
+
+ // Set reboot count to default value
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,INFO_MRK
+ "rediscoverI2CTargets: Writing Reboot Sensor Count=%d",
+ count);
+
+ auto new_err = l_sensor.setRebootCount( count );
+ if ( new_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"rediscoverI2CTargets: "
+ "FAIL Writing Reboot Sensor Count to %d. "
+ "Committing Error Log rc=0x%.4X eid=0x%.8X "
+ "plid=0x%.8X, but continuing shutdown",
+ count,
+ new_err->reasonCode(),
+ new_err->eid(),
+ new_err->plid());
+ new_err->collectTrace(ISTEP_COMP_NAME);
+ errlCommit( new_err, ISTEP_COMP_ID );
+
+ // No Break - Still send chassis power cycle
+ }
+
+ // Initiate a graceful power cycle
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,INFO_MRK
+ "rediscoverI2CTargets: requesting power cycle");
+ INITSERVICE::requestReboot();
+
+ // sleep here to give IPMI code so that the istep doesn't
+ // continue with SBE Update
+ while (true)
+ {
+ nanosleep(60,0); // 60 seconds
+ }
+#endif
+
+
+ }
+
+ } while(0);
+
+ TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace,EXIT_MRK
+ "rediscoverI2CTargets: err plid=0x%X rc=0x%X",
+ ERRL_GETPLID_SAFE(err), ERRL_GETRC_SAFE(err) );
+
+ return err;
+}
+
void* call_host_slave_sbe_update (void *io_pArgs)
{
errlHndl_t l_errl = NULL;
@@ -67,6 +261,14 @@ void* call_host_slave_sbe_update (void *io_pArgs)
errlCommit( l_errl, HWPF_COMP_ID );
}
+ // Attempt to rediscover any I2C devices after the above reset
+ l_errl = rediscoverI2CTargets();
+ if (l_errl)
+ {
+ // Commit error and keep going
+ errlCommit( l_errl, HWPF_COMP_ID );
+ }
+
// Call to check state of Processor SBE SEEPROMs and
// make any necessary updates
l_errl = SBE::updateProcessorSbeSeeproms();
OpenPOWER on IntegriCloud