Skip to content

Commit

Permalink
Adjust I2C Reset for OpenPower MPIPL
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mabaiocchi authored and dcrowell77 committed Mar 18, 2019
1 parent 8594247 commit 4eb72a8
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 3 deletions.
74 changes: 71 additions & 3 deletions src/usr/i2c/i2c.C
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
28 changes: 28 additions & 0 deletions src/usr/i2c/i2c.H
Original file line number Diff line number Diff line change
Expand Up @@ -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
{

Expand Down

0 comments on commit 4eb72a8

Please sign in to comment.