diff options
author | Mike Baiocchi <mbaiocch@us.ibm.com> | 2018-04-19 06:34:23 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-05-07 09:54:48 -0400 |
commit | 22b6130039608d9cb68cd023130b17706a31d1aa (patch) | |
tree | c78d8fcb459f1868ac340df1e9ebdc20b9d828dc /src/usr | |
parent | fbea67f16d58a24d78797e1a080f21020e63b4a9 (diff) | |
download | talos-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/usr')
-rwxr-xr-x | src/usr/i2c/i2c.C | 15 | ||||
-rw-r--r-- | src/usr/isteps/istep10/call_host_slave_sbe_update.C | 204 |
2 files changed, 211 insertions, 8 deletions
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(¬Present).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(); |