summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c
diff options
context:
space:
mode:
authorMike Baiocchi <mbaiocch@us.ibm.com>2019-03-15 07:24:34 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-03-18 10:39:45 -0500
commit4eb72a8bf0741c537261baef74358cba49c383ef (patch)
tree01830227db79c729f7370e503ddfaa6a3e817c92 /src/usr/i2c
parent85942470b22360f2b74051887609362f6d1116a9 (diff)
downloadtalos-hostboot-4eb72a8bf0741c537261baef74358cba49c383ef.tar.gz
talos-hostboot-4eb72a8bf0741c537261baef74358cba49c383ef.zip
Adjust I2C Reset for OpenPower MPIPL
A new internal I2C function was created to read the Security Switch Registers "Seeprom Update Lock" ("SUL") bit and reduce the I2C reset level if set to avoid Arbitration Lost errors during an OpenPower MPIPL. Change-Id: I1709b425182be92377a988cd64d5683733236b05 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/73405 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> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com> Reviewed-by: Matthew Raybuck <matthew.raybuck@ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/i2c')
-rwxr-xr-xsrc/usr/i2c/i2c.C74
-rwxr-xr-xsrc/usr/i2c/i2c.H28
2 files changed, 99 insertions, 3 deletions
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 6854d58ac..0e0c37256 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -4597,12 +4597,17 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType,
{
case I2C_OP_RESET:
{
+
+ i2c_reset_level reset_level =
+ setResetLevelViaStickyBit(tgt, engine);
+
TRACFCOMP( g_trac_i2c,INFO_MRK
- "i2cProcessActiveMasters: reset engine: %d",
- engine );
+ "i2cProcessActiveMasters: reset engine: %d, "
+ "reset_level=%d",
+ engine, reset_level );
err = i2cReset ( tgt, io_args,
- FORCE_UNLOCK_RESET);
+ reset_level );
if( err )
{
TRACFCOMP( g_trac_i2c,ERR_MRK
@@ -5656,4 +5661,67 @@ void addHwCalloutsI2c(errlHndl_t i_err,
}
}
+i2c_reset_level setResetLevelViaStickyBit(TARGETING::Target * i_target,
+ uint8_t i_engine)
+{
+ TRACDCOMP(g_trac_i2c,ENTER_MRK"setResetLevelViaStickyBit: "
+ "i_target=0x%.8X, i_engine=%d",
+ TARGETING::get_huid(i_target), i_engine);
+
+ i2c_reset_level o_reset_level = FORCE_UNLOCK_RESET;
+
+ do
+ {
+
+ if ((i_target==nullptr) ||
+ (TARGETING::TYPE_PROC != i_target->getAttr<TARGETING::ATTR_TYPE>()) ||
+ (i_engine != 1))
+ {
+ // No-op - just return default of FORCE_UNLOCK_RESET
+ break;
+ }
+
+ // Get Processor Target's Security Switch Register
+ uint64_t switch_reg_value = 0x0;
+ errlHndl_t err = SECUREBOOT::getSecuritySwitch(switch_reg_value, i_target);
+ if (err)
+ {
+ // Commit Error Log and return BASIC_RESET to be safe
+ o_reset_level = BASIC_RESET;
+ TRACFCOMP(g_trac_i2c,ERR_MRK"setResetLevelViaStickyBit: "
+ "Error returned from SECUREBOOT::getSecuritySwitch(): plid=0x%X. "
+ "Committing error here and returning o_reset_level=%d",
+ err->plid(), o_reset_level);
+
+ err->collectTrace( I2C_COMP_NAME, 256);
+ errlCommit(err, I2C_COMP_ID);
+
+ break;
+ }
+
+ // Check if SUL bit is set in the security switch register
+ if (switch_reg_value &
+ static_cast<uint64_t>(SECUREBOOT::ProcSecurity::SULBit))
+ {
+ // Since SUL bit is set return BASIC_RESET to be safe
+ o_reset_level = BASIC_RESET;
+ TRACFCOMP(g_trac_i2c,INFO_MRK"setResetLevelViaStickyBit: "
+ "SUL bit in Security Switch Register (0x%.16llx) is set - "
+ "o_reset_level=%d",
+ switch_reg_value, o_reset_level);
+
+ break;
+ }
+ // else: return default FORCE_UNLOCK_RESET
+
+ } while (0);
+
+ TRACDCOMP(g_trac_i2c,EXIT_MRK"setResetLevelViaStickyBit: "
+ "returning o_reset_level=%d",
+ o_reset_level);
+
+ return o_reset_level;
+}
+
+
}; // end namespace I2C
diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H
index 5b69b302e..eca944479 100755
--- a/src/usr/i2c/i2c.H
+++ b/src/usr/i2c/i2c.H
@@ -969,6 +969,34 @@ void addHwCalloutsI2c(errlHndl_t i_err,
TARGETING::Target * i_target,
const misc_args_t & i_args);
+
+/**
+ * @brief This function checks the 'Seeprom Update Lock" (aka SUL) bit in
+ * the input processor target's Security Switch Register and if
+ * enabled will choose a BASIC_RESET level versus the more complex
+ * FORCE_RESET_UNLOCK
+ *
+ * @param[in] i_target - Processor I2C Master Target
+ * No-op if nullptr
+ * No-op if not Processor Type
+ *
+ * @param[in] i_engine - I2C Engine off of the Processor I2C Master Target
+ * No-op if engine does not equal 1
+ *
+ * @note - For all no-op conditions above, FORCE_RESET_UNLOCK will be returned
+ *
+ * @note - Any error logs will be handled internally
+ *
+ * @note - The sticky bit setting only matters for accessing the MVPD and
+ * SBE Seeproms, and thererfore will only change the reset level for
+ * engine == to 1.
+ *
+ * @return i2c_reset_level - Max Reset Level Allowed for This Target
+ */
+i2c_reset_level setResetLevelViaStickyBit(TARGETING::Target * i_target,
+ uint8_t i_engine);
+
+
namespace SMBUS
{
OpenPOWER on IntegriCloud