diff options
author | Mike Baiocchi <mbaiocch@us.ibm.com> | 2019-03-15 07:24:34 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-03-18 10:39:45 -0500 |
commit | 4eb72a8bf0741c537261baef74358cba49c383ef (patch) | |
tree | 01830227db79c729f7370e503ddfaa6a3e817c92 /src/usr/i2c/i2c.C | |
parent | 85942470b22360f2b74051887609362f6d1116a9 (diff) | |
download | talos-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/i2c.C')
-rwxr-xr-x | src/usr/i2c/i2c.C | 74 |
1 files changed, 71 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 |