diff options
-rw-r--r-- | src/include/usr/i2c/i2creasoncodes.H | 3 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 72 | ||||
-rw-r--r-- | src/usr/isteps/ucd/updateUcdFlash.C | 71 |
3 files changed, 101 insertions, 45 deletions
diff --git a/src/include/usr/i2c/i2creasoncodes.H b/src/include/usr/i2c/i2creasoncodes.H index 6e29065db..a2b79be32 100644 --- a/src/include/usr/i2c/i2creasoncodes.H +++ b/src/include/usr/i2c/i2creasoncodes.H @@ -66,9 +66,9 @@ enum i2cModuleId READ_I2C_ATTRIBUTES = 0x10, I2C_ACCESS_MUX = 0x11, I2C_GENERIC_PRES_DETECT = 0x12, + I2C_BAD_PEC_BYTE_ERROR = 0x13, }; - /** * @enum i2cReasonCode * @@ -106,6 +106,7 @@ enum i2cReasonCode I2C_INVALID_BLOCK_WRITE_LENGTH = I2C_COMP_ID | 0x1A, // Invalid block write length I2C_INVALID_READ_BYTE_OR_WORD_LENGTH = I2C_COMP_ID | 0x1B, // Invalid read byte/word length I2C_INVALID_BLOCK_READ_LENGTH = I2C_COMP_ID | 0x1C, // Invalid block read length + I2C_BAD_PEC_BYTE = I2C_COMP_ID | 0x1D, // Bad PEC byte }; diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 88233dadb..850f841cd 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -214,6 +214,61 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, TARGETING::TYPE_MEMBUF, i2cPerformOp ); +/* + * @brief A helper function for i2cCommonOp that commonizes error handling + * for a bad PEC byte for a power sequencer. + * + * @param[in] i_expectedPec The value of the expected PEC byte. + * + * @param[in] i_actualPec The value of the actual PEC byte. + * + * @param[in] i_i2cMaster The i2c master for the power sequencer. + * + * @param[in] i_args The i2c info for the power sequencer. + * + * @return errlHndl_t A pointer to an error log. + */ +errlHndl_t badPecByteError(const uint8_t i_expectedPec, + const uint8_t i_actualPec, + const TARGETING::TargetHandle_t& i_i2cMaster, + const misc_args_t i_args) +{ + /*@ + * @errortype + * @severity ERRL_SEV_PREDICTIVE + * @moduleid I2C_BAD_PEC_BYTE_ERROR + * @reasoncode I2C_BAD_PEC_BYTE + * @devdesc A bad PEC byte was found during the + * device operation. + * @custdesc Unexpected firmware error + * @userdata1[00:31] Expected PEC byte + * @userdata1[32:63] Actual PEC byte + */ + errlHndl_t err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE, + I2C_BAD_PEC_BYTE_ERROR, + I2C_BAD_PEC_BYTE, + TWO_UINT32_TO_UINT64( + i_expectedPec, + i_actualPec)); + + // Add a callout for the I2C master. + err->addI2cDeviceCallout(i_i2cMaster, + i_args.engine, + i_args.port, + i_args.devAddr, + HWAS::SRCI_PRIORITY_HIGH); + + // Add a callout for hostboot code. + err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_LOW); + + err->collectTrace(I2C_COMP_NAME); + + return err; + +} + + /** * * @brief A useful utility to dump (trace out) the TARGETING::FapiI2cControlInfo @@ -1758,8 +1813,12 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, "but received 0x%02X. # PEC bytes = %d", expectedPec,readByteOrWord.pec,pecBytes); - // @TODO RTC 201990 support bad PEC handling - // Right now just ignore it + err = badPecByteError(expectedPec, + readByteOrWord.pec, + i_target, + i_args); + + break; } } @@ -1927,6 +1986,7 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, + blockRead.blockCount; const auto expectedPec = I2C::SMBUS::calculatePec( reinterpret_cast<uint8_t*>(&blockRead),pecBytes); + if(blockRead.pec != expectedPec) { TRACFCOMP(g_trac_i2c, ERR_MRK @@ -1934,8 +1994,12 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, "but received 0x%02X. # PEC bytes = %d", expectedPec,blockRead.pec,pecBytes); - // @TODO RTC 201990 support bad PEC handling - // Right now just ignore it + err = badPecByteError(expectedPec, + blockRead.pec, + i_target, + i_args); + + break; } } diff --git a/src/usr/isteps/ucd/updateUcdFlash.C b/src/usr/isteps/ucd/updateUcdFlash.C index f71727a72..4c90540fe 100644 --- a/src/usr/isteps/ucd/updateUcdFlash.C +++ b/src/usr/isteps/ucd/updateUcdFlash.C @@ -122,7 +122,7 @@ private: const uint8_t i_modId, const uint16_t i_reasonCode, const uint64_t i_user1, - const uint64_t i_user2) + const uint64_t i_user2) const { errlHndl_t err = nullptr; @@ -175,7 +175,7 @@ private: const DeviceFW::I2C_SUBOP i_smbusOpType, void * const io_buffer, size_t& io_bufferLength, - const uint8_t * const i_cmd = nullptr) + const uint8_t * const i_cmd = nullptr) const { assert(io_buffer != nullptr, "io_buffer must not be nullptr"); errlHndl_t err = nullptr; @@ -257,13 +257,13 @@ private: * @return boolean true if the error is retryable. * Otherwise, false. */ - bool errorIsRetryable(const uint16_t i_reasonCode) + bool errorIsRetryable(const uint16_t i_reasonCode) const { - //@TODO RTC 205982 Handle Bad PEC byte. bool retryable = false; if ( (i_reasonCode == I2C::I2C_NACK_ONLY_FOUND) - || (i_reasonCode == I2C::I2C_CMD_COMP_TIMEOUT)) + || (i_reasonCode == I2C::I2C_CMD_COMP_TIMEOUT) + || (i_reasonCode == I2C::I2C_BAD_PEC_BYTE)) { retryable = true; } @@ -331,19 +331,14 @@ private: auto page = i_page; size_t size = sizeof(page); const auto expSize = size; + uint8_t cmd = PAGE; + + pError = attemptDeviceOp(DeviceFW::WRITE, + DeviceFW::I2C_SMBUS_BYTE, + &page, + size, + &cmd); - pError = deviceOp(DeviceFW::WRITE, - iv_pI2cMaster, - &page, - size, - DEVICE_I2C_SMBUS_BYTE(iv_i2cInfo.engine, - iv_i2cInfo.port, - iv_i2cInfo.devAddr, - PAGE, - iv_i2cInfo.i2cMuxBusSelector, - &iv_i2cInfo.i2cMuxPath)); - - // @TODO RTC 205982: Handle the PEC byte if it exists. if(pError) { TRACFCOMP(g_trac_ucd, ERR_MRK @@ -457,19 +452,14 @@ public: size_t size = sizeof(mfrStatus.value); const auto expSize = size; + uint8_t cmd = MFR_STATUS; + + pError = attemptDeviceOp(DeviceFW::READ, + DeviceFW::I2C_SMBUS_BLOCK, + &mfrStatus.value, + size, + &cmd); - pError = deviceOp(DeviceFW::READ, - iv_pI2cMaster, - &mfrStatus.value, - size, - DEVICE_I2C_SMBUS_BLOCK(iv_i2cInfo.engine, - iv_i2cInfo.port, - iv_i2cInfo.devAddr, - MFR_STATUS, - iv_i2cInfo.i2cMuxBusSelector, - &iv_i2cInfo.i2cMuxPath)); - - // @TODO RTC 205982: Handle the PEC byte if it exists. if (pError) { TRACFCOMP(g_trac_ucd, ERR_MRK @@ -1242,14 +1232,16 @@ public: } // end of updateUcdFlash() - //@TODO RTC 205982 Include bad pec byte RC in description /* * @brief This function will attempt to perform a deviceOp three times * using the supplied parameters to select the appropriate * operation. If an error is encountered during an attempt it * will be handled in terms of retryable versus non-retryable. - * A retryable error has a return code of either: - * I2C_NACK_ONLY_FOUND, I2C_CMD_COMP_TIMEOUT, or a bad pec byte. + * A retryable error has a return code of: + * > I2C_NACK_ONLY_FOUND + * > I2C_CMD_COMP_TIMEOUT + * > I2C_BLOCK_READ_BAD_PEC_BYTE + * > I2C_READ_BYTE_WORD_BAD_PEC_BYTE * If these errors are encountered they will not be returned by * the function unless the operation fails three times then the * final error will be returned as a non-retryable error. @@ -1283,7 +1275,7 @@ public: const DeviceFW::I2C_SUBOP i_smbusOpType, void * const io_buffer, size_t& io_bufferLength, - const uint8_t * const i_cmd = nullptr) + const uint8_t * const i_cmd = nullptr) const { assert(io_buffer != nullptr, "io_buffer must not be nullptr"); @@ -1316,7 +1308,6 @@ public: break; } - // Retry Error Handling Section if (pUcdError == nullptr) { @@ -1716,17 +1707,15 @@ errlHndl_t updateAllUcdFlashImages( const auto position = pI2cMasterTarget-> getAttr<TARGETING::ATTR_POSITION>(); - // @TODO RTC 205982 Reset UCD if needed to put it in a good state - Ucd ucd(powerSequencer); - pError=ucd.initialize(); + pError = ucd.initialize(); if(pError) { TRACFCOMP(g_trac_ucd,ERR_MRK "updateAllUcdFlashImages: Failed in Ucd::initialize() for UCD " "with HUID of 0x%08X", TARGETING::get_huid(powerSequencer)); - // @TODO: RTC 205982 mark non-functional, more FFDC + pError->collectTrace(UCD_COMP_NAME); errlCommit(pError,UCD_COMP_ID); break; @@ -1802,7 +1791,7 @@ errlHndl_t updateAllUcdFlashImages( deviceIds.add("Expected device ID",tocEntry.deviceId); deviceIds.add("Actual device ID",deviceId); deviceIds.addToLog(pError); - // @TODO: RTC 205982 set non-functional, deconfig + pError->collectTrace(UCD_COMP_NAME); errlCommit(pError,UCD_COMP_ID); nextUcd=true; @@ -1874,7 +1863,7 @@ errlHndl_t updateAllUcdFlashImages( "updateUcdFlash for UCD with HUID of " " 0x%08X.", TARGETING::get_huid(powerSequencer)); - // @TODO: RTC 205982 Deconfigure UCD, call it out, etc. + pError->collectTrace(UCD_COMP_NAME); errlCommit(pError,UCD_COMP_ID); break; @@ -1890,6 +1879,8 @@ errlHndl_t updateAllUcdFlashImages( TARGETING::get_huid(powerSequencer)); pError->collectTrace(UCD_COMP_NAME); errlCommit(pError,UCD_COMP_ID); + + break; } TRACFCOMP(g_trac_ucd,INFO_MRK |