diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/usr/i2c/i2cif.H | 48 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 38 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 28 |
3 files changed, 98 insertions, 16 deletions
diff --git a/src/include/usr/i2c/i2cif.H b/src/include/usr/i2c/i2cif.H index 583eb5083..5fa3216e4 100644 --- a/src/include/usr/i2c/i2cif.H +++ b/src/include/usr/i2c/i2cif.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* Contributors Listed Below - COPYRIGHT 2012,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -34,8 +34,8 @@ namespace I2C /** * @enum i2cProcessType * - * @brief I2C Process Type specifies which targets and which I2C master - * engines are reset or setup + * @brief I2C Process Type specifies which targets and which mode the + * I2C master engines are in to be reset or setup * * Specifically: * @@ -70,6 +70,45 @@ enum i2cProcessType }; /** + * @enum i2cEngineSelect + * + * @brief I2C Engine Select determines which engine(s) the action will be + * executed on. + * + * @note This enum is setup to be used as a bit-mask where _ALL combines + * all possibilities. + * + * @note See i2cEngineToEngineSelect() function for converting an engine + * number to a value represented by this enum. + */ +enum i2cEngineSelect : uint8_t +{ + // Individual Engines + I2C_ENGINE_SELECT_ONLY_0 = 0x80, + I2C_ENGINE_SELECT_ONLY_1 = 0x40, + I2C_ENGINE_SELECT_ONLY_2 = 0x20, + I2C_ENGINE_SELECT_ONLY_3 = 0x10, + + I2C_ENGINE_SELECT_ALL = I2C_ENGINE_SELECT_ONLY_0 | + I2C_ENGINE_SELECT_ONLY_1 | + I2C_ENGINE_SELECT_ONLY_2 | + I2C_ENGINE_SELECT_ONLY_3, +}; + +/** + * @brief This inline function will take an engine number input and convert + * it to the corresponding i2cEngineSelect enum. + * + * @param[in] i_engine - Specfies which engine number to convert + * + * @return i2cEngineSelect - Corresponding enum value + */ +inline i2cEngineSelect i2cEngineToEngineSelect(const uint8_t i_engine) +{ + return static_cast<i2cEngineSelect>(0x80 >> i_engine); +} + +/** * @brief This function will handle everything required to reset a target's * "active" I2C master engine. * [NOTE: "active" engine is determined by target's I2C_SWITCHES attribute] @@ -88,7 +127,8 @@ enum i2cProcessType * the error log. */ errlHndl_t i2cResetActiveMasters ( i2cProcessType i_resetType, - bool i_functional = true ); + bool i_functional = true, + i2cEngineSelect = I2C_ENGINE_SELECT_ALL); /** * @brief This function will handle everything required to setup a target's diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 95074f82d..3aed2eb02 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -3179,7 +3179,8 @@ enum i2cProcessOperation errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, i2cProcessOperation i_processOperation, uint64_t i_busSpeed, - bool i_functional ) + bool i_functional, + i2cEngineSelect i_engineSelect ) { errlHndl_t err = NULL; bool error_found = false; @@ -3193,9 +3194,10 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, TARGETING::ATTR_I2C_BUS_SPEED_ARRAY_type speed_array; TRACFCOMP( g_trac_i2c, - ENTER_MRK"i2cProcessActiveMasters(): Type=0x%X, " - "Operation=%d Bus Speed=%d Functional=%d", - i_processType, i_processOperation, i_busSpeed, i_functional ); + ENTER_MRK"i2cProcessActiveMasters(): Type=0x%X " + "Operation=%d Bus Speed=%d Functional=%d engineSelect=0x%.2X", + i_processType, i_processOperation, i_busSpeed, i_functional, + i_engineSelect ); do { @@ -3357,7 +3359,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, } } - for( size_t engine = 0; + for( uint8_t engine = 0; engine < I2C_BUS_ATTR_MAX_ENGINE; engine++ ) { @@ -3373,8 +3375,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, continue; } - // Never touch engine 0 for Host -- the SBE owns - // it + // Never touch engine 0 for Host -- the SBE owns it if ( ( engine == 0 ) && (io_args.switches.useHostI2C == 1) ) { @@ -3383,6 +3384,16 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, continue; } + // Only operate on selected engines + if ( ! ( i2cEngineToEngineSelect(engine) & i_engineSelect ) ) + { + TRACFCOMP( g_trac_i2c,INFO_MRK + "Skipping engine %d because i_engineSelect=0x%.2X", + engine, i_engineSelect ); + continue; + } + + // Look for any device on this engine based on speed_array bool skip = true; size_t l_numPorts = I2C_BUS_ATTR_MAX_PORT; @@ -3647,19 +3658,21 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, * Set bus speed from the MRW value. */ errlHndl_t i2cResetActiveMasters ( i2cProcessType i_resetType, - bool i_functional ) + bool i_functional, + i2cEngineSelect i_engineSelect ) { errlHndl_t err = NULL; TRACFCOMP( g_trac_i2c, ENTER_MRK"i2cResetActiveMasters(): i2cProcessType=0x%X, " - "i_functional=%d", - i_resetType, i_functional ); + "i_functional=%d, i_engineSelect=0x%.2X", + i_resetType, i_functional, i_engineSelect ); err = i2cProcessActiveMasters (i_resetType, // select engines I2C_OP_RESET, // reset engines I2C_BUS_SPEED_FROM_MRW, - i_functional); + i_functional, + i_engineSelect); TRACFCOMP( g_trac_i2c, EXIT_MRK"i2cResetActiveMasters(): err rc=0x%X, plid=0x%X", @@ -3686,7 +3699,8 @@ errlHndl_t i2cSetupActiveMasters ( i2cProcessType i_setupType, err = i2cProcessActiveMasters (i_setupType, // select engines I2C_OP_SETUP, // setup engines I2C_BUS_SPEED_400KHZ, - i_functional); + i_functional, + I2C_ENGINE_SELECT_ALL); TRACFCOMP( g_trac_i2c, EXIT_MRK"i2cSetupActiveMasters(): err rc=0x%X, plid=0x%X", diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index 0c1e9e974..43ce1f330 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -52,6 +52,7 @@ #include <config.h> #include <devicefw/driverif.H> #include <i2c/tpmddif.H> +#include <i2c/i2cif.H> #include "trustedboot.H" #include "trustedTypes.H" #include "trustedbootCmds.H" @@ -274,6 +275,33 @@ void* host_update_master_tpm( void *io_pArgs ) if( hwasState.present && hwasState.functional) { + // If MPIPL do I2C Reset to any processor's I2C engine that is + // driving the TPMs + TARGETING::Target* sys = nullptr; + (void) tS.getTopLevelTarget( sys ); + assert(sys, "host_update_master_tpm() system target is nullptr"); + + if (sys->getAttr<TARGETING::ATTR_IS_MPIPL_HB>()) + { + err = I2C::i2cResetActiveMasters( + I2C::I2C_PROC_HOST, + true, + I2C::i2cEngineToEngineSelect(tpmData.engine)); + + if (nullptr != err) + { + // Commit log and continue + TRACFCOMP(g_trac_trustedboot,ERR_MRK + "host_update_master_tpm(): Committing I2C " + "Reset Fail plid=0x%X but continuing", + err->plid()); + err->collectTrace(TRBOOT_COMP_NAME); + errlCommit(err, TRBOOT_COMP_ID); + err = nullptr; + } + + } + // API call will set TPM init attempted appropriately tpmInitialize(pPrimaryTpm); } |