summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2019-02-21 19:24:11 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2019-03-01 09:30:09 -0600
commitb8720c117759a6873256835da8fb52d31199a3b7 (patch)
tree80a32340f154e51d57fad1de4202fc367d89526d /src
parentd2899da82cb004acbcba439673dc1dfb02ae6fb6 (diff)
downloadtalos-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.C81
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);
OpenPOWER on IntegriCloud