diff options
author | Roland Veloz <rveloz@us.ibm.com> | 2018-09-26 00:51:53 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-12-06 19:18:15 -0600 |
commit | b63c84765363b7bf4eea4a19d4cf5bba2533b63b (patch) | |
tree | a9e19493bf958bc47233af466f3106ecc4f2e22f | |
parent | 082f9363ee8ea21647959637cf05a102fec4d24e (diff) | |
download | blackbird-hostboot-b63c84765363b7bf4eea4a19d4cf5bba2533b63b.tar.gz blackbird-hostboot-b63c84765363b7bf4eea4a19d4cf5bba2533b63b.zip |
Driver changes to support i2c mux
- Updated data structures gpioAddr_t, eeprom_addr_t, misc_args_t, nvdimm_addr_t
and tpm_info_t with I2C MUX data members. Also added constructors to these
structures to default there data members with the correct default info.
- Updated macros DEVICE_I2C_PARMS, DEVICE_I2C_ADDRESS and
DEVICE_I2C_ADDRESS_OFFSET to take the I2C MUX bus selector parameter and the
I2C MUX entity path.
- Added method i2cAccessMux to file i2c.H/.C that will setup the call for the
I2C MUX. Method i2cCommonOP calls i2cAccessMux which then calls i2cCommonOp
with appropriate parameters for the I2C MUX: i2cCommonOP -> i2cAccessMux
-> i2cCommonOP.
- Updated i2ctest.H with new I2C MUX params to get it to pass.
RTC:191352
Change-Id: I6a70860eb2286bbd23d6157d72351b8adfa21aac
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66651
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@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: Daniel M. Crowell <dcrowell@us.ibm.com>
27 files changed, 1566 insertions, 324 deletions
diff --git a/src/build/configs/axone.config b/src/build/configs/axone.config new file mode 100644 index 000000000..965b1dc60 --- /dev/null +++ b/src/build/configs/axone.config @@ -0,0 +1 @@ +set DJVPD_READ_FROM_HW diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index 9bed7bb94..6e94f04e4 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -41,6 +41,14 @@ #endif // not PARSER +namespace I2C_MUX +{ + enum SELECTOR: uint8_t + { + NOT_APPLICABLE = 0xFF, + }; +} + namespace DeviceFW { /** @enum AccessType_DriverOnly @@ -57,6 +65,7 @@ namespace DeviceFW FSI_I2C, SBEFIFOSCOM, I2CSCOM, + I2C_MUX, LAST_DRIVER_ACCESS_TYPE }; @@ -119,22 +128,29 @@ namespace DeviceFW /** * @brief Macro that handles the I2C parameters */ - #define DEVICE_I2C_PARMS(port, engine, devAddr, offset_len, offset)\ + #define DEVICE_I2C_PARMS(port, engine, devAddr, offset_len,\ + offset, muxSelector, i_i2cMuxPath)\ static_cast<uint64_t>( port ),\ static_cast<uint64_t>( engine ),\ static_cast<uint64_t>( devAddr ),\ static_cast<uint64_t>( offset_len ),\ - static_cast<uint8_t*>( offset ) + static_cast<uint8_t*>( offset ),\ + static_cast<uint64_t>( muxSelector), \ + static_cast<const TARGETING::EntityPath*>(i_i2cMuxPath) /** * Construct the device addressing parameters for the I2C device ops. * @param[in] i_port - Which port to use from the I2C master. * @param[in] i_engine - Which I2C master engine to use. * @param[in] i_devAddr - The device address on a given engine/port. - * @note '0' and 'NULL' added to line up with other DeviceFW::I2C + * @param[in] i_i2cMuxBusSelector - The I2C MUX bus selector + * @param[in] i_i2cMuxPath - The I2C MUX entity path + * @note '0' and 'nullptr' added to line up with other DeviceFW::I2C */ - #define DEVICE_I2C_ADDRESS( i_port, i_engine, i_devAddr )\ - DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL) + #define DEVICE_I2C_ADDRESS( i_port, i_engine, i_devAddr, \ + i_i2cMuxBusSelector, i_i2cMuxPath )\ + DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\ + 0, nullptr, i_i2cMuxBusSelector, i_i2cMuxPath) /** * Construct the device addressing parameters for the I2C-offset device ops. @@ -143,10 +159,13 @@ namespace DeviceFW * @param[in] i_devAddr - The device address on a given engine/port. * @param[in] i_offset_len - Length of offset (in bytes) * @param[in] i_offset - Offset into I2C device + * @param[in] i_i2cMuxBusSelector - The I2C MUX bus selector + * @param[in] i_i2cMuxPath - The I2C MUX entity path */ - #define DEVICE_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\ - DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset) - + #define DEVICE_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset, i_i2cMuxBusSelector, i_i2cMuxPath)\ + DeviceFW::I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset, i_i2cMuxBusSelector, i_i2cMuxPath) /** * Construct the device addressing parameters for locking the page @@ -162,7 +181,8 @@ namespace DeviceFW * want to lock the page mutex or not. This bool allows * us to switch pages mid read without hitting a deadlock. */ -#define DEVICE_I2C_CONTROL_PAGE_OP( i_port, i_engine, i_shouldLock, i_desired_page, i_lockMutex )\ +#define DEVICE_I2C_CONTROL_PAGE_OP( i_port, i_engine, i_shouldLock,\ + i_desired_page, i_lockMutex )\ DeviceFW::I2C,\ static_cast<uint64_t>(i_port),\ static_cast<uint64_t>(i_engine),\ @@ -177,42 +197,50 @@ namespace DeviceFW * @param[in] i_port - Which port to use from the I2C master. * @param[in] i_engine - Which I2C master engine to use. * @param[in] i_devAddr - The device address on a given engine/port. - * @note '0' and 'NULL' added to line up with other DeviceFW::I2C + * @note '0' and 'nullptr' added to line up with other DeviceFW::I2C */ #define DEVICE_HOSTI2C_ADDRESS( i_port, i_engine, i_devAddr )\ - DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL) + DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\ + 0, nullptr) /** - * Construct the device addressing parameters for the Host I2C-offset device ops. + * Construct the device addressing parameters for the Host I2C-offset + * device ops. * @param[in] i_port - Which port to use from the I2C master. * @param[in] i_engine - Which I2C master engine to use. * @param[in] i_devAddr - The device address on a given engine/port. * @param[in] i_offset_len - Length of offset (in bytes) * @param[in] i_offset - Offset into I2C device */ - #define DEVICE_HOSTI2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\ - DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset) + #define DEVICE_HOSTI2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset)\ + DeviceFW::HOSTI2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset) /** * Construct the device addressing parameters for the FSI I2C device ops. * @param[in] i_port - Which port to use from the I2C master. * @param[in] i_engine - Which I2C master engine to use. * @param[in] i_devAddr - The device address on a given engine/port. - * @note '0' and 'NULL' added to line up with other DeviceFW::I2C + * @note '0' and 'nullptr' added to line up with other DeviceFW::I2C */ #define DEVICE_FSI_I2C_ADDRESS( i_port, i_engine, i_devAddr )\ - DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, 0, NULL) + DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine,\ + i_devAddr, 0, nullptr) /** - * Construct the device addressing parameters for the FSI I2C-offset device ops. + * Construct the device addressing parameters for the FSI I2C-offset + * device ops. * @param[in] i_port - Which port to use from the I2C master. * @param[in] i_engine - Which I2C master engine to use. * @param[in] i_devAddr - The device address on a given engine/port. * @param[in] i_offset_len - Length of offset (in bytes) * @param[in] i_offset - Offset into I2C device */ - #define DEVICE_FSI_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr, i_offset_len, i_offset)\ - DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr, i_offset_len, i_offset) + #define DEVICE_FSI_I2C_ADDRESS_OFFSET( i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset)\ + DeviceFW::FSI_I2C, DEVICE_I2C_PARMS(i_port, i_engine, i_devAddr,\ + i_offset_len, i_offset) /** Construct the device addressing parameters for the SBE FIFO Scom * device ops. diff --git a/src/include/usr/i2c/i2creasoncodes.H b/src/include/usr/i2c/i2creasoncodes.H index 4ce6c3a81..e17b057ef 100644 --- a/src/include/usr/i2c/i2creasoncodes.H +++ b/src/include/usr/i2c/i2creasoncodes.H @@ -64,6 +64,7 @@ enum i2cModuleId I2C_CHOOSE_EEPROM_PAGE = 0x0E, FAPI_I2C_PERFORM_OP = 0x0F, READ_I2C_ATTRIBUTES = 0x10, + I2C_ACCESS_MUX = 0x11, }; @@ -95,6 +96,8 @@ enum i2cReasonCode I2C_INVALID_EEPROM_PAGE_REQUEST = I2C_COMP_ID | 0x11, // Invalid EEPROM page request I2C_FAILURE_UNLOCKING_EEPROM_PAGE = I2C_COMP_ID | 0x12, // Error while attempting to unlock the eeprom page INVALID_MASTER_TARGET = I2C_COMP_ID | 0x13, // Master I2C target not valid + I2C_MUX_TARGET_NOT_FOUND = I2C_COMP_ID | 0x14, // The MUX target is not valid (null) + I2C_MUX_TARGET_NON_FUNCTIONAL = I2C_COMP_ID | 0x15, // The MUX target is non functional }; diff --git a/src/include/usr/i2c/tpmddif.H b/src/include/usr/i2c/tpmddif.H index 34128e04c..d9ff469b8 100644 --- a/src/include/usr/i2c/tpmddif.H +++ b/src/include/usr/i2c/tpmddif.H @@ -25,6 +25,8 @@ #ifndef __TPMDDIF_H #define __TPMDDIF_H +#include "usr/devicefw/driverif.H" // I2C_MUX::NOT_APPLICABLE + namespace TPMDD { @@ -79,6 +81,9 @@ struct tpm_info_t size_t offset; ///< TPM Device register offset tpm_addr_size_t addrSize; ///< I2C Addr size + uint8_t i2cMuxBusSelector; ///< The Selector for the I2C MUX + TARGETING::EntityPath i2cMuxPath; ///< I2C MUX path + /** * @brief Construct a default tpm_info_t */ @@ -93,7 +98,9 @@ struct tpm_info_t tpmEnabled(false), devAddr(0), offset(0), - addrSize(LAST_DEVICE_TYPE) + addrSize(LAST_DEVICE_TYPE), + i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE), + i2cMuxPath() { } }; diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C index 5b2c840e7..559dab79e 100644 --- a/src/usr/gpio/gpiodd.C +++ b/src/usr/gpio/gpiodd.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2015 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -35,7 +35,6 @@ #include "gpiodd.H" #include <gpio/gpioddreasoncodes.H> - trace_desc_t * g_trac_gpio = NULL; TRAC_INIT( & g_trac_gpio, GPIO_COMP_NAME, KILOBYTE ); @@ -187,7 +186,9 @@ errlHndl_t gpioRead( TARGETING::Target * i_target, i_gpioInfo.engine, i_gpioInfo.i2cDeviceAddr, GPIO_ADDR_SIZE, - reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr)) + reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr)), + i_gpioInfo.i2cMuxBusSelector, + &(i_gpioInfo.i2cMuxPath) ) ); if(err) @@ -217,7 +218,9 @@ errlHndl_t gpioWrite ( TARGETING::Target * i_target, DEVICE_I2C_ADDRESS ( i_gpioInfo.i2cPort, i_gpioInfo.engine, - i_gpioInfo.i2cDeviceAddr + i_gpioInfo.i2cDeviceAddr, + i_gpioInfo.i2cMuxBusSelector, + &(i_gpioInfo.i2cMuxPath) ) ); if(err) @@ -312,6 +315,8 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target, io_gpioInfo.engine = gpioData.engine; io_gpioInfo.i2cPort = gpioData.port; io_gpioInfo.i2cDeviceAddr = gpioData.devAddr; + io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector; + io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath; } return err; diff --git a/src/usr/gpio/gpiodd.H b/src/usr/gpio/gpiodd.H index 702c68c3f..8c0e9ba1e 100644 --- a/src/usr/gpio/gpiodd.H +++ b/src/usr/gpio/gpiodd.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2015 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -40,6 +40,23 @@ namespace GPIO uint8_t i2cPort; uint8_t engine; uint8_t i2cDeviceAddr; + uint8_t i2cMuxBusSelector; + TARGETING::EntityPath i2cMuxPath; + + /** + * @brief Construct a default gpioAddr_t + */ + gpioAddr_t() + : i2cMasterPath(), + deviceType(INVALID_GPIO), + portAddr(0), + i2cPort(0), + engine(0), + i2cDeviceAddr(0), + i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE), + i2cMuxPath() + { + } }; /** diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C index 3939cc06c..d8530ad98 100644 --- a/src/usr/hwas/common/hwas.C +++ b/src/usr/hwas/common/hwas.C @@ -582,6 +582,57 @@ errlHndl_t check_current_proc_mem_to_use_is_still_valid (bool o_match) return l_err; } +/** + * @brief Do presence detect on only MUX targets and enable HWAS state + * + * @param[in] i_sysTarget the top level target (CLASS_SYS) + * @return errlHndl_t return nullptr if no error, + * else return a handle to an error entry + * + */ +errlHndl_t discoverMuxTargetsAndEnable(const Target &i_sysTarget) +{ + HWAS_DBG(ENTER_MRK"discoverMuxTargetsAndEnable"); + + errlHndl_t l_err{nullptr}; + + do + { + // Only get MUX targets + const PredicateCTM l_muxPred(CLASS_CHIP, TYPE_I2C_MUX); + TARGETING::PredicatePostfixExpr l_muxPredExpr; + l_muxPredExpr.push(&l_muxPred); + TargetHandleList l_pMuxCheckPres; + targetService().getAssociated( l_pMuxCheckPres, (&i_sysTarget), + TargetService::CHILD, TargetService::ALL, &l_muxPredExpr); + + // Do the presence detect on only MUX targets + l_err = platPresenceDetect(l_pMuxCheckPres); + + // If an issue with platPresenceDetect, then exit, returning + // error back to caller + if (nullptr != l_err) + { + break; + } + + // Enable the HWAS State for the MUXes + const bool l_present(true); + const bool l_functional(true); + const uint32_t l_errlEid(0); + for (TargetHandle_t pTarget : l_pMuxCheckPres) + { + // set HWAS state to show MUX is present and functional + enableHwasState(pTarget, l_present, l_functional, l_errlEid); + } + } while (0); + + HWAS_DBG(EXIT_MRK"discoverMuxTargetsAndEnable exit with %s", + (nullptr == l_err ? "no error" : "error")); + + return l_err; +} + errlHndl_t discoverTargets() { HWAS_DBG("discoverTargets entry"); @@ -635,7 +686,17 @@ errlHndl_t discoverTargets() HWAS_DBG("pSys %.8X - marked present", pSys->getAttr<ATTR_HUID>()); - // find list of all we need to call platPresenceDetect against + // Certain targets have dependencies on the MUX, so it is best to + // presence detect and enable the MUX before moving on to these targets. + // Please take this into consideration if code needs to be rearranged + // in the future. + errl = discoverMuxTargetsAndEnable(*pSys); + + if (errl != NULL) + { + break; // break out of the do/while so that we can return + } + PredicateCTM predEnc(CLASS_ENC); PredicateCTM predChip(CLASS_CHIP); PredicateCTM predDimm(CLASS_LOGICAL_CARD, TYPE_DIMM); @@ -698,10 +759,13 @@ errlHndl_t discoverTargets() uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES]; bzero(pgData, sizeof(pgData)); + // Cache the target type + auto l_targetType = pTarget->getAttr<ATTR_TYPE>(); if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP) && - (pTarget->getAttr<ATTR_TYPE>() != TYPE_TPM) && - (pTarget->getAttr<ATTR_TYPE>() != TYPE_SP) && - (pTarget->getAttr<ATTR_TYPE>() != TYPE_BMC) ) + (l_targetType != TYPE_TPM) && + (l_targetType != TYPE_SP) && + (l_targetType != TYPE_BMC) && + (l_targetType != TYPE_I2C_MUX) ) { // read Chip ID/EC data from these physical chips errl = platReadIDEC(pTarget); @@ -720,7 +784,7 @@ errlHndl_t discoverTargets() errlCommit(errl, HWAS_COMP_ID); // errl is now NULL } - else if (pTarget->getAttr<ATTR_TYPE>() == TYPE_PROC) + else if (l_targetType == TYPE_PROC) { // read partialGood vector from these as well. errl = platReadPartialGood(pTarget, pgData); diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C index b617b827b..f55f885ff 100644 --- a/src/usr/hwas/hwasPlat.C +++ b/src/usr/hwas/hwasPlat.C @@ -479,12 +479,13 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets) #endif } + // Cache the attribute type + auto l_attrType = pTarget->getAttr<ATTR_TYPE>(); // if CLASS_SP // Hostboot is told everything it needs to know about the // SP at compile time so just mark the target as present // by default - if ((pTarget->getAttr<ATTR_TYPE>() == TYPE_SP) || - (pTarget->getAttr<ATTR_TYPE>() == TYPE_BMC)) + if ((l_attrType == TYPE_SP) || (l_attrType == TYPE_BMC)) { HWAS_DBG("pTarget %.8X - detected present", pTarget->getAttr<ATTR_HUID>()); @@ -518,7 +519,7 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets) // trully tied to processor PG. So remove from list since // the DVPD present detect hook has been called // TODO RTC 169572 -- Fix correctly by reworking DVPD - if (pTarget->getAttr<ATTR_TYPE>() == TYPE_MCS) + if (l_attrType == TYPE_MCS) { // erase this target, and 'increment' to next pTarget_it = io_targets.erase(pTarget_it); diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C index 79a78323d..c1cbf45c8 100755 --- a/src/usr/i2c/eepromdd.C +++ b/src/usr/i2c/eepromdd.C @@ -189,9 +189,9 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, { TRACFCOMP( g_trac_eeprom, ERR_MRK"eepromPerformOp(): Device Overflow! " - "C-p/e/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X " - "devSizeKB=0x%X", i2cInfo.chip, i2cInfo.port, - i2cInfo.engine, i2cInfo.devAddr, i2cInfo.offset, + "C-e/p/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X " + "devSizeKB=0x%X", i2cInfo.chip, i2cInfo.engine, + i2cInfo.port, i2cInfo.devAddr, i2cInfo.offset, io_buflen, i2cInfo.devSize_KB); @@ -236,12 +236,21 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, TRACFCOMP( g_trac_eeprom, "eepromPerformOp(): i_opType=%d " - "C-p/e/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X, " + "C-e/p/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X, " "snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X", i_opType, - i2cInfo.chip, i2cInfo.port, i2cInfo.engine, i2cInfo.devAddr, + i2cInfo.chip, i2cInfo.engine, i2cInfo.port, i2cInfo.devAddr, i2cInfo.offset, io_buflen, l_snglChipSize, i2cInfo.chipCount, i2cInfo.devSize_KB); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_eeprom, "eepromPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + #ifdef __HOSTBOOT_RUNTIME // Disable Sensor Cache if the I2C master target is MEMBUF if( i2cMasterTarget->getAttr<TARGETING::ATTR_TYPE>() == @@ -766,17 +775,19 @@ errlHndl_t eepromReadData( TARGETING::Target * i_target, // Only write the byte address if we have data to write if( 0 != i_byteAddressSize ) { - // Use the I2C OFFSET Interface for the READ + // Use the I2C MUX OFFSET Interface for the READ l_err = deviceOp( DeviceFW::READ, - i_target, - o_buffer, - i_buflen, - DEVICE_I2C_ADDRESS_OFFSET( - i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr, - i_byteAddressSize, - reinterpret_cast<uint8_t*>(i_byteAddress))); + i_target, + o_buffer, + i_buflen, + DEVICE_I2C_ADDRESS_OFFSET( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + i_byteAddressSize, + reinterpret_cast<uint8_t*>(i_byteAddress), + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath))); if( l_err ) { @@ -798,9 +809,12 @@ errlHndl_t eepromReadData( TARGETING::Target * i_target, i_target, o_buffer, i_buflen, - DEVICE_I2C_ADDRESS( i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr ) ); + DEVICE_I2C_ADDRESS( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath) ) ); if( l_err ) { @@ -1244,8 +1258,9 @@ errlHndl_t eepromWriteData( TARGETING::Target * i_target, i_i2cInfo.devAddr, i_byteAddressSize, reinterpret_cast<uint8_t*>( - i_byteAddress))); - + i_byteAddress), + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath) ) ); if ( err == NULL ) { @@ -1278,6 +1293,15 @@ errlHndl_t eepromWriteData( TARGETING::Target * i_target, i_i2cInfo.offset, i_i2cInfo.addrSize, i_i2cInfo.writePageSize); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_eeprom, ERR_MRK"eepromWriteData():" + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // If op will be attempted again: save error and continue if ( retry < EEPROM_MAX_RETRIES ) { @@ -1609,6 +1633,8 @@ errlHndl_t eepromReadAttributes ( TARGETING::Target * i_target, o_i2cInfo.devSize_KB = eepromData.maxMemorySizeKB; o_i2cInfo.chipCount = eepromData.chipCount; o_i2cInfo.writeCycleTime = eepromData.writeCycleTime; + o_i2cInfo.i2cMuxBusSelector = eepromData.i2cMuxBusSelector; + o_i2cInfo.i2cMuxPath = eepromData.i2cMuxPath; // Convert attribute info to eeprom_addr_size_t enum if ( eepromData.byteAddrOffset == 0x3 ) @@ -1667,6 +1693,14 @@ errlHndl_t eepromReadAttributes ( TARGETING::Target * i_target, o_i2cInfo.chipCount, o_i2cInfo.addrSize, eepromData.byteAddrOffset, o_i2cInfo.writeCycleTime); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = o_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_eeprom, "eepromReadAttributes(): " + "muxSelector=0x%X, muxPath=%s", + o_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; TRACDCOMP( g_trac_eeprom, EXIT_MRK"eepromReadAttributes()" ); @@ -1746,8 +1780,10 @@ errlHndl_t eepromGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( EEPROM_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_i2cInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = i_i2cInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } @@ -1799,8 +1835,10 @@ errlHndl_t eepromGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( EEPROM_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_i2cInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = i_i2cInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } diff --git a/src/usr/i2c/eepromdd.H b/src/usr/i2c/eepromdd.H index cfff8f679..1dddb0b0e 100755 --- a/src/usr/i2c/eepromdd.H +++ b/src/usr/i2c/eepromdd.H @@ -57,7 +57,7 @@ typedef enum * @brief Structure of common parameters needed by different parts of * the code. */ -typedef struct +struct eeprom_addr_t { uint64_t port; uint64_t engine; @@ -70,7 +70,29 @@ typedef struct uint64_t devSize_KB; // in kilobytes uint64_t chipCount; // number of chips making up eeprom device uint64_t writeCycleTime; // in milliseconds -} eeprom_addr_t; + uint8_t i2cMuxBusSelector; + TARGETING::EntityPath i2cMuxPath; + + /** + * @brief Construct a default eeprom_addr_t + */ + eeprom_addr_t() + : port(0), + engine(0), + devAddr(0), + chip(0), + offset(0), + addrSize(LAST_DEVICE_TYPE), + i2cMasterPath(), + writePageSize(0), + devSize_KB(0), + chipCount(0), + writeCycleTime(0), + i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE), + i2cMuxPath() + { + } +}; /** * diff --git a/src/usr/i2c/errlud_i2c.C b/src/usr/i2c/errlud_i2c.C index 6442e635b..1e33d6ea6 100644 --- a/src/usr/i2c/errlud_i2c.C +++ b/src/usr/i2c/errlud_i2c.C @@ -27,6 +27,7 @@ * * @brief Implementation of classes to log FSI FFDC */ +#include <string.h> // strlen #include "errlud_i2c.H" #include <i2c/i2creasoncodes.H> #include <i2c/eepromddreasoncodes.H> @@ -50,7 +51,7 @@ UdI2CParms::UdI2CParms( uint8_t i_opType, { // Set up Ud instance variables iv_CompId = I2C_COMP_ID; - iv_Version = 1; + iv_Version = 2; iv_SubSection = I2C_UDT_PARAMETERS; //***** Memory Layout ***** @@ -69,7 +70,11 @@ UdI2CParms::UdI2CParms( uint8_t i_opType, // 2 bytes : Bit Rate Divisor // 8 bytes : Timeout Interval // 8 bytes : Timeout Count; + // 1 byte : I2C MUX Bus Selector + // N bytes : I2C MUX path in string form + // Cache the MUX path in string form for reference and easy access + char *l_muxPath = i_args.i2cMuxPath->toString(); char * l_pBuf = reinterpret_cast<char *>( reallocUsrBuf(sizeof(uint8_t)*2 @@ -80,7 +85,9 @@ UdI2CParms::UdI2CParms( uint8_t i_opType, +sizeof(uint8_t)*3 +sizeof(uint64_t) +sizeof(uint16_t) - +sizeof(uint64_t)*2 ) ); + +sizeof(uint64_t)*2 + +sizeof(uint8_t) + +(strlen(l_muxPath) +1) ) ); uint64_t tmp64 = 0; uint32_t tmp32 = 0; uint16_t tmp16 = 0; @@ -157,6 +164,18 @@ UdI2CParms::UdI2CParms( uint8_t i_opType, memcpy(l_pBuf, &tmp64, sizeof(tmp64)); l_pBuf += sizeof(tmp64); + // Begin Version 2 Data + tmp8 = i_args.i2cMuxBusSelector; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + memcpy(l_pBuf, l_muxPath, strlen(l_muxPath)); + l_pBuf += strlen(l_muxPath); + l_pBuf = '\0'; // add a terminator for ease of parsing + ++l_pBuf; + + free(l_muxPath); + l_muxPath = nullptr; } //------------------------------------------------------------------------------ @@ -181,7 +200,7 @@ UdEepromParms::UdEepromParms( uint8_t i_opType, { // Set up Ud instance variables iv_CompId = EEPROM_COMP_ID; - iv_Version = 2; + iv_Version = 3; iv_SubSection = EEPROM_UDT_PARAMETERS; //***** Memory Layout ***** @@ -199,13 +218,20 @@ UdEepromParms::UdEepromParms( uint8_t i_opType, // 8 bytes : Device Size (in KB) // 8 bytes : Chip Count // 8 bytes : Write Cycle Time + // 1 byte : I2C MUX Bus Selector + // N bytes : I2C MUX path in string form + + // Cache the MUX path in string form for reference and easy access + char *l_muxPath = i_i2cInfo.i2cMuxPath.toString(); char * l_pBuf = reinterpret_cast<char *>( reallocUsrBuf(sizeof(uint8_t)*2 +sizeof(uint32_t) +sizeof(uint64_t)*6 +sizeof(uint8_t) - +sizeof(uint64_t)*4 )); + +sizeof(uint64_t)*4 + +sizeof(uint8_t) + +(strlen(l_muxPath) +1) ) ); uint64_t tmp64 = 0; uint32_t tmp32 = 0; @@ -278,6 +304,18 @@ UdEepromParms::UdEepromParms( uint8_t i_opType, memcpy(l_pBuf, &tmp64, sizeof(tmp64)); l_pBuf += sizeof(tmp64); + // Begin Version 3 Data + tmp8 = i_i2cInfo.i2cMuxBusSelector; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + memcpy(l_pBuf, l_muxPath, strlen(l_muxPath)); + l_pBuf += strlen(l_muxPath); + l_pBuf = '\0'; // add a terminator for ease of parsing + ++l_pBuf; + + free(l_muxPath); + l_muxPath = nullptr; } //------------------------------------------------------------------------------ @@ -301,7 +339,7 @@ UdNvdimmParms::UdNvdimmParms( uint8_t i_opType, { // Set up Ud instance variables iv_CompId = NVDIMM_COMP_ID; - iv_Version = 2; + iv_Version = 3; iv_SubSection = NVDIMM_UDT_PARAMETERS; //***** Memory Layout ***** @@ -318,13 +356,20 @@ UdNvdimmParms::UdNvdimmParms( uint8_t i_opType, // 8 bytes : Device Size (in KB) // 8 bytes : Chip Count // 8 bytes : Write Cycle Time + // 1 byte : I2C MUX Bus Selector + // N bytes : I2C MUX path in string form + + // Cache the MUX path in string form for reference and easy access + char *l_muxPath = i_i2cInfo.i2cMuxPath.toString(); char * l_pBuf = reinterpret_cast<char *>( reallocUsrBuf(sizeof(uint8_t)*2 +sizeof(uint32_t) - +sizeof(uint64_t)*6 + +sizeof(uint64_t)*5 +sizeof(uint8_t) - +sizeof(uint64_t)*3 )); + +sizeof(uint64_t)*4 + +sizeof(uint8_t) + +(strlen(l_muxPath) +1) ) ); uint64_t tmp64 = 0; uint32_t tmp32 = 0; @@ -393,6 +438,18 @@ UdNvdimmParms::UdNvdimmParms( uint8_t i_opType, memcpy(l_pBuf, &tmp64, sizeof(tmp64)); l_pBuf += sizeof(tmp64); + // Begin Version 3 Data + tmp8 = i_i2cInfo.i2cMuxBusSelector; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + memcpy(l_pBuf, l_muxPath, strlen(l_muxPath)); + l_pBuf += strlen(l_muxPath); + l_pBuf = '\0'; // add a terminator for ease of parsing + ++l_pBuf; + + free(l_muxPath); + l_muxPath = nullptr; } //------------------------------------------------------------------------------ diff --git a/src/usr/i2c/fapi_i2c_dd.C b/src/usr/i2c/fapi_i2c_dd.C index 23bf5bdbe..bf1771865 100644 --- a/src/usr/i2c/fapi_i2c_dd.C +++ b/src/usr/i2c/fapi_i2c_dd.C @@ -113,9 +113,13 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType, // master target has to exist and can not be just sys target if( (i2cm == nullptr) || (i2cm == sys) ) { + char* l_masterPath = l_i2cInfo.i2cMasterPath.toString(); TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp() - " "I2C Master path (%s) not valid", - l_i2cInfo.i2cMasterPath.toString() ); + l_masterPath); + free(l_masterPath); + l_masterPath = nullptr; + /*@ * @errortype * @reasoncode I2C::INVALID_MASTER_TARGET @@ -317,18 +321,32 @@ errlHndl_t i2cRead( TARGETING::Target * i_target, i_target, o_buffer, io_buffer_size, - DEVICE_I2C_ADDRESS_OFFSET(i_i2cInfo->port, - i_i2cInfo->engine, - i_i2cInfo->devAddr, - i_offset_data_size, - i_offset_data) ); + DEVICE_I2C_ADDRESS_OFFSET( + i_i2cInfo->port, + i_i2cInfo->engine, + i_i2cInfo->devAddr, + i_offset_data_size, + i_offset_data, + i_i2cInfo->i2cMuxBusSelector, + &(i_i2cInfo->i2cMuxPath) ) ); if( l_err ) { + TRACFCOMP(g_trac_i2c, - ERR_MRK"fapi i2cRead(): read failed on %d/%d/0x%X offsetSize=%d " - "with eid 0x%x", i_i2cInfo->port, i_i2cInfo->engine, - i_i2cInfo->devAddr, i_offset_data_size, l_err->eid()); + ERR_MRK"fapi i2cRead(): read failed on %d/%d/0x%X, offsetSize=%d " + "with eid 0x%x", i_i2cInfo->port, + i_i2cInfo->engine, i_i2cInfo->devAddr, i_offset_data_size, + l_err->eid()); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo->i2cMuxPath.toString(); + TRACFCOMP(g_trac_i2c, ERR_MRK"fapi i2cRead(): " + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo->i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; if (i_offset_data_size > 0) { @@ -358,14 +376,27 @@ errlHndl_t i2cWrite( TARGETING::Target * i_target, i_buffer, io_buffer_size, DEVICE_I2C_ADDRESS(i_i2cInfo->port, - i_i2cInfo->engine, - i_i2cInfo->devAddr) ); + i_i2cInfo->engine, + i_i2cInfo->devAddr, + i_i2cInfo->i2cMuxBusSelector, + &(i_i2cInfo->i2cMuxPath) ) ); + if( l_err ) { TRACFCOMP(g_trac_i2c, - ERR_MRK"fapi i2cWrite(): write failed on %d/%d/0x%X length %d " - "with eid 0x%x", i_i2cInfo->port, i_i2cInfo->engine, - i_i2cInfo->devAddr, io_buffer_size, l_err->eid()); + ERR_MRK"fapi i2cWrite(): write failed on %d/%d/0x%X, length %d " + "with eid 0x%x", i_i2cInfo->port, + i_i2cInfo->engine, i_i2cInfo->devAddr, io_buffer_size, + l_err->eid()); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo->i2cMuxPath.toString(); + TRACFCOMP(g_trac_i2c, ERR_MRK"fapi i2cWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo->i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; } diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 9d2e1d620..e74d9ecd4 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -40,6 +40,8 @@ #include <errl/errlentry.H> #include <errl/errlmanager.H> #include <errl/errludtarget.H> +#include <errl/errludstring.H> // ERRORLOG::ErrlUserDetailsString +#include <targeting/common/entitypath.H> #include <targeting/common/targetservice.H> #include <targeting/common/utilFilter.H> #include <targeting/common/predicates/predicates.H> @@ -56,9 +58,7 @@ #include <i2c/eepromif.H> #include <i2c/tpmddif.H> #include <i2c/nvdimmif.H> - -// TODO RTC 94872 Remove the following include in a future commit -#include <initservice/initserviceif.H> +#include <hwas/common/hwas.H> // HwasState // ---------------------------------------------- // Globals @@ -78,7 +78,6 @@ TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE ); //#define TRACUCOMP(args...) TRACFCOMP(args) #define TRACUCOMP(args...) - // ---------------------------------------------- // Defines // ---------------------------------------------- @@ -125,6 +124,15 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args ) { + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cPerformOp() opType(%s), " + "i_target(0x%X), io_buffer(%p), io_buflen(%d), " + "i_accessType(%d)", + i_opType == DeviceFW::READ ? "READ" : "WRITE", + TARGETING::get_huid(i_target), + io_buffer, + io_buflen, + i_accessType); + errlHndl_t err = NULL; // Get the input args our of the va_list @@ -138,7 +146,6 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, // These are additional parms in the case an offset is passed in // via va_list, as well - // Set both Host and FSI switches to 0 so that they get set later by // attribute in i2cCommonOp() args.switches.useHostI2C = 0; @@ -164,7 +171,6 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, l_lockMutex, args ); - if( err ) { TRACFCOMP(g_trac_i2c, "Locking the page FAILED"); @@ -202,30 +208,34 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, I2C_FAILURE_UNLOCKING_EEPROM_PAGE, TARGETING::get_huid(i_target), 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); // TODO RTC 148705: Callout downstream DIMMs err->collectTrace(I2C_COMP_NAME, 256 ); } } } + // Else this is not a page operation, call the normal common function else { args.offset_length = va_arg( i_args, uint64_t); + uint8_t* temp = reinterpret_cast<uint8_t*>(va_arg(i_args, uint64_t)); + args.i2cMuxBusSelector = va_arg( i_args, uint64_t); + args.i2cMuxPath = reinterpret_cast<const TARGETING::EntityPath*>(va_arg(i_args, uint64_t)); + if ( args.offset_length != 0 ) { - args.offset_buffer = reinterpret_cast<uint8_t*> - (va_arg(i_args, uint64_t)); + args.offset_buffer = temp; + } - // Else, call the normal common function - err = i2cCommonOp( i_opType, - i_target, - io_buffer, - io_buflen, - i_accessType, - args ); - } + err = i2cCommonOp( i_opType, + i_target, + io_buffer, + io_buflen, + i_accessType, + args ); + } TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cPerformOp() - %s", @@ -257,6 +267,8 @@ errlHndl_t host_i2cPerformOp( DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args ) { + TRACUCOMP( g_trac_i2c, ENTER_MRK"host_i2cPerformOp()" ); + errlHndl_t err = NULL; // Get the input args our of the va_list @@ -271,11 +283,13 @@ errlHndl_t host_i2cPerformOp( DeviceFW::OperationType i_opType, // via va_list, as well args.offset_length = va_arg( i_args, uint64_t); + uint8_t* temp = reinterpret_cast<uint8_t*>(va_arg(i_args, uint64_t)); + args.i2cMuxBusSelector = va_arg( i_args, uint64_t); + args.i2cMuxPath = reinterpret_cast<const TARGETING::EntityPath*>(va_arg(i_args, uint64_t)); if ( args.offset_length != 0 ) { - args.offset_buffer = reinterpret_cast<uint8_t*> - (va_arg(i_args, uint64_t)); + args.offset_buffer = temp; } // Set Host switch to 1 and FSI switch to 0 @@ -292,7 +306,7 @@ errlHndl_t host_i2cPerformOp( DeviceFW::OperationType i_opType, args ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"host_i2cPerformOp() - %s", ((NULL == err) ? "No Error" : "With Error") ); @@ -322,6 +336,8 @@ errlHndl_t fsi_i2cPerformOp( DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args ) { + TRACUCOMP( g_trac_i2c, ENTER_MRK"fsi_i2cPerformOp()" ); + errlHndl_t err = NULL; // Get the input args our of the va_list @@ -336,11 +352,13 @@ errlHndl_t fsi_i2cPerformOp( DeviceFW::OperationType i_opType, // via va_list, as well args.offset_length = va_arg( i_args, uint64_t); + uint8_t* temp = reinterpret_cast<uint8_t*>(va_arg(i_args, uint64_t)); + args.i2cMuxBusSelector = va_arg( i_args, uint64_t); + args.i2cMuxPath = reinterpret_cast<const TARGETING::EntityPath*>(va_arg(i_args, uint64_t)); if ( args.offset_length != 0 ) { - args.offset_buffer = reinterpret_cast<uint8_t*> - (va_arg(i_args, uint64_t)); + args.offset_buffer = temp; } // Set FSI switch to 1 and Host switch to 0 @@ -357,7 +375,7 @@ errlHndl_t fsi_i2cPerformOp( DeviceFW::OperationType i_opType, args ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"fsi_i2cPerformOp() - %s", ((NULL == err) ? "No Error" : "With Error") ); @@ -460,7 +478,7 @@ errlHndl_t i2cChooseEepromPage(TARGETING::Target * i_target, I2C_INVALID_EEPROM_PAGE_REQUEST, TARGETING::get_huid(i_target), i_desiredPage, - true ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); l_err->collectTrace( I2C_COMP_NAME, 256 ); } } @@ -518,7 +536,7 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, I2C_MASTER_SENTINEL_TARGET, i_opType, 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); l_err->collectTrace( I2C_COMP_NAME, 256); @@ -555,7 +573,7 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, I2C_INVALID_EEPROM_PAGE_MUTEX, TARGETING::get_huid(i_target), 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); l_err->collectTrace( I2C_COMP_NAME, 256 ); break; @@ -569,7 +587,7 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, if( l_err ) { TRACFCOMP(g_trac_i2c, - "Error in i2cPageSwitchOp::i2cSetBusVariables()"); + ERR_MRK"Error in i2cPageSwitchOp::i2cSetBusVariables()"); // Error means we need to unlock the page mutex prematurely l_mutex_needs_unlock = true; @@ -583,7 +601,7 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, (page_array ) ) ) { TRACFCOMP(g_trac_i2c, - "i2cPageSwitchOp() - Cannot find ATTR_EEPROM_PAGE_ARRAY"); + "i2cPageSwitchOp() - Cannot find ATTR_EEPROM_PAGE_ARRAY"); /*@ * @errortype * @reasoncode I2C_ATTRIBUTE_NOT_FOUND @@ -599,7 +617,7 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, I2C_ATTRIBUTE_NOT_FOUND, TARGETING::get_huid(i_target), 0x0, - true ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); l_err->collectTrace( I2C_COMP_NAME, 256 ); l_mutex_needs_unlock = true; break; @@ -639,16 +657,29 @@ errlHndl_t i2cPageSwitchOp( DeviceFW::OperationType i_opType, uint8_t * l_zeroBuffer = static_cast<uint8_t*>(malloc(l_zeroBuflen)); memset(l_zeroBuffer, 0, l_zeroBuflen); - TRACUCOMP(g_trac_i2c,"i2cPageSwitchOp args! \n" "misc_args_t: port:%d / engine: %d: devAddr: %x: skip_mode_step(%d):\n" "with_stop(%d): read_not_write(%d): bus_speed: %d: bit_rate_divisor: %d:\n" - "polling_interval_ns: %d: timeout_count: %d: offset_length: %d", + "polling_interval_ns: %d: timeout_count: %d: offset_length: %d, ", i_args.port, i_args.engine, i_args.devAddr, i_args.skip_mode_setup, i_args.with_stop, i_args.read_not_write, i_args.bus_speed, i_args.bit_rate_divisor, i_args.polling_interval_ns, i_args.timeout_count, - i_args.offset_length ); + i_args.offset_length); + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACUCOMP(g_trac_i2c, "i2cPageSwitchOp(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACUCOMP(g_trac_i2c, "i2cPageSwitchOp(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } // Retry MAX_NACK_RETRIES so we can bypass nacks caused by a busy bus. // Other Nack errors are expected and caused by the empty write @@ -807,7 +838,7 @@ bool i2cPageUnlockOp( TARGETING::Target * i_target, I2C_INVALID_EEPROM_PAGE_MUTEX, TARGETING::get_huid(i_target), 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); l_err->collectTrace( I2C_COMP_NAME, 256 ); errlCommit(l_err, I2C_COMP_ID); @@ -844,6 +875,217 @@ void i2cSetSwitches( TARGETING::Target * i_target, return; } + + +/** +* +* @brief Retrieves the I2C MUX target from the given Entity Path +* +* @param [in] i_i2cMuxPath - the Entity Path for the I2C MUX +* +* @param [out] o_target - The I2C MUX target if Entity Path is found, valid and +* functional, else this is set to nullptr +* +* @return errlHndl_t - NULL if successful, otherwise a pointer to the +* error log. +* +*/ +// ------------------------------------------------------------------ +// i2cGetI2cMuxTarget +// ------------------------------------------------------------------ +errlHndl_t i2cGetI2cMuxTarget ( const TARGETING::EntityPath & i_i2cMuxPath, + TARGETING::Target * &o_target ) +{ + errlHndl_t l_err(nullptr); + o_target = nullptr; + + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cGetI2cMuxTarget()" ); + + do + { + TARGETING::TargetService& l_targetService = TARGETING::targetService(); + + // Retrieve the I2C MUX target from path + o_target = l_targetService.toTarget(i_i2cMuxPath); + + if ( nullptr == o_target ) + { + char* l_muxPath = i_i2cMuxPath.toString(); + TRACFCOMP( g_trac_i2c, + ERR_MRK "i2cGetI2cMuxTarget() - I2C MUX Entity Path (%s)" + " could not be converted to a target.", + l_muxPath ); + + + /*@ + * @errortype + * @reasoncode I2C_MUX_TARGET_NOT_FOUND + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid I2C_ACCESS_MUX + * @devdesc I2C mux path target is null + * @custdesc Unexpected boot firmware error + */ + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + I2C_ACCESS_MUX, + I2C_MUX_TARGET_NOT_FOUND, + 0, + 0, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); + + // Collect the MUX entity path info + ERRORLOG::ErrlUserDetailsString(l_muxPath).addToLog(l_err); + + // Release the mux memory + free(l_muxPath); + l_muxPath = nullptr; + + l_err->collectTrace( I2C_COMP_NAME, 256); + + break; + } + + // Is the target functional + TARGETING::HwasState l_hwasState = + o_target->getAttr<TARGETING::ATTR_HWAS_STATE>(); + if ( !l_hwasState.poweredOn || + !l_hwasState.present || + !l_hwasState.functional ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK "i2cGetI2cMuxTarget() - I2C MUX target (0x%X) " + "is non functional.", + TARGETING::get_huid(o_target) ); + /*@ + * @errortype + * @reasoncode I2C_MUX_TARGET_NON_FUNCTIONAL + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid I2C_ACCESS_MUX + * @userdata1 I2C MUX Target Huid + * @devdesc I2C mux path target is not functional + * @custdesc Unexpected boot firmware error + */ + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + I2C_ACCESS_MUX, + I2C_MUX_TARGET_NON_FUNCTIONAL, + TARGETING::get_huid(o_target), + 0, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); + + // Collect the MUX entity path info + char* l_muxPath = i_i2cMuxPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_muxPath).addToLog(l_err); + free(l_muxPath); + l_muxPath = nullptr; + + l_err->collectTrace( I2C_COMP_NAME, 256); + + // Don't return a non functional target + o_target = nullptr; + + break; + } + } while( 0 ); + + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cGetI2cMuxTarget() - %s", + ((NULL == l_err) ? "No Error" : "With Error") ); + + return l_err; +} // end i2cGetI2cMuxTarget + + +/** +* +* @brief Retrieves the MUX target and sets the MUX to the given bus selector +* +* @param[in] i_masterTarget - I2C Master Target device +* +* @param[in] i_args - A copy of the structure containing arguments +* needed for a command transaction. +* +* @pre i_masterTarget and i_args.i2cMuxPath must not be nullptrs; +* i_args.i2cMuxBusSelector must not be I2C_MUX::NOT_APPLICABLE +* +* @return errlHndl_t - NULL if successful, otherwise a pointer to the +* error log. +* +*/ +// ------------------------------------------------------------------ +// i2cAccessMux +// ------------------------------------------------------------------ +errlHndl_t i2cAccessMux( TARGETING::TargetHandle_t i_masterTarget, + misc_args_t i_args /* make a copy */ ) +{ + TRACUCOMP( g_trac_i2c, + ENTER_MRK"i2cAccessMux(): " + "e/p/devAddr= %d/%d/0x%x, offset=0x%x/%p", + i_args.engine, i_args.port, i_args.devAddr, + i_args.offset_length, i_args.offset_buffer ); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACUCOMP(g_trac_i2c, "i2cAccessMux(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACUCOMP(g_trac_i2c, "i2cAccessMux(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } + + errlHndl_t l_err{nullptr}; + + do + { + TARGETING::TargetHandle_t l_i2cMuxTarget(nullptr); + + l_err = i2cGetI2cMuxTarget(*(i_args.i2cMuxPath), + l_i2cMuxTarget); + + // If an issue getting the MUX target, then return error + if (l_err) + { + break; + } + + TARGETING::I2cMuxInfo l_muxData; + + if (! (l_i2cMuxTarget->tryGetAttr<TARGETING::ATTR_I2C_MUX_INFO>(l_muxData)) ) + { + TRACFCOMP(g_trac_i2c, + "i2cAccessMux(): get attributes failed"); + break; + } + + uint8_t l_muxSelector = i_args.i2cMuxBusSelector; + uint8_t *l_ptrMuxSelector = &l_muxSelector; + size_t l_muxSelectorSize = sizeof(l_muxSelector); + + i_args.i2cMuxBusSelector = I2C_MUX::NOT_APPLICABLE; + l_err = DeviceFW::deviceOp( + DeviceFW::WRITE, + i_masterTarget, + l_ptrMuxSelector, + l_muxSelectorSize, + DEVICE_I2C_ADDRESS(l_muxData.port, + l_muxData.engine, + l_muxData.devAddr, + i_args.i2cMuxBusSelector, + i_args.i2cMuxPath)); + } while (0); + + TRACUCOMP( g_trac_i2c, + EXIT_MRK"i2cAccessMux() - %s", + ((NULL == l_err) ? "No Error" : "With Error") ); + + return l_err; +} // i2cAccessMux + // ------------------------------------------------------------------ // i2cCommonOp // ------------------------------------------------------------------ @@ -862,11 +1104,26 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cCommonOp(): i_opType=%d, aType=%d, " - "p/e/devAddr= %d/%d/0x%x, len=%d, offset=%x/%p", - (uint64_t) i_opType, i_accessType, i_args.port, i_args.engine, + "e/p/devAddr= %d/%d/0x%x, len=%d, offset=0x%x/%p", + static_cast<uint64_t>(i_opType), i_accessType, i_args.engine, i_args.port, i_args.devAddr, io_buflen, i_args.offset_length, i_args.offset_buffer); + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACUCOMP(g_trac_i2c, "i2cCommonOp(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACUCOMP(g_trac_i2c, "i2cCommonOp(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } + do { // Check for Master Sentinel chip @@ -891,7 +1148,7 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, I2C_MASTER_SENTINEL_TARGET, i_opType, 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); err->collectTrace( I2C_COMP_NAME, 256); @@ -901,11 +1158,10 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, //Set Host vs Fsi switches if not done already i2cSetSwitches(i_target, i_args); - // Get the mutex for the requested engine mutex_success = i2cGetEngineMutex( i_target, - i_args, - engineLock ); + i_args, + engineLock ); if( !mutex_success ) { @@ -915,9 +1171,24 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, } // Lock on this engine - (void)mutex_lock( engineLock ); + recursive_mutex_lock( engineLock ); mutex_needs_unlock = true; + if ( (I2C_MUX::NOT_APPLICABLE != i_args.i2cMuxBusSelector) && + (nullptr != i_args.i2cMuxPath) ) + { + err = i2cAccessMux(i_target, i_args ); + } + + if ( err ) + { + TRACFCOMP(g_trac_i2c, + ERR_MRK"i2cCommonOp() - There is an issue accessing " + "the I2C MUX"); + + // Skip performing the actual I2C Operation + break; + } // Calculate variables related to I2C Bus Speed in 'args' struct err = i2cSetBusVariables( i_target, I2C_BUS_SPEED_FROM_MRW, i_args); @@ -928,7 +1199,6 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, break; } - /*******************************************************/ /* Perform the I2C Operation */ /*******************************************************/ @@ -994,9 +1264,7 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, newBufLen, i_args ); - free( newBuffer ); - } /***********************************************/ @@ -1064,7 +1332,7 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, I2C_INVALID_OP_TYPE, i_opType, userdata2, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); err->collectTrace( I2C_COMP_NAME, 256); @@ -1081,14 +1349,13 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, i_args ); break; } - } while( 0 ); // Check if we need to unlock the mutex if ( mutex_needs_unlock == true ) { // Unlock - (void) mutex_unlock( engineLock ); + recursive_mutex_unlock( engineLock ); TRACUCOMP( g_trac_i2c, INFO_MRK"Unlocked engine: %d", i_args.engine ); @@ -1097,7 +1364,6 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, // If there is an error, add FFDC if ( err != NULL ) { - // Add parameter info to log // @todo RTC 114298- update this for new parms/switches I2C::UdI2CParms( i_opType, @@ -1112,7 +1378,7 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, } - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cCommonOp() - %s", ((NULL == err) ? "No Error" : "With Error") ); @@ -1120,7 +1386,6 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, } // end i2cCommonOp - // ------------------------------------------------------------------ // i2cPresence // ------------------------------------------------------------------ @@ -1182,15 +1447,13 @@ bool i2cPresence( TARGETING::Target * i_target, INFO_MRK"Obtaining lock for engine: %d", args.engine ); - (void)mutex_lock( engineLock ); + recursive_mutex_lock( engineLock ); mutex_needs_unlock = true; TRACUCOMP( g_trac_i2c, INFO_MRK"Locked on engine: %d", args.engine ); - - // Set I2C Mode (Host vs FSI) for the target args.switches.useHostI2C = 0; args.switches.useFsiI2C = 0; @@ -1346,7 +1609,7 @@ bool i2cPresence( TARGETING::Target * i_target, if ( mutex_needs_unlock == true ) { // Unlock - (void) mutex_unlock( engineLock ); + recursive_mutex_unlock( engineLock ); TRACUCOMP( g_trac_i2c, INFO_MRK"Unlocked engine: %d", args.engine ); @@ -1381,12 +1644,28 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, status_reg_t status; fifo_reg_t fifo; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cRead()" ); TRACSCOMP( g_trac_i2cr, - "I2C READ START : engine %.2X : port %.2X : devAddr %.2X : len %d", - i_args.engine, i_args.port, i_args.devAddr, i_buflen ); + "I2C READ START : engine %.2X : port %.2X : devAddr %.2X : " + "len %d", + i_args.engine, i_args.port, i_args.devAddr, i_buflen); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACSCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACSCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } do { @@ -1404,7 +1683,7 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, for( bytesRead = 0; bytesRead < i_buflen; bytesRead++ ) { - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, INFO_MRK"Reading byte (%d) out of (%d)", (bytesRead+1), i_buflen ); @@ -1519,8 +1798,23 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, TRACUCOMP( g_trac_i2cr, "I2C READ DATA : engine %.2X : port %.2x : " "devAddr %.2X : byte %d : %.2X (0x%lx)", - i_args.engine, i_args.port, i_args.devAddr, bytesRead, - fifo.byte_0, fifo.value ); + i_args.engine, i_args.port, i_args.devAddr, + bytesRead, fifo.byte_0, fifo.value ); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACUCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, " + "muxPath=%s", i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACUCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, " + "muxPath=NULL", i_args.i2cMuxBusSelector); + } } if( err ) @@ -1539,10 +1833,26 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, } while( 0 ); TRACSCOMP( g_trac_i2cr, - "I2C READ END : engine %.2X : port %.2x : devAddr %.2X : len %d", + "I2C READ END : engine %.2X : port %.2x : devAddr %.2X : " + "len %d", i_args.engine, i_args.port, i_args.devAddr, i_buflen ); - TRACDCOMP( g_trac_i2c, + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACSCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACSCOMP(g_trac_i2c, "i2cRead(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } + + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cRead()" ); return err; @@ -1565,9 +1875,23 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cWrite()" ); - TRACSCOMP( g_trac_i2cr, - "I2C WRITE START : engine %.2X : port %.2X : devAddr %.2X : len %d", - i_args.engine, i_args.port, i_args.devAddr, io_buflen ); + TRACSCOMP( g_trac_i2c, + "I2C WRITE START : engine %.2X : port %.2x : devAddr %.2X : " + "len %d", i_args.engine, i_args.port, i_args.devAddr, io_buflen); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACSCOMP(g_trac_i2c, "i2cWrite(): muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + } + else + { + TRACSCOMP(g_trac_i2c, "i2cWrite(): muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } do { @@ -1635,8 +1959,8 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, } while( 0 ); TRACSCOMP( g_trac_i2cr, - "I2C WRITE END : engine %.2X: port %.2X : devAddr %.2X : len %d", - i_args.engine, i_args.port, i_args.devAddr, io_buflen ); + "I2C WRITE END : engine %.2X: port %.2X : devAddr %.2X : " + "len %d", i_args.engine, i_args.port, i_args.devAddr, io_buflen); TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cWrite()" ); @@ -1653,7 +1977,7 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, { errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cSetup(): buf_len=%d, r_nw=%d, w_stop=%d, sms=%d", i_buflen, i_args.read_not_write, i_args.with_stop, i_args.skip_mode_setup); @@ -1763,7 +2087,7 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, } } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cSetup()" ); return err; @@ -1866,7 +2190,7 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, { errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cWaitForCmdComp()" ); // Define the registers that we'll use @@ -1944,7 +2268,7 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, } } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cWaitForCmdComp()" ); return err; @@ -1959,7 +2283,7 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, { errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cReadStatusReg()" ); do @@ -1994,7 +2318,7 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, } } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cReadStatusReg()" ); return err; @@ -2013,7 +2337,7 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, bool busArbiLostFound = false; uint64_t intRegVal = 0x0; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cCheckForErrors()" ); do @@ -2224,7 +2548,7 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cCheckForErrors()" ); return err; @@ -2246,7 +2570,7 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, // Define regs we'll be using status_reg_t status; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cWaitForFifoSpace()" ); do @@ -2334,7 +2658,7 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, } } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cWaitForFifoSpace()" ); return err; @@ -2349,7 +2673,7 @@ errlHndl_t i2cSendStopSignal(TARGETING::Target * i_target, errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cSendStopSignal" ); do @@ -2433,7 +2757,7 @@ errlHndl_t i2cToggleClockLine(TARGETING::Target * i_target, errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cToggleClockLine()" ); do @@ -2494,7 +2818,7 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target, // I2C Bus Speed Array TARGETING::ATTR_I2C_BUS_SPEED_ARRAY_type speed_array; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cForceResetAndUnlock()" ); do @@ -2523,7 +2847,7 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target, I2C_ATTRIBUTE_NOT_FOUND, TARGETING::get_huid(i_target), 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); err->collectTrace( I2C_COMP_NAME, 256); @@ -2533,7 +2857,7 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target, uint32_t l_numPorts = I2C_BUS_ATTR_MAX_PORT; if (i_args.switches.useFsiI2C == 1) { - TRACDCOMP( g_trac_i2c,INFO_MRK + TRACUCOMP( g_trac_i2c,INFO_MRK "Using FSI I2C, use numports: %d", FSI_MODE_MAX_PORT); l_numPorts = FSI_MODE_MAX_PORT; } @@ -2582,8 +2906,27 @@ errlHndl_t i2cForceResetAndUnlock( TARGETING::Target * i_target, "limitations. Disable diag mode on e2 = %d, " "secure mode enabled = %d", TARGETING::get_huid(i_target), - i_args.engine, port,l_disable_diag_mode, + i_args.engine, port, + l_disable_diag_mode, SECUREBOOT::enabled()); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACFCOMP(g_trac_i2c, INFO_MRK"i2cForceResetAndUnlock(): " + "muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACFCOMP(g_trac_i2c, INFO_MRK"i2cForceResetAndUnlock(): " + "muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } + continue; } } @@ -2691,7 +3034,7 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target, { errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cReset()" ); // Writing to the Status Register does a full I2C reset. @@ -2742,7 +3085,7 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target, } } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cReset()" ); return err; @@ -2765,7 +3108,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, // I2C Bus Speed Array TARGETING::ATTR_I2C_BUS_SPEED_ARRAY_type speed_array; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cSendSlaveStop()" ); do @@ -2795,7 +3138,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, I2C_ATTRIBUTE_NOT_FOUND, TARGETING::get_huid(i_target), 0x0, - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); err->collectTrace( I2C_COMP_NAME, 256); @@ -2805,7 +3148,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, uint32_t l_numPorts = I2C_BUS_ATTR_MAX_PORT; if (i_args.switches.useFsiI2C == 1) { - TRACDCOMP( g_trac_i2c,INFO_MRK + TRACUCOMP( g_trac_i2c,INFO_MRK "Using FSI I2C, use numports: %d", FSI_MODE_MAX_PORT); l_numPorts = FSI_MODE_MAX_PORT; } @@ -2824,7 +3167,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, // presence detect here to remove this workaround if ( (i_args.engine == 1) && (port >= 4) ) { - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, "Saw Errors resetting these devices, temporarily skipping engine: %d, port: %d", i_args.engine, port); continue; @@ -2918,8 +3261,8 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, "Not seeing SCL (%d) high " "after %d ns of polling (max=%d). " "Full status register = 0x%.16llX. " - "Inhibiting sending slave stop to e%/p% for " - "HUID 0x%08X.", + "Inhibiting sending slave stop to e%/p%, " + "for HUID 0x%08X.", status_reg.scl_input_level, delay_ns, I2C_RESET_POLL_DELAY_TOTAL_NS, @@ -2927,6 +3270,24 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, i_args.engine, port, TARGETING::get_huid(i_target)); + + // Printing mux info separately, if combined, nothing is displayed + if (i_args.i2cMuxPath) + { + char* l_muxPath = i_args.i2cMuxPath->toString(); + TRACFCOMP(g_trac_i2c, ERR_MRK"i2cSendSlaveStop(): " + "muxSelector=0x%X, muxPath=%s", + i_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACFCOMP(g_trac_i2c, ERR_MRK"i2cSendSlaveStop(): " + "muxSelector=0x%X, muxPath=NULL", + i_args.i2cMuxBusSelector); + } + continue; } @@ -2967,7 +3328,7 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cSendSlaveStop()" ); return err; @@ -2986,7 +3347,7 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, // Master Regs interrupt_reg_t intreg; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cGetInterrupts()" ); do @@ -3011,7 +3372,7 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, o_intRegValue = intreg.value; } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cGetInterrupts( int reg val: %016llx)", o_intRegValue ); @@ -3104,6 +3465,21 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target, i_speed, io_args.bus_speed, io_args.bit_rate_divisor, io_args.polling_interval_ns, io_args.timeout_count); + // Printing mux info separately, if combined, nothing is displayed + if (io_args.i2cMuxPath) + { + char* l_muxPath = io_args.i2cMuxPath->toString(); + TRACUCOMP(g_trac_i2c, "i2cSetBusVariables(): muxSelector=0x%X, " + "muxPath=%s", io_args.i2cMuxBusSelector, l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + } + else + { + TRACUCOMP(g_trac_i2c, "i2cSetBusVariables(): muxSelector=0x%X, " + "muxPath=NULL", io_args.i2cMuxBusSelector); + } + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cSetBusVariables()" ); @@ -3269,7 +3645,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, TWO_UINT32_TO_UINT64( i_processOperation, i_processType), - true /*Add HB SW Callout*/ ); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT ); err->collectTrace( I2C_COMP_NAME, 256); @@ -3316,7 +3692,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, ( engine != 0 ) && (io_args.switches.useFsiI2C == 1) ) { - TRACDCOMP( g_trac_i2c,INFO_MRK + TRACUCOMP( g_trac_i2c,INFO_MRK "Only reset engine 0 for FSI"); continue; } @@ -3325,7 +3701,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, if ( ( engine == 0 ) && (io_args.switches.useHostI2C == 1) ) { - TRACDCOMP( g_trac_i2c,INFO_MRK + TRACUCOMP( g_trac_i2c,INFO_MRK "Never touch engine 0 for Host"); continue; } @@ -3345,7 +3721,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, size_t l_numPorts = I2C_BUS_ATTR_MAX_PORT; if (io_args.switches.useFsiI2C == 1) { - TRACDCOMP( g_trac_i2c,INFO_MRK + TRACUCOMP( g_trac_i2c,INFO_MRK "Using FSI I2c, use numports: %d", FSI_MODE_MAX_PORT); l_numPorts = FSI_MODE_MAX_PORT; } @@ -3413,7 +3789,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, TRACUCOMP( g_trac_i2c, INFO_MRK"i2cProcessActiveMasters: Obtaining lock for " "engine: %d", engine ); - (void)mutex_lock( engineLock ); + recursive_mutex_lock( engineLock ); mutex_needs_unlock = true; TRACUCOMP( g_trac_i2c,INFO_MRK "i2cProcessActiveMasters: Locked on engine: %d", @@ -3579,7 +3955,7 @@ errlHndl_t i2cProcessActiveMasters ( i2cProcessType i_processType, if ( mutex_needs_unlock == true ) { // Unlock - (void) mutex_unlock( engineLock ); + recursive_mutex_unlock( engineLock ); TRACUCOMP( g_trac_i2c,INFO_MRK "i2cProcessActiveMasters: Unlocked engine: %d", engine ); @@ -3661,7 +4037,7 @@ errlHndl_t i2cSetupActiveMasters ( i2cProcessType i_setupType, // ------------------------------------------------------------------ void i2cSetAccessMode( i2cSetAccessModeType i_setModeType ) { - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cSetAccessMode(): %d", i_setModeType ); TARGETING::I2cSwitches switches; @@ -3728,7 +4104,7 @@ void i2cSetAccessMode( i2cSetAccessModeType i_setModeType ) INFO_MRK"Obtaining lock for engine: %d", args.engine ); - (void)mutex_lock( engineLocks[engine] ); + recursive_mutex_lock( engineLocks[engine] ); TRACUCOMP( g_trac_i2c, INFO_MRK"Locked on engine: %d", @@ -3754,7 +4130,7 @@ void i2cSetAccessMode( i2cSetAccessModeType i_setModeType ) tgt->setAttr<TARGETING::ATTR_I2C_SWITCHES>(switches); - TRACFCOMP( g_trac_i2c,"i2cSetAccessMode: tgt=0x%X " + TRACUCOMP( g_trac_i2c,"i2cSetAccessMode: tgt=0x%X " "I2C_SWITCHES updated: host=%d, fsi=%d", TARGETING::get_huid(tgt), switches.useHostI2C, switches.useFsiI2C); @@ -3769,7 +4145,7 @@ void i2cSetAccessMode( i2cSetAccessModeType i_setModeType ) args.engine = engine; if ( engineLocks[engine] != NULL ) { - (void) mutex_unlock( engineLocks[engine] ); + recursive_mutex_unlock( engineLocks[engine] ); TRACUCOMP( g_trac_i2c, INFO_MRK"Unlocked engine: %d", args.engine ); @@ -3779,7 +4155,7 @@ void i2cSetAccessMode( i2cSetAccessModeType i_setModeType ) } while( 0 ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cSetAccessMode"); return; @@ -3797,7 +4173,7 @@ errlHndl_t i2cRegisterOp ( DeviceFW::OperationType i_opType, { errlHndl_t err = NULL; - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, ENTER_MRK"i2cRegisterOp()"); uint64_t op_addr = 0x0; @@ -3866,7 +4242,7 @@ errlHndl_t i2cRegisterOp ( DeviceFW::OperationType i_opType, i_args.switches.useFsiI2C, op_size, i_reg, op_addr, (*io_data_64) ); - TRACDCOMP( g_trac_i2c, + TRACUCOMP( g_trac_i2c, EXIT_MRK"i2cRegisterOp()" ); return err; @@ -4126,19 +4502,19 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, for(auto const& i2cm : l_i2cInfo) { - TRACDCOMP(g_trac_i2c,"i2c loop - eng=%.8X", TARGETING::get_huid(pChipTarget)); + TRACUCOMP(g_trac_i2c,"i2c loop - eng=%.8X", TARGETING::get_huid(pChipTarget)); /* I2C Busses */ std::list<EEPROM::EepromInfo_t>::iterator l_eep = l_eepromInfo.begin(); while( l_eep != l_eepromInfo.end() ) { - TRACDCOMP(g_trac_i2c,"eeprom loop - eng=%.8X, port=%.8X", TARGETING::get_huid(l_eep->i2cMaster), l_eep->engine ); + TRACUCOMP(g_trac_i2c,"eeprom loop - eng=%.8X, port=%.8X", TARGETING::get_huid(l_eep->i2cMaster), l_eep->engine ); DeviceInfo_t l_currentDI; //ignore the devices that aren't on the current target if( l_eep->i2cMaster != pChipTarget ) { - TRACDCOMP(g_trac_i2c,"skipping unmatched i2cmaster"); + TRACUCOMP(g_trac_i2c,"skipping unmatched i2cmaster"); l_eep = l_eepromInfo.erase(l_eep); continue; } @@ -4146,7 +4522,7 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, //skip the devices that are on a different engine else if( l_eep->engine != i2cm.engine) { - TRACDCOMP(g_trac_i2c,"skipping umatched engine"); + TRACUCOMP(g_trac_i2c,"skipping umatched engine"); ++l_eep; continue; } @@ -4185,7 +4561,7 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, break; } - TRACDCOMP(g_trac_i2c,"Adding addr=%X", l_eep->devAddr); + TRACUCOMP(g_trac_i2c,"Adding addr=0x%X", l_eep->devAddr); o_deviceInfo.push_back(l_currentDI); l_eep = l_eepromInfo.erase(l_eep); } //end of eeprom iter @@ -4239,20 +4615,20 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, #ifdef CONFIG_NVDIMM for (auto& l_nv : l_nvdimmInfo) { - TRACDCOMP(g_trac_i2c,"nvdimm loop - eng=%.8X, port=%.8X", TARGETING::get_huid(l_nv.i2cMaster), l_nv.engine ); + TRACUCOMP(g_trac_i2c,"nvdimm loop - eng=%.8X, port=%.8X", TARGETING::get_huid(l_nv.i2cMaster), l_nv.engine ); DeviceInfo_t l_currentDI; //ignore the devices that aren't on the current target if( l_nv.i2cMaster != pChipTarget ) { - TRACDCOMP(g_trac_i2c,"skipping unmatched i2cmaster"); + TRACUCOMP(g_trac_i2c,"skipping unmatched i2cmaster"); continue; } //skip the devices that are on a different engine else if( l_nv.engine != i2cm.engine) { - TRACDCOMP(g_trac_i2c,"skipping umatched engine"); + TRACUCOMP(g_trac_i2c,"skipping umatched engine"); continue; } @@ -4268,7 +4644,7 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, strcpy(l_currentDI.deviceLabel, "?unknown,unknown,nvdimm,nvdimm"); - TRACDCOMP(g_trac_i2c,"Adding addr=%X", l_nv.devAddr); + TRACUCOMP(g_trac_i2c,"Adding addr=0x%X", l_nv.devAddr); o_deviceInfo.push_back(l_currentDI); } //end of nvdimm iter #endif diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H index dfc79d2d2..13b859060 100755 --- a/src/usr/i2c/i2c.H +++ b/src/usr/i2c/i2c.H @@ -639,12 +639,11 @@ void i2cSetSwitches( TARGETING::Target * i_target, * */ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType, - TARGETING::Target * i_target, - void * io_buffer, - size_t & io_buflen, - int64_t i_accessType, - misc_args_t & i_args ); - + TARGETING::Target * i_target, + void * io_buffer, + size_t & io_buflen, + int64_t i_accessType, + misc_args_t & i_args ); /** * @brief Does the real work of reading from the I2C device. diff --git a/src/usr/i2c/i2c.mk b/src/usr/i2c/i2c.mk index 822f1d948..ac31ba45f 100644 --- a/src/usr/i2c/i2c.mk +++ b/src/usr/i2c/i2c.mk @@ -25,4 +25,5 @@ # common objects with runtime OBJS += eepromdd.o OBJS += errlud_i2c.o +OBJS += mux_i2c.o OBJS += $(if $(CONFIG_NVDIMM),nvdimmdd.o,) diff --git a/src/usr/i2c/i2c_common.H b/src/usr/i2c/i2c_common.H index 1772ea2b2..fdb6029bb 100644 --- a/src/usr/i2c/i2c_common.H +++ b/src/usr/i2c/i2c_common.H @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/i2c/i2c.H $ */ +/* $Source: src/usr/i2c/i2c_common.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -61,6 +61,8 @@ struct misc_args_t uint64_t timeout_count; uint64_t offset_length; uint8_t* offset_buffer; + uint8_t i2cMuxBusSelector; + const TARGETING::EntityPath* i2cMuxPath; TARGETING::I2cSwitches switches; @@ -75,7 +77,9 @@ struct misc_args_t polling_interval_ns(0), timeout_count(0), offset_length(0), - offset_buffer(NULL) + offset_buffer(nullptr), + i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE), + i2cMuxPath(nullptr) { memset(&switches, 0x0, sizeof(switches)); }; diff --git a/src/usr/i2c/mux_i2c.C b/src/usr/i2c/mux_i2c.C new file mode 100644 index 000000000..39447a14c --- /dev/null +++ b/src/usr/i2c/mux_i2c.C @@ -0,0 +1,78 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/i2c/mux_i2c.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file mux_i2c.C + * + * @brief I2C MUX utility functions + * + */ + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include "mux_i2c.H" + +// ----------------------------------------------------------------------------- +// Trace definitions +// ----------------------------------------------------------------------------- +extern trace_desc_t* g_trac_i2c; + +namespace MUX_I2C +{ + +using namespace TARGETING; + +// Register the presence detect for the I2C MUX +DEVICE_REGISTER_ROUTE( DeviceFW::READ, + DeviceFW::PRESENT, + TARGETING::TYPE_I2C_MUX, + i2cMuxPresenceDetect ); + + +// ------------------------------------------------------------------ +// i2cMuxPresenceDetect +// ------------------------------------------------------------------ +errlHndl_t i2cMuxPresenceDetect(DeviceFW::OperationType i_opType, + TargetHandle_t i_target, + void* io_isPresentBuffer, + size_t& io_isPresentBufferSize, + int64_t i_accessType, + va_list i_args) +{ + TRACDCOMP(g_trac_i2c, ENTER_MRK"i2cMuxPresenceDetect()"); + + // Always return true + bool l_present = true; + memcpy(io_isPresentBuffer, &l_present, sizeof(l_present)); + io_isPresentBufferSize = sizeof(l_present); + + TRACDCOMP(g_trac_i2c, EXIT_MRK"i2cMuxPresenceDetect()"); + + return nullptr; +} + + +} // namespace MUX_I2C diff --git a/src/usr/i2c/mux_i2c.H b/src/usr/i2c/mux_i2c.H new file mode 100644 index 000000000..ed39e000a --- /dev/null +++ b/src/usr/i2c/mux_i2c.H @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/i2c/mux_i2c.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __MUX_I2C_H +#define __MUX_I2C_H + +/** + * @file mux_i2c.H + * + * @brief I2C MUX utility functions API + * + */ + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +// Integral support +#include <stdint.h> // uint64_t + +// Error handling support +#include <errl/errlentry.H> // errlHndl_t + +// Targeting support +#include <targeting/common/target.H> // TARGETING::TargetHandle_t + +// Driver support +#include <devicefw/driverif.H> // DeviceFW::OperationType + +namespace MUX_I2C +{ + +/** + * @brief Performs a presence detect operation on an I2C MUX. + * This is used during the target discovery (hwas.C::discoverTargets) phase + * + * @note As of current needs/requirements this always returns true (present). + * + * @param[in] i_opType Operation type, see DeviceFW::OperationType + * in driverif.H + * @param[in] i_target I2C MUX target + * @param[out] o_isPresentBuffer Pointer to output data storage + * Output: is present = 1, is not present = 0 + * @param[out] o_isPresentBufferSize Size of o_isPresentBuffer + * (in bytes, always 1) + * @param[in] i_accessType DeviceFW::AccessType enum (userif.H) + * @param[in] i_args In this function, there are no arguments. + * @return errlHndl_t Returns a pointer to an ErrlEntry if error, + * else nullptr if no error + */ + errlHndl_t i2cMuxPresenceDetect(DeviceFW::OperationType i_opType, + TARGETING::TargetHandle_t i_target, + void* o_isPresentBuffer, + size_t& o_isPresentBufferSize, + int64_t i_accessType, + va_list i_args); +} // namespace MUX_I2C + +#endif diff --git a/src/usr/i2c/nvdimmdd.C b/src/usr/i2c/nvdimmdd.C index b0f1f6aca..6afac1d18 100755 --- a/src/usr/i2c/nvdimmdd.C +++ b/src/usr/i2c/nvdimmdd.C @@ -161,11 +161,20 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType, { TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmPerformOp(): Device Overflow! " - "p/e/dA=%d/%d/0x%X, offset=0x%X, len=0x%X " - "devSizeKB=0x%X", i2cInfo.port, i2cInfo.engine, + "e/p/dA=%d/%d/0x%X, offset=0x%X, len=0x%X " + "devSizeKB=0x%X", + i2cInfo.engine, i2cInfo.port, i2cInfo.devAddr, i2cInfo.offset, io_buflen, - i2cInfo.devSize_KB); + i2cInfo.devSize_KB ); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; /*@ * @errortype @@ -201,11 +210,20 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType, TRACFCOMP( g_trac_nvdimm, "nvdimmPerformOp(): i_opType=%d " - "p/e/dA=%d/%d/0x%X, offset=0x%X, len=0x%X, " + "e/p/dA=%d/%d/0x%X, offset=0x%X, len=0x%X, " "snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X", i_opType, - i2cInfo.port, i2cInfo.engine, i2cInfo.devAddr, + i2cInfo.engine, i2cInfo.port, i2cInfo.devAddr, i2cInfo.offset, io_buflen, l_snglChipSize, - i2cInfo.chipCount, i2cInfo.devSize_KB); + i2cInfo.chipCount, i2cInfo.devSize_KB ); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, "nvdimmPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; // Do the read or write while(l_remainingOpLen > 0) @@ -453,29 +471,41 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target, retry <= NVDIMM_MAX_RETRIES; retry++) { - // Only write the byte address if we have data to write if( 0 != i_byteAddressSize ) { // Use the I2C OFFSET Interface for the READ - l_err = deviceOp( DeviceFW::READ, - i_target, - o_buffer, - i_buflen, - DEVICE_I2C_ADDRESS_OFFSET( - i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr, - i_byteAddressSize, - reinterpret_cast<uint8_t*>(i_byteAddress))); + l_err = deviceOp(DeviceFW::READ, + i_target, + o_buffer, + i_buflen, + DEVICE_I2C_ADDRESS_OFFSET( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + i_byteAddressSize, + reinterpret_cast<uint8_t*>(i_byteAddress), + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath))); if( l_err ) { TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): I2C Read-Offset failed on " - "%d/%d/0x%X aS=%d", + "%d/%d/0x%X, aS=%d", i_i2cInfo.port, i_i2cInfo.engine, - i_i2cInfo.devAddr, i_byteAddressSize); + i_i2cInfo.devAddr, + i_byteAddressSize); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): " + "muxSelector=0x%X, muxPath=%s", + i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + TRACFBIN(g_trac_nvdimm, "i_byteAddress[]", i_byteAddress, i_byteAddressSize); @@ -486,19 +516,32 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target, { // Do the actual read via I2C l_err = deviceOp( DeviceFW::READ, - i_target, - o_buffer, - i_buflen, - DEVICE_I2C_ADDRESS( i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr ) ); + i_target, + o_buffer, + i_buflen, + DEVICE_I2C_ADDRESS( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath) ) ); if( l_err ) { TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): I2C Read failed on " - "%d/%d/0x%0X", i_i2cInfo.port, i_i2cInfo.engine, - i_i2cInfo.devAddr); + "%d/%d/0x%0X", + i_i2cInfo.port, i_i2cInfo.engine, + i_i2cInfo.devAddr ); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): " + "muxSelector=0x%X, muxPath=%s", + i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; // Don't break here -- error handled below } @@ -744,11 +787,21 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target, } TRACUCOMP(g_trac_nvdimm,"nvdimmWrite() Loop: %d/%d/0x%X " - "writeBuflen=%d, offset=0x%X, bAS=%d, diffs=%d/%d", + "writeBuflen=%d, offset=0x%X, " + "bAS=%d, diffs=%d/%d", i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr, newBufLen, i_i2cInfo.offset, byteAddrSize, data_left, diff_wps); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, "nvdimmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // Perform the requested write operation err = nvdimmWriteData( i_target, newBuffer, @@ -831,19 +884,20 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target, retry <= NVDIMM_MAX_RETRIES; retry++) { - // Do the actual data write - err = deviceOp( DeviceFW::WRITE, - i_target, - i_dataToWrite, - i_dataLen, - DEVICE_I2C_ADDRESS_OFFSET( - i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr, - i_byteAddressSize, - reinterpret_cast<uint8_t*>( - i_byteAddress))); - + // Do the actual data write + err = deviceOp( DeviceFW::WRITE, + i_target, + i_dataToWrite, + i_dataLen, + DEVICE_I2C_ADDRESS_OFFSET( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + i_byteAddressSize, + reinterpret_cast<uint8_t*>( + i_byteAddress), + i_i2cInfo.i2cMuxBusSelector, + &(i_i2cInfo.i2cMuxPath) )); if ( err == nullptr ) { @@ -861,6 +915,15 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target, i_i2cInfo.devAddr, i_dataLen, i_i2cInfo.offset, i_i2cInfo.addrSize, retry); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): " + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + err->collectTrace(NVDIMM_COMP_NAME); // break from retry loop @@ -876,6 +939,15 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target, i_i2cInfo.offset, i_i2cInfo.addrSize, i_i2cInfo.writePageSize); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): " + "muxSelector=0x%X, muxPath=%s", + i_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // If op will be attempted again: save error and continue if ( retry < NVDIMM_MAX_RETRIES ) { @@ -1043,7 +1115,7 @@ errlHndl_t nvdimmReadAttributes ( TARGETING::Target * i_target, ENTER_MRK"nvdimmReadAttributes()" ); // These variables will be used to hold the NVDIMM attribute data - // 'EepromNvInfo' struct is kept the same as nvdimm_addr_t via the + // 'EepromNvInfo' struct is kept the same as nvdimm_addr_t via the // attributes. TARGETING::EepromNvInfo nvdimmData; @@ -1090,6 +1162,8 @@ errlHndl_t nvdimmReadAttributes ( TARGETING::Target * i_target, o_i2cInfo.devSize_KB = nvdimmData.maxMemorySizeKB; o_i2cInfo.chipCount = nvdimmData.chipCount; o_i2cInfo.writeCycleTime = nvdimmData.writeCycleTime; + o_i2cInfo.i2cMuxBusSelector = nvdimmData.i2cMuxBusSelector; + o_i2cInfo.i2cMuxPath = nvdimmData.i2cMuxPath; // Convert attribute info to nvdimm_addr_size_t enum if ( nvdimmData.byteAddrOffset == 0x3 ) @@ -1146,6 +1220,14 @@ errlHndl_t nvdimmReadAttributes ( TARGETING::Target * i_target, o_i2cInfo.chipCount, o_i2cInfo.addrSize, nvdimmData.byteAddrOffset, o_i2cInfo.writeCycleTime); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = o_i2cInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_nvdimm, "nvdimmReadAttributes(): " + "muxSelector=0x%X, muxPath=%s", + o_i2cInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; TRACDCOMP( g_trac_nvdimm, EXIT_MRK"nvdimmReadAttributes()" ); @@ -1222,8 +1304,10 @@ errlHndl_t nvdimmGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( NVDIMM_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_i2cInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = i_i2cInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } @@ -1272,8 +1356,10 @@ errlHndl_t nvdimmGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( NVDIMM_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_i2cInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = i_i2cInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } @@ -1362,7 +1448,13 @@ void add_to_list( std::list<EEPROM::EepromInfo_t>& i_list, } i_list.push_back(nv_info); - TRACFCOMP(g_trac_nvdimm,"--Adding i2cm=%.8X, eng=%d, port=%d, addr=%.2X for %.8X", TARGETING::get_huid(i2cm),nvdimmData.engine,nvdimmData.port, nv_info.devAddr, TARGETING::get_huid(nv_info.assocTarg)); + TRACFCOMP(g_trac_nvdimm,"--Adding i2cm=%.8X, eng=%d, port=%d, " + "addr=%.2X for %.8X", + TARGETING::get_huid(i2cm), + nvdimmData.engine, + nvdimmData.port, + nv_info.devAddr, + TARGETING::get_huid(nv_info.assocTarg)); } } @@ -1377,7 +1469,7 @@ bool isNVDIMM( TARGETING::Target * i_target ) { // Not the most elegant way of doing it but the hybrid attributes // are at the MCS level. Need to find my way up to MCS and check - // if the dimm is hybrid + // if the dimm is hybrid TARGETING::TargetHandleList l_mcaList; getParentAffinityTargets(l_mcaList, i_target, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA); @@ -1392,15 +1484,15 @@ bool isNVDIMM( TARGETING::Target * i_target ) // 2-D array. [MCA][DIMM] TARGETING::ATTR_EFF_HYBRID_type l_hybrid; TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE_type l_hybrid_type; - + if( l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID>(l_hybrid) && l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE>(l_hybrid_type) ) { - //Using huid to lookup the hybrid attribute for the current dimm + //Using huid to lookup the hybrid attribute for the current dimm const auto l_dimm_huid = TARGETING::get_huid(i_target); const auto l_mca_huid = TARGETING::get_huid(l_mcaList[0]); - return (l_hybrid[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_IS_HYBRID && + return (l_hybrid[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_IS_HYBRID && l_hybrid_type[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_MEMORY_TYPE_NVDIMM); } } diff --git a/src/usr/i2c/nvdimmdd.H b/src/usr/i2c/nvdimmdd.H index e7885d3d4..e88dbd483 100755 --- a/src/usr/i2c/nvdimmdd.H +++ b/src/usr/i2c/nvdimmdd.H @@ -56,7 +56,7 @@ typedef enum * @brief Structure of common parameters needed by different parts of * the code. */ -typedef struct +struct nvdimm_addr_t { uint64_t port; uint64_t engine; @@ -68,7 +68,28 @@ typedef struct uint64_t devSize_KB; // in kilobytes uint64_t chipCount; // number of chips making up nvdimm device uint64_t writeCycleTime; // in milliseconds -} nvdimm_addr_t; + uint8_t i2cMuxBusSelector; + TARGETING::EntityPath i2cMuxPath; + + /** + * @brief Construct a default nvdimm_addr_t + */ + nvdimm_addr_t() + : port(0), + engine(0), + devAddr(0), + offset(0), + addrSize(LAST_DEVICE_TYPE), + i2cMasterPath(), + writePageSize(0), + devSize_KB(0), + chipCount(0), + writeCycleTime(0), + i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE), + i2cMuxPath() + { + } +}; /* * @brief Miscellaneous enums for NVDIMM @@ -102,7 +123,7 @@ enum * usrif.H * * @param [in] i_args - This is an argument list for the device driver -* framework. This argument list consists of the internal offset +* framework. This argument list consists of the internal offset * to use on the slave I2C device. * * @return errlHndl_t - NULL if successful, otherwise a pointer to the @@ -119,9 +140,9 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType, /* * @brief On the NV Controller, the page is selected by writing to offset * 0x00 with the page you would like to switch too. e.g. to activate - * page 1, write 0x01 to offset 0x00. The user will need to select + * page 1, write 0x01 to offset 0x00. The user will need to select * the page as appropriate. - * Each page contains 256 offsets (0xFF). This function checks if + * Each page contains 256 offsets (0xFF). This function checks if * the offset is outside of 0xFF boundary. * * @param[in] i_offset - The requested read/write offset to the NVDIMM. diff --git a/src/usr/i2c/plugins/errludP_i2c.H b/src/usr/i2c/plugins/errludP_i2c.H index efbd2fa6d..e19dd08fe 100644 --- a/src/usr/i2c/plugins/errludP_i2c.H +++ b/src/usr/i2c/plugins/errludP_i2c.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -95,6 +95,8 @@ public: // 2 bytes : Bit Rate Divisor // 8 bytes : Polling Interval in ns // 8 bytes : Timeout Count; + // 1 byte : I2C MUX Bus Selector + // N bytes : I2C MUX path in string form uint8_t op = TO_UINT8(l_databuf); l_databuf += sizeof(uint8_t); @@ -145,6 +147,15 @@ public: i_parser.PrintNumber("Timeout Count","%.16lX",TO_UINT64(l_databuf)); l_databuf += sizeof(uint64_t); + if (i_version >= 2 ) + { + i_parser.PrintNumber("I2C Mux Selector","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + i_parser.PrintString("I2C Mux Path", l_databuf); + // Increment past the NULL terminated string + 1 (null terminator) + l_databuf += strlen(l_databuf) + 1; + + } } private: @@ -207,6 +218,8 @@ public: // 8 bytes : Device Size (in KB) // 8 bytes : Chip Count // 8 bytes : Write Cycle Time + // 1 byte : I2C MUX Bus Selector + // N bytes : I2C MUX path in string form uint8_t op = TO_UINT8(l_databuf); l_databuf += sizeof(uint8_t); @@ -256,6 +269,14 @@ public: i_parser.PrintNumber("Write Cycle Time","%.16lX",TO_UINT64(l_databuf)); l_databuf += sizeof(uint64_t); + if (i_version >= 3 ) + { + i_parser.PrintNumber("I2C Mux Selector","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + i_parser.PrintString("I2C Mux Path", l_databuf); + // Increment past the NULL terminated string + 1 (null terminator) + l_databuf += (strlen(l_databuf) + 1); + } } private: diff --git a/src/usr/i2c/test/i2ctest.H b/src/usr/i2c/test/i2ctest.H index faa4fd1a2..8e56c2f0b 100755 --- a/src/usr/i2c/test/i2ctest.H +++ b/src/usr/i2c/test/i2ctest.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -300,7 +300,9 @@ class I2CTest: public CxxTest::TestSuite testData[i].size, DEVICE_I2C_ADDRESS( testData[i].port, testData[i].engine, - testData[i].devAddr ) ); + testData[i].devAddr, + 0xFF, + nullptr) ); if( err ) { @@ -529,7 +531,9 @@ class I2CTest: public CxxTest::TestSuite testData[i].devAddr, sizeof(testData[i].offset), reinterpret_cast<uint8_t*>( - &(testData[i].offset)))); + &(testData[i].offset)), + 0xFF, + nullptr)); if( err ) { @@ -840,7 +844,9 @@ class I2CTest: public CxxTest::TestSuite size, DEVICE_I2C_ADDRESS( 0x0, 0x0, - 0x50 ) ); + 0x50, + 0xFF, + nullptr) ); if( !err ) { @@ -902,7 +908,9 @@ class I2CTest: public CxxTest::TestSuite dataSize, DEVICE_I2C_ADDRESS( 0x0, 0x0, - 0x50 ) ); + 0x50, + 0xFF, + nullptr) ); if( NULL == err ) { @@ -979,7 +987,9 @@ class I2CTest: public CxxTest::TestSuite data_size, DEVICE_I2C_ADDRESS( 0, 0, - 0xAC ) ); + 0xAC, + 0xFF, + nullptr) ); } diff --git a/src/usr/i2c/tpmdd.C b/src/usr/i2c/tpmdd.C index 68cb8081b..e782faf13 100755 --- a/src/usr/i2c/tpmdd.C +++ b/src/usr/i2c/tpmdd.C @@ -94,7 +94,6 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, TARGETING::TYPE_TPM, tpmPerformOp ); - // ------------------------------------------------------------------ // tpmPerformOp // ------------------------------------------------------------------ @@ -146,6 +145,16 @@ errlHndl_t tpmPerformOp( DeviceFW::OperationType i_opType, tpmInfo.engine, tpmInfo.port, tpmInfo.devAddr, tpmInfo.operation); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_DISABLED_VIA_MRW @@ -190,6 +199,15 @@ errlHndl_t tpmPerformOp( DeviceFW::OperationType i_opType, tpmInfo.port, tpmInfo.devAddr, tpmInfo.operation, io_buflen); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; /*@ * @errortype @@ -277,6 +295,16 @@ errlHndl_t tpmPerformOp( DeviceFW::OperationType i_opType, tpmInfo.port, tpmInfo.devAddr, tpmInfo.operation, i_opType); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPerformOp(): " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_INVALID_OPERATION @@ -430,7 +458,7 @@ bool tpmPresence (TARGETING::Target* i_pTpm) TRACFCOMP(g_trac_tpmdd,ERR_MRK "tpmPresence: Sampled TPM vendor ID did not match expected " "vendor ID! " - "TPM HUID=0x%08X, e/p/dA=%d/%d/0x%02X, " + "TPM HUID=0x%08X, e/p/dA=%d/%d/0x%02X" "Actual vendor ID=0x%08X, expected vendor ID=0x%08X.", TARGETING::get_huid(i_pTpm), tpmInfo.engine, @@ -438,6 +466,16 @@ bool tpmPresence (TARGETING::Target* i_pTpm) static_cast<uint64_t>(tpmInfo.devAddr), vendorId, TPMDD::TPM_VENDORID); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPresence: " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; } /*@ @@ -476,13 +514,23 @@ bool tpmPresence (TARGETING::Target* i_pTpm) { TRACFCOMP(g_trac_tpmdd,ERR_MRK "tpmPresence: tpmRead: Failed to read TPM family ID! " - "TPM HUID=0x%08X, e/p/dA=%d/%d/0x%02X. " + "TPM HUID=0x%08X, e/p/dA=%d/%d/0x%02X", TRACE_ERR_FMT, TARGETING::get_huid(i_pTpm), tpmInfo.engine, tpmInfo.port, static_cast<uint64_t>(tpmInfo.devAddr), TRACE_ERR_ARGS(pError)); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPresence: " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; } break; @@ -503,6 +551,16 @@ bool tpmPresence (TARGETING::Target* i_pTpm) static_cast<uint64_t>(tpmInfo.devAddr), familyId, TPMDD::TPM_FAMILYID); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPresence: " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; } /*@ @@ -537,6 +595,17 @@ bool tpmPresence (TARGETING::Target* i_pTpm) static_cast<uint64_t>(tpmInfo.devAddr), vendorId, familyId); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + INFO_MRK"tpmPresence: " + "muxSelector=0x%X, muxPath=%s", + tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + present = true; } @@ -619,6 +688,9 @@ bool tpmPresence (TARGETING::Target* i_pTpm) return present; } +// ------------------------------------------------------------------ +// tpmPresenceDetect +// ------------------------------------------------------------------ errlHndl_t tpmPresenceDetect(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, @@ -693,7 +765,6 @@ errlHndl_t tpmRead ( void * o_buffer, retry <= TPM_MAX_RETRIES; retry++) { - // Only write the byte address if we have data to write if( 0 != byteAddrSize ) { @@ -703,12 +774,13 @@ errlHndl_t tpmRead ( void * o_buffer, o_buffer, i_buflen, DEVICE_I2C_ADDRESS_OFFSET( - i_tpmInfo.port, - i_tpmInfo.engine, - i_tpmInfo.devAddr, - byteAddrSize, - reinterpret_cast<uint8_t*>(&byteAddr))); - + i_tpmInfo.port, + i_tpmInfo.engine, + i_tpmInfo.devAddr, + byteAddrSize, + reinterpret_cast<uint8_t*>(&byteAddr), + i_tpmInfo.i2cMuxBusSelector, + &(i_tpmInfo.i2cMuxPath) ) ); if( err ) { TRACFCOMP(g_trac_tpmdd, @@ -722,6 +794,16 @@ errlHndl_t tpmRead ( void * o_buffer, TRACFBIN(g_trac_tpmdd, "byteAddr[]", &byteAddr, byteAddrSize); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmRead(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // Don't break here -- error handled below } } @@ -732,10 +814,12 @@ errlHndl_t tpmRead ( void * o_buffer, i_tpmInfo.i2cTarget, o_buffer, i_buflen, - DEVICE_I2C_ADDRESS( i_tpmInfo.port, - i_tpmInfo.engine, - i_tpmInfo.devAddr ) ); - + DEVICE_I2C_ADDRESS( + i_tpmInfo.port, + i_tpmInfo.engine, + i_tpmInfo.devAddr, + i_tpmInfo.i2cMuxBusSelector, + &(i_tpmInfo.i2cMuxPath) ) ); if( err ) { TRACFCOMP(g_trac_tpmdd, @@ -747,6 +831,16 @@ errlHndl_t tpmRead ( void * o_buffer, i_tpmInfo.operation, i_buflen); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmRead(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // Don't break here -- error handled below } } @@ -780,6 +874,16 @@ errlHndl_t tpmRead ( void * o_buffer, err_RETRY->eid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmRead(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + err_RETRY->collectTrace(TPMDD_COMP_NAME); } else @@ -797,6 +901,16 @@ errlHndl_t tpmRead ( void * o_buffer, err->reasonCode(), err->eid(), err->plid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmRead(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + ERRORLOG::ErrlUserDetailsString( "Another ERROR found") .addToLog(err_RETRY); @@ -827,6 +941,16 @@ errlHndl_t tpmRead ( void * o_buffer, err->reasonCode(), err->eid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmRead(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + err->collectTrace(TPMDD_COMP_NAME); // break from retry loop @@ -930,11 +1054,13 @@ errlHndl_t tpmWrite ( void * i_buffer, i_buffer, i_buflen, DEVICE_I2C_ADDRESS_OFFSET( - i_tpmInfo.port, - i_tpmInfo.engine, - i_tpmInfo.devAddr, - byteAddrSize, - reinterpret_cast<uint8_t*>(&byteAddr))); + i_tpmInfo.port, + i_tpmInfo.engine, + i_tpmInfo.devAddr, + byteAddrSize, + reinterpret_cast<uint8_t*>(&byteAddr), + i_tpmInfo.i2cMuxBusSelector, + &(i_tpmInfo.i2cMuxPath) ) ); if( err ) { @@ -946,6 +1072,17 @@ errlHndl_t tpmWrite ( void * i_buffer, i_tpmInfo.port, i_tpmInfo.devAddr, i_tpmInfo.operation, i_tpmInfo.offset, byteAddrSize, i_buflen); + + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + TRACFBIN(g_trac_tpmdd, "byteAddr[]", &byteAddr, byteAddrSize); @@ -959,9 +1096,12 @@ errlHndl_t tpmWrite ( void * i_buffer, i_tpmInfo.i2cTarget, i_buffer, i_buflen, - DEVICE_I2C_ADDRESS( i_tpmInfo.port, - i_tpmInfo.engine, - i_tpmInfo.devAddr ) ); + DEVICE_I2C_ADDRESS( + i_tpmInfo.port, + i_tpmInfo.engine, + i_tpmInfo.devAddr, + i_tpmInfo.i2cMuxBusSelector, + &(i_tpmInfo.i2cMuxPath) ) ); if( err ) { @@ -974,6 +1114,16 @@ errlHndl_t tpmWrite ( void * i_buffer, i_tpmInfo.operation, i_buflen); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + // Don't break here -- error handled below } } @@ -1007,6 +1157,16 @@ errlHndl_t tpmWrite ( void * i_buffer, err_RETRY->eid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + err_RETRY->collectTrace(TPMDD_COMP_NAME); } else @@ -1024,6 +1184,16 @@ errlHndl_t tpmWrite ( void * i_buffer, err->reasonCode(), err->eid(), err->plid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + ERRORLOG::ErrlUserDetailsString( "Another ERROR found") .addToLog(err_RETRY); @@ -1054,6 +1224,16 @@ errlHndl_t tpmWrite ( void * i_buffer, err->reasonCode(), err->eid(), retry, TPM_MAX_RETRIES); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWrite(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + err->collectTrace(TPMDD_COMP_NAME); // break from retry loop @@ -1388,6 +1568,8 @@ errlHndl_t tpmReadAttributes ( TARGETING::Target * i_target, io_tpmInfo.i2cMasterPath = tpmData.i2cMasterPath; io_tpmInfo.tpmEnabled = tpmData.tpmEnabled; io_tpmInfo.tpmTarget = i_target; + io_tpmInfo.i2cMuxBusSelector = tpmData.i2cMuxBusSelector; + io_tpmInfo.i2cMuxPath = tpmData.i2cMuxPath; // Convert attribute info to tpm_addr_size_t enum if ( tpmData.byteAddrOffset == 0x2 ) @@ -1482,13 +1664,22 @@ errlHndl_t tpmReadAttributes ( TARGETING::Target * i_target, } while( 0 ); - TRACUCOMP(g_trac_tpmdd,"tpmReadAttributes() tgt=0x%X, e/p/dA=%d/%d/0x%X " + TRACUCOMP(g_trac_tpmdd,"tpmReadAttributes() tgt=0x%X, e/p/dA=%d/%d/0x%X, " "En=%d, aS=%d, aO=%d", TARGETING::get_huid(i_target), io_tpmInfo.engine, io_tpmInfo.port, io_tpmInfo.devAddr, io_tpmInfo.tpmEnabled, io_tpmInfo.addrSize, tpmData.byteAddrOffset); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = io_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, "tpmReadAttributes(): " + "muxSelector=0x%X, muxPath=%s", + io_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + TRACDCOMP( g_trac_tpmdd, EXIT_MRK"tpmReadAttributes()" ); @@ -1563,8 +1754,10 @@ errlHndl_t tpmGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( TPMDD_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - io_tpmInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = io_tpmInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } @@ -1613,8 +1806,10 @@ errlHndl_t tpmGetI2CMasterTarget ( TARGETING::Target * i_target, err->collectTrace( TPMDD_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - io_tpmInfo.i2cMasterPath.toString()).addToLog(err); + char* l_masterPath = io_tpmInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; break; } @@ -1688,6 +1883,16 @@ errlHndl_t tpmReadSTSRegValid ( tpm_info_t i_tpmInfo, i_tpmInfo.port, i_tpmInfo.devAddr, o_stsReg.value); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmReadSTSRegValid(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_TIMEOUT @@ -1796,9 +2001,20 @@ errlHndl_t tpmPollForCommandReady( const tpm_info_t & i_tpmInfo) "e/p/dA=%d/%d/0x%X, OP=%d, " "STS=0x%X", i_tpmInfo.engine, - i_tpmInfo.port, i_tpmInfo.devAddr, i_tpmInfo.operation, + i_tpmInfo.port, i_tpmInfo.devAddr, + i_tpmInfo.operation, stsReg.value ); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPollForCommandReady(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_TIMEOUT @@ -1819,9 +2035,10 @@ errlHndl_t tpmPollForCommandReady( const tpm_info_t & i_tpmInfo) err->collectTrace( TPMDD_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_tpmInfo.i2cMasterPath.toString()).addToLog(err); - + char* l_masterPath = i_tpmInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; } return err; @@ -1885,12 +2102,22 @@ errlHndl_t tpmPollForDataAvail( const tpm_info_t & i_tpmInfo) TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmPollForDataAvail() - " "Timeout polling for dataAvail! " - "e/p/dA=%d/%d/0x%X, OP=%d, " - "STS=0x%X", + "e/p/dA=%d/%d/0x%X, OP=%d, STS=0x%X", i_tpmInfo.engine, - i_tpmInfo.port, i_tpmInfo.devAddr, i_tpmInfo.operation, + i_tpmInfo.port, i_tpmInfo.devAddr, + i_tpmInfo.operation, stsReg.value ); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmPollForDataAvail(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_TIMEOUT @@ -1911,9 +2138,10 @@ errlHndl_t tpmPollForDataAvail( const tpm_info_t & i_tpmInfo) err->collectTrace( TPMDD_COMP_NAME ); - ERRORLOG::ErrlUserDetailsString( - i_tpmInfo.i2cMasterPath.toString()).addToLog(err); - + char* l_masterPath = i_tpmInfo.i2cMasterPath.toString(); + ERRORLOG::ErrlUserDetailsString(l_masterPath).addToLog(err); + free(l_masterPath); + l_masterPath = nullptr; } return err; @@ -2049,12 +2277,21 @@ errlHndl_t tpmWriteFifo( const tpm_info_t & i_tpmInfo, // TPM is not expecting more data, we overflowed TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmWriteFifo(): Data Overflow! " - "e/p/dA=%d/%d/0x%X, blen=%d, " - "clen=%d", + "e/p/dA=%d/%d/0x%X, blen=%d, clen=%d", i_tpmInfo.engine, i_tpmInfo.port, i_tpmInfo.devAddr, i_buflen, curByte); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWriteFifo(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_OVERFLOW_ERROR @@ -2135,12 +2372,21 @@ errlHndl_t tpmWriteFifo( const tpm_info_t & i_tpmInfo, { TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmWriteFifo(): Timeout! " - "e/p/dA=%d/%d/0x%X, blen=%d, " - "clen=%d", + "e/p/dA=%d/%d/0x%X, blen=%d, clen=%d", i_tpmInfo.engine, i_tpmInfo.port, i_tpmInfo.devAddr, i_buflen, curByte); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWriteFifo(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_TIMEOUT @@ -2177,12 +2423,21 @@ errlHndl_t tpmWriteFifo( const tpm_info_t & i_tpmInfo, // TPM is expecting more data even though we think we are done TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmWriteFifo(): Data Underflow! " - "e/p/dA=%d/%d/0x%X, blen=%d, " - "clen=%d", + "e/p/dA=%d/%d/0x%X, blen=%d, clen=%d", i_tpmInfo.engine, i_tpmInfo.port, i_tpmInfo.devAddr, i_buflen, curByte); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmWriteFifo(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_UNDERFLOW_ERROR @@ -2254,12 +2509,21 @@ errlHndl_t tpmReadFifo( const tpm_info_t & i_tpmInfo, // TPM is expecting more data even though we think we are done TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmReadFifo(): Data Overflow! " - "e/p/dA=%d/%d/0x%X, blen=%d, " - "clen=%d", + "e/p/dA=%d/%d/0x%X, blen=%d, clen=%d", i_tpmInfo.engine, i_tpmInfo.port, i_tpmInfo.devAddr, io_buflen, curByte + burstCount); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmReadFifo(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_OVERFLOW_ERROR @@ -2317,12 +2581,21 @@ errlHndl_t tpmReadFifo( const tpm_info_t & i_tpmInfo, { TRACFCOMP( g_trac_tpmdd, ERR_MRK"tpmReadFifo(): Timeout! " - "e/p/dA=%d/%d/0x%X, blen=%d, " - "clen=%d", + "e/p/dA=%d/%d/0x%X, blen=%d, clen=%d", i_tpmInfo.engine, i_tpmInfo.port, i_tpmInfo.devAddr, io_buflen, curByte); + // Printing mux info separately, if combined, nothing is displayed + char* l_muxPath = i_tpmInfo.i2cMuxPath.toString(); + TRACFCOMP(g_trac_tpmdd, + ERR_MRK"tpmReadFifo(): " + "muxSelector=0x%X, muxPath=%s", + i_tpmInfo.i2cMuxBusSelector, + l_muxPath); + free(l_muxPath); + l_muxPath = nullptr; + /*@ * @errortype * @reasoncode TPM_TIMEOUT diff --git a/src/usr/i2c/tpmdd.H b/src/usr/i2c/tpmdd.H index b48d73aab..be184e921 100755 --- a/src/usr/i2c/tpmdd.H +++ b/src/usr/i2c/tpmdd.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -108,9 +108,6 @@ union tpm_sts_reg_t } PACKED; }; - - - /** * * @brief Perform a TPM access operation. @@ -506,7 +503,6 @@ errlHndl_t tpmPresenceDetect(DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args); - }; // end TPMDD namespace #endif // __TPMDD_H diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 1c574ebaa..bffa2e9cb 100755 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -509,7 +509,7 @@ <id>I2C_ENGINE_MUTEX_0</id> <description>Mutex for I2C Master engine 0</description> <simpleType> - <hbmutex/> + <hbrecursivemutex/> </simpleType> <persistency>volatile-zeroed</persistency> <readable/> @@ -521,7 +521,7 @@ <id>I2C_ENGINE_MUTEX_1</id> <description>Mutex for I2C Master engine 1</description> <simpleType> - <hbmutex/> + <hbrecursivemutex/> </simpleType> <persistency>volatile-zeroed</persistency> <readable/> @@ -533,7 +533,7 @@ <id>I2C_ENGINE_MUTEX_2</id> <description>Mutex for I2C Master engine 2</description> <simpleType> - <hbmutex/> + <hbrecursivemutex/> </simpleType> <persistency>volatile-zeroed</persistency> <readable/> @@ -545,7 +545,7 @@ <id>I2C_ENGINE_MUTEX_3</id> <description>Mutex for I2C Master engine 3</description> <simpleType> - <hbmutex/> + <hbrecursivemutex/> </simpleType> <persistency>volatile-zeroed</persistency> <readable/> diff --git a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml index 99aa13feb..f93730c46 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml @@ -333,6 +333,24 @@ <type>uint8_t</type> <default>0</default> </field> + <!-- i2c Mux Bus Selector Definition --> + <field> + <default>0xFF</default> + <description>Determines which of the N selectable buses the mux + will connect to. OxFF indicates no mux present + or N/A.</description> + <name>i2cMuxBusSelector</name> + <type>uint8_t</type> + </field> + <!-- i2c Mux Path Definition --> + <field> + <!-- NOTE: physical:sys-0 implies that there is no mux in + the bus path for this part. --> + <default>physical:sys-0</default> + <description>Entity path to the I2C mux for this device.</description> + <name>i2cMuxPath</name> + <type>EntityPath</type> + </field> </complexType> <persistency>non-volatile</persistency> <readable/> diff --git a/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml b/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml index 665e9c234..a8e8e9939 100644 --- a/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml @@ -517,7 +517,7 @@ <default>400,400,0,0,0,0,0,0,0,0,0,0,0, 400,400,400,400,0,0,0,0,0,0,0,0,0, 400,400,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0</default> + 0,400,0,0,0,0,0,0,0,0,0,0,0</default> </attribute> <attribute> <id>MRU_ID</id> |