Skip to content

Commit

Permalink
Rediscover I2C Targets after Host I2C Reset
Browse files Browse the repository at this point in the history
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/58125
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>
Reviewed-by: ILYA SMIRNOV <ismirno@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
  • Loading branch information
mabaiocchi authored and Nicholas E. Bofferding committed May 4, 2018
1 parent f7a5aa5 commit deebbaa
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/include/usr/isteps/istep_reasoncodes.H
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/**
Expand Down Expand Up @@ -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,
};

};
Expand Down
15 changes: 8 additions & 7 deletions src/usr/i2c/i2c.C
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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 );

Expand Down
204 changes: 203 additions & 1 deletion src/usr/isteps/istep10/call_host_slave_sbe_update.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2016 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand All @@ -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>
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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();
Expand Down

0 comments on commit deebbaa

Please sign in to comment.