diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2019-02-21 19:24:11 -0600 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2019-03-01 09:30:09 -0600 |
commit | b8720c117759a6873256835da8fb52d31199a3b7 (patch) | |
tree | 80a32340f154e51d57fad1de4202fc367d89526d /src | |
parent | d2899da82cb004acbcba439673dc1dfb02ae6fb6 (diff) | |
download | talos-hostboot-b8720c117759a6873256835da8fb52d31199a3b7.tar.gz talos-hostboot-b8720c117759a6873256835da8fb52d31199a3b7.zip |
Reset Engine E to handle NVDIMMs
Force a reset of Engine E during MPIPL if we have NVDIMMs present.
This is required to clear out any latent runtime usage that may still
be laying around (specifically an active i2c interrupt).
CQ: SW457992
Change-Id: Ie5191fd71c07b903af482e2eb57295ab91f2a6f2
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72370
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/isteps/istep06/host_init_fsi.C | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/usr/isteps/istep06/host_init_fsi.C b/src/usr/isteps/istep06/host_init_fsi.C index 47941a3ea..2e294893e 100644 --- a/src/usr/isteps/istep06/host_init_fsi.C +++ b/src/usr/isteps/istep06/host_init_fsi.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -111,6 +111,65 @@ i2cEngineSelect find_proc_i2c_engines_for_tpm ( void ) return static_cast<i2cEngineSelect>(engineSelect); } +/* @brief Find Processor I2C Engines Connected to NVDIMMs + * + * This helper function loops through all of the DIMMs in the system, + * checks if they are an NVDIMM, and finds all of the Processors + * that serve as their I2C Masters. It then keeps track of + * which processor I2C engine(s) are used. + * + * @return i2cEngineSelect - bit-wise enum indicating which processor engine(s) + * were found + */ +i2cEngineSelect find_proc_i2c_engines_for_nvdimms ( void ) +{ + int engineSelect = static_cast<int>(I2C_ENGINE_SELECT_NONE); + +#ifdef CONFIG_NVDIMM + // Get all functional DIMMs + // Functional is valid this early in the boot because we only call this in MPIPL + TargetHandleList dimmList; + getAllLogicalCards(dimmList, TYPE_DIMM, true ); + + for (auto dimm : dimmList) + { + if( isNVDIMM(dimm) ) + { + ATTR_EEPROM_NV_INFO_type nvdimmData = + dimm->getAttr<ATTR_EEPROM_NV_INFO>(); + + TargetHandle_t proc_target = nullptr; + proc_target = targetService().toTarget( nvdimmData.i2cMasterPath ); + + // If NVDIMM is connected to a processor then keep track + // of what engine needs to be reset + assert( proc_target->getAttr<ATTR_TYPE>() == TYPE_PROC, + "find_proc_i2c_engines_for_nvdimms: Unsupported i2c master type for NVDIMM" ); + + engineSelect |= + static_cast<int>(i2cEngineToEngineSelect(nvdimmData.engine)); + } + } + + // There should only be 1 or 0 such bus per processor. So if we found multiple + // engines then we know that there are different proc/engine combinations + // and we'd need a I2C reset interface to support that. This check here + // makes sure we add that support when its necessary. + assert(__builtin_popcount(engineSelect)<=1, + "find_proc_i2c_engines_for_nvdimms: Only one engine should be found"); + +#endif + + if( engineSelect != I2C_ENGINE_SELECT_NONE ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "Found NVDIMM i2c master at 0x%X", + engineSelect ); + } + + return static_cast<i2cEngineSelect>(engineSelect); +} + void* host_init_fsi( void *io_pArgs ) { @@ -157,6 +216,26 @@ void* host_init_fsi( void *io_pArgs ) // Commit this error errlCommit( l_err, ISTEP_COMP_ID ); } + + // This engine (specifically the Host logic) is used at runtime by the OCC. We + // need to reset it back to a known state before we start using it again to + // avoid noticing leftover errors/activities (like interrupts). Since this is + // a MPIPL, the hardware isn't reset unless we explicitly do it. + TARGETING::Target* l_pTopLevel = NULL; + TARGETING::targetService().getTopLevelTarget( l_pTopLevel ); + assert(l_pTopLevel, "host_init_fsi: no TopLevelTarget"); + if (l_pTopLevel->getAttr<TARGETING::ATTR_IS_MPIPL_HB>()) + { + l_err = i2cResetActiveMasters( + I2C_PROC_HOST, + false, + find_proc_i2c_engines_for_nvdimms()); + if (l_err) + { + // Commit this error + errlCommit( l_err, ISTEP_COMP_ID ); + } + } } } while (0); |