summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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