diff options
Diffstat (limited to 'src/usr/i2c')
-rwxr-xr-x | src/usr/i2c/eepromdd.C | 452 | ||||
-rwxr-xr-x | src/usr/i2c/eepromdd.H | 17 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 426 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.H | 144 | ||||
-rwxr-xr-x | src/usr/i2c/test/eepromddtest.H | 417 | ||||
-rwxr-xr-x | src/usr/i2c/test/i2ctest.H | 122 |
6 files changed, 973 insertions, 605 deletions
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C index f734b66cc..8ea9b94c1 100755 --- a/src/usr/i2c/eepromdd.C +++ b/src/usr/i2c/eepromdd.C @@ -38,10 +38,10 @@ #include <trace/interface.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> +#include <errl/errludtarget.H> #include <targeting/common/targetservice.H> #include <devicefw/driverif.H> #include <i2c/eepromddreasoncodes.H> - #include <i2c/eepromif.H> #include "eepromdd.H" @@ -90,6 +90,7 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD, TARGETING::TYPE_MEMBUF, eepromPerformOp ); + // ------------------------------------------------------------------ // eepromPerformOp // ------------------------------------------------------------------ @@ -103,7 +104,6 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, errlHndl_t err = NULL; TARGETING::Target * theTarget = NULL; eeprom_addr_t i2cInfo; - i2cInfo.deviceType = LAST_DEVICE_TYPE; i2cInfo.chip = va_arg( i_args, uint64_t ); i2cInfo.offset = va_arg( i_args, uint64_t ); @@ -138,6 +138,38 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, break; } + // Check that the offset + data length is less than device max size + if ( ( i2cInfo.offset + io_buflen ) > + ( i2cInfo.devSize_KB * KILOBYTE ) ) + { + 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, + io_buflen, i2cInfo.devSize_KB); + + + /*@ + * @errortype + * @reasoncode EEPROM_OVERFLOW_ERROR + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid EEPROM_PERFORM_OP + * @userdata1[0:31] Offset + * @userdata1[32:63] Buffer Length + * @userdata2 Device Max Size (in KB) + * @devdesc I2C Buffer Length + Offset > Max Size + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EEPROM_PERFORM_OP, + EEPROM_OVERFLOW_ERROR, + TWO_UINT32_TO_UINT64( + i2cInfo.offset, + io_buflen ), + i2cInfo.devSize_KB ); + break; + } + // Do the read or write if( i_opType == DeviceFW::READ ) { @@ -187,6 +219,13 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType, } } while( 0 ); + + // If there is an error, add target to log + if ( (err != NULL) && (i_target != NULL) ) + { + ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(err); + } + TRACDCOMP( g_trac_eeprom, EXIT_MRK"eepromPerformOp() - %s", ((NULL == err) ? "No Error" : "With Error") ); @@ -250,7 +289,7 @@ errlHndl_t eepromRead ( TARGETING::Target * i_target, { TRACFCOMP(g_trac_eeprom, ERR_MRK"eepromRead(): I2C Read-Offset failed on " - "%d/%d/0x%x", + "%d/%d/0x%X", i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr); break; } @@ -269,7 +308,7 @@ errlHndl_t eepromRead ( TARGETING::Target * i_target, if( err ) { TRACFCOMP(g_trac_eeprom, - ERR_MRK"eepromRead(): I2C Read failed on %d/%d/0x%x", + ERR_MRK"eepromRead(): I2C Read failed on %d/%d/0x%0X", i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr); break; } @@ -312,7 +351,6 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, uint8_t * newBuffer = NULL; bool needFree = false; bool unlock = false; - eeprom_addr_t l_i2cInfo = i_i2cInfo; TRACDCOMP( g_trac_eeprom, ENTER_MRK"eepromWrite()" ); @@ -337,8 +375,8 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, // EEPROM devices have write page boundaries, so when necessary // need to split up command into multiple write operations - // Setup a max-size buffer of byteAddrSize + writePageSize - size_t newBufLen = byteAddrSize + i_i2cInfo.writePageSize; + // Setup a max-size buffer of writePageSize + size_t newBufLen = i_i2cInfo.writePageSize; newBuffer = static_cast<uint8_t*>(malloc( newBufLen )); needFree = true; @@ -351,7 +389,6 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, // variables to store different amount of data length size_t loop_data_length = 0; - size_t loop_buffer_length = 0; size_t total_bytes_written = 0; for ( uint64_t i = 0 ; @@ -372,55 +409,56 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, loop_data_length = io_buflen % i_i2cInfo.writePageSize; } - // Update the offset for each loop - l_i2cInfo.offset += i * i_i2cInfo.writePageSize; + // Add the data the user wanted to write + memcpy( newBuffer, + &l_data_ptr[i * i_i2cInfo.writePageSize], + loop_data_length); + - err = eepromPrepareAddress( &byteAddr, - byteAddrSize, - l_i2cInfo ); - if (err) + // Update the offset for each loop after the first one + if ( i > 0 ) { - break; + i_i2cInfo.offset += i_i2cInfo.writePageSize; } - // Add the byte address to the buffer - memcpy( newBuffer, - byteAddr, - byteAddrSize ); + // Setup offset/address parms + err = eepromPrepareAddress( &byteAddr, + byteAddrSize, + i_i2cInfo ); - // Now add the data the user wanted to write - memcpy( &newBuffer[byteAddrSize], - &l_data_ptr[i * i_i2cInfo.writePageSize], - loop_data_length); + if( err ) + { + break; + } - // Calculate Total Length - loop_buffer_length = loop_data_length + byteAddrSize; - TRACUCOMP(g_trac_eeprom,"eepromWrite() Loop: %d/%d/0x%x " - "loop=%d, l_b_l=%d, l_d_l=%d, offset=0x%x", - i_i2cInfo.port, i_i2cInfo.engine, - i_i2cInfo.devAddr, i, loop_buffer_length, loop_data_length, - l_i2cInfo.offset); + TRACUCOMP(g_trac_eeprom,"eepromWrite() Loop: %d/%d/0x%X " + "loop=%d, l_d_l=%d, offset=0x%X, bAS=%d", + i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr, + i, loop_data_length, i_i2cInfo.offset, byteAddrSize); // Do the actual data write err = deviceOp( DeviceFW::WRITE, i_target, newBuffer, - loop_buffer_length, - DEVICE_I2C_ADDRESS( i_i2cInfo.port, - i_i2cInfo.engine, - i_i2cInfo.devAddr ) ); + loop_data_length, + DEVICE_I2C_ADDRESS_OFFSET( + i_i2cInfo.port, + i_i2cInfo.engine, + i_i2cInfo.devAddr, + byteAddrSize, + reinterpret_cast<uint8_t*>( + &byteAddr))); if( err ) { TRACFCOMP(g_trac_eeprom, - ERR_MRK"eepromWrite(): I2C Write failed on %d/%d/0x%x " - "loop=%d, l_b_l=%d, offset=0x%x", - i_i2cInfo.port, i_i2cInfo.engine, - i_i2cInfo.devAddr, i, loop_buffer_length, l_i2cInfo.offset); - + ERR_MRK"eepromWrite(): I2C Write failed on %d/%d/0x%X " + "loop=%d, l_d_l=%d, offset=0x%X, aS=%d", + i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr, i, + loop_data_length, i_i2cInfo.offset, i_i2cInfo.addrSize); // Can't assume that anything was written if // there was an error, so no update to total_bytes_written @@ -430,7 +468,8 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, // Update how much data was written total_bytes_written += loop_data_length; - } + + } // end of write for-loop // Release mutex lock mutex_unlock( &g_eepromMutex ); @@ -473,7 +512,7 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, // ------------------------------------------------------------------ // eepromPrepareAddress // ------------------------------------------------------------------ -errlHndl_t eepromPrepareAddress ( void * o_buffer, +errlHndl_t eepromPrepareAddress ( void * io_buffer, size_t & o_bufSize, eeprom_addr_t i_i2cInfo ) { @@ -486,57 +525,53 @@ errlHndl_t eepromPrepareAddress ( void * o_buffer, do { + // -------------------------------------------------------------------- - // @todo RTC:72715 - support different I2C devices and the way - // they handle addressing. A new attribute will need to be added to - // EEPROM_ADDR_INFOx to indicate the device type so the addressing - // here can be handled properly. - // - // Until we get a different device, we'll just code for the 2 examples - // that I know of now. + // Currently only supporting I2C devices and that use 0, 1, or 2 bytes + // to set the offset (ie, internal address) into the device. // -------------------------------------------------------------------- - switch( i_i2cInfo.deviceType ) + switch( i_i2cInfo.addrSize ) { case TWO_BYTE_ADDR: o_bufSize = 2; - memset( o_buffer, 0x0, o_bufSize ); - *((uint8_t*)o_buffer) = (i_i2cInfo.offset & 0xFF00ull) >> 8; - *((uint8_t*)o_buffer+1) = (i_i2cInfo.offset & 0x00FFull); + memset( io_buffer, 0x0, o_bufSize ); + *((uint8_t*)io_buffer) = (i_i2cInfo.offset & 0xFF00ull) >> 8; + *((uint8_t*)io_buffer+1) = (i_i2cInfo.offset & 0x00FFull); break; case ONE_BYTE_ADDR: o_bufSize = 1; - memset( o_buffer, 0x0, o_bufSize ); - *((uint8_t*)o_buffer) = (i_i2cInfo.offset & 0xFFull); + memset( io_buffer, 0x0, o_bufSize ); + *((uint8_t*)io_buffer) = (i_i2cInfo.offset & 0xFFull); + break; + + case ZERO_BYTE_ADDR: + o_bufSize = 0; + // nothing to do with the buffer in this case break; default: TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromPrepareAddress() - Invalid device type: %08x", - i_i2cInfo.deviceType ); + ERR_MRK"eepromPrepareAddress() - Invalid Device " + "Address Size: 0x%08x", i_i2cInfo.addrSize); /*@ * @errortype * @reasoncode EEPROM_INVALID_DEVICE_TYPE * @severity ERRL_SEV_UNRECOVERABLE * @moduleid EEPROM_PREPAREADDRESS - * @userdata1 Device Type + * @userdata1 Address Size (aka Device Type) * @userdata2 EEPROM chip - * @devdesc The Device type was not recognized as one supported. + * @devdesc The Device type not supported (addrSize) */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, EEPROM_PREPAREADDRESS, EEPROM_INVALID_DEVICE_TYPE, - i_i2cInfo.deviceType, - i_i2cInfo.chip ); - + i_i2cInfo.addrSize, + i_i2cInfo.chip); break; - }; - - if( err ) - { - break; } + } while( 0 ); TRACDCOMP( g_trac_eeprom, @@ -553,227 +588,174 @@ errlHndl_t eepromReadAttributes ( TARGETING::Target * i_target, eeprom_addr_t & o_i2cInfo ) { errlHndl_t err = NULL; + bool fail_reading_attribute = false; TRACDCOMP( g_trac_eeprom, ENTER_MRK"eepromReadAttributes()" ); + // These variables will be used to hold the EEPROM attribute data + // Note: each 'EepromVpd' struct is kept the same via the attributes + // so will be copying each to eepromData to save code space + TARGETING::EepromVpdPrimaryInfo eepromData; + do { - if( VPD_PRIMARY == o_i2cInfo.chip ) + + switch (o_i2cInfo.chip ) { - // Read Attributes from EEPROM_VPD_PRIMARY_INFO - TARGETING::EepromVpdPrimaryInfo eepromData; - if( i_target->tryGetAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO> - ( eepromData ) ) - { - o_i2cInfo.chipTypeEnum = VPD_PRIMARY; - o_i2cInfo.port = eepromData.port; - o_i2cInfo.devAddr = eepromData.devAddr; - o_i2cInfo.engine = eepromData.engine; - o_i2cInfo.i2cMasterPath = eepromData.i2cMasterPath; + case VPD_PRIMARY: + if( !( i_target-> + tryGetAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO> + ( eepromData ) ) ) + + { + fail_reading_attribute = true; + } + break; - // @todo RTC:72715 - More attributes to be read - o_i2cInfo.deviceType = TWO_BYTE_ADDR; - o_i2cInfo.writePageSize = 128; + case VPD_BACKUP: - } - else - { - TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromReadAttributes() - ERROR reading " - "attributes for chip %d! (VPD_PRIMARY)", - o_i2cInfo.chip ); + if( !(i_target-> + tryGetAttr<TARGETING::ATTR_EEPROM_VPD_BACKUP_INFO> + ( reinterpret_cast< + TARGETING::ATTR_EEPROM_VPD_BACKUP_INFO_type&> + ( eepromData) ) ) ) + { + fail_reading_attribute = true; + } + break; - /*@ - * @errortype - * @reasoncode EEPROM_VPD_PRIMARY_INFO_NOT_FOUND - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE - * @moduleid EEPROM_READATTRIBUTES - * @userdata1 HUID of target - * @userdata2[0:31] EEPROM chip - * @userdata2[32:63] Attribute Enumeration - * @devdesc ATTR_EEPROM_VPD_PRIMARY_INFO Attribute - * was not found - */ - err = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EEPROM_READATTRIBUTES, - EEPROM_VPD_PRIMARY_INFO_NOT_FOUND, - TARGETING::get_huid(i_target), - TWO_UINT32_TO_UINT64( - o_i2cInfo.chip, - TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO)); + case SBE_PRIMARY: + if( !(i_target-> + tryGetAttr<TARGETING::ATTR_EEPROM_SBE_PRIMARY_INFO> + ( reinterpret_cast< + TARGETING::ATTR_EEPROM_SBE_PRIMARY_INFO_type&> + ( eepromData) ) ) ) + { + fail_reading_attribute = true; + } + break; + + case SBE_BACKUP: + if( (!i_target-> + tryGetAttr<TARGETING::ATTR_EEPROM_SBE_BACKUP_INFO> + ( reinterpret_cast< + TARGETING::ATTR_EEPROM_SBE_BACKUP_INFO_type&> + ( eepromData) ) ) ) + { + fail_reading_attribute = true; + } break; - } - } - else if( VPD_BACKUP == o_i2cInfo.chip ) - { - // Read Attributes from EEPROM_VPD_BACKUP_INFO - TARGETING::EepromVpdBackupInfo eepromData; - if( i_target->tryGetAttr<TARGETING::ATTR_EEPROM_VPD_BACKUP_INFO> - ( eepromData ) ) - { - o_i2cInfo.chipTypeEnum = VPD_BACKUP; - o_i2cInfo.port = eepromData.port; - o_i2cInfo.devAddr = eepromData.devAddr; - o_i2cInfo.engine = eepromData.engine; - o_i2cInfo.i2cMasterPath = eepromData.i2cMasterPath; - - // @todo RTC:72715 - More attributes to be read - o_i2cInfo.deviceType = TWO_BYTE_ADDR; - o_i2cInfo.writePageSize = 128; - } - else - { - TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromReadAttributes() - ERROR reading " - "attributes for chip %d! (VPD_BACKUP)", - o_i2cInfo.chip ); + + default: + TRACFCOMP( g_trac_eeprom,ERR_MRK"eepromReadAttributes() - " + "Invalid chip (%d) to read attributes from!", + o_i2cInfo.chip ); /*@ * @errortype - * @reasoncode EEPROM_VPD_BACKUP_INFO_NOT_FOUND + * @reasoncode EEPROM_INVALID_CHIP * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid EEPROM_READATTRIBUTES - * @userdata1 HUID of target - * @userdata2[0:31] EEPROM chip - * @userdata2[32:63] Attribute Enumeration - * @devdesc ATTR_EEPROM_VPD_BACKUP_INFO Attribute - * was not found + * @userdata1 EEPROM Chip + * @userdata2 HUID of target + * @devdesc Invalid EEPROM chip to access */ - err = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EEPROM_READATTRIBUTES, - EEPROM_VPD_BACKUP_INFO_NOT_FOUND, - TARGETING::get_huid(i_target), - TWO_UINT32_TO_UINT64( - o_i2cInfo.chip, - TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO)); + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + EEPROM_READATTRIBUTES, + EEPROM_INVALID_CHIP, + o_i2cInfo.chip, + TARGETING::get_huid(i_target) ); break; - } } - else if( SBE_PRIMARY == o_i2cInfo.chip ) + + // Check if Attribute Data was found + if( fail_reading_attribute == true ) { - // Read Attributes from EEPROM_SBE_PRIMARY_INFO - TARGETING::EepromSbePrimaryInfo eepromData; - if( i_target->tryGetAttr<TARGETING::ATTR_EEPROM_SBE_PRIMARY_INFO> - ( eepromData ) ) - { - o_i2cInfo.chipTypeEnum = SBE_PRIMARY; - o_i2cInfo.port = eepromData.port; - o_i2cInfo.devAddr = eepromData.devAddr; - o_i2cInfo.engine = eepromData.engine; - o_i2cInfo.i2cMasterPath = eepromData.i2cMasterPath; - - // @todo RTC:72715 - More attributes to be read - o_i2cInfo.deviceType = TWO_BYTE_ADDR; - o_i2cInfo.writePageSize = 128; - } - else - { - TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromReadAttributes() - ERROR reading " - "attributes for chip %d! (SBE_PRIMARY)", - o_i2cInfo.chip ); + TRACFCOMP( g_trac_eeprom, + ERR_MRK"eepromReadAttributes() - ERROR reading " + "attributes for chip %d!", + o_i2cInfo.chip ); /*@ * @errortype - * @reasoncode EEPROM_SBE_PRIMARY_INFO_NOT_FOUND + * @reasoncode EEPROM_ATTR_INFO_NOT_FOUND * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid EEPROM_READATTRIBUTES * @userdata1 HUID of target - * @userdata2[0:31] EEPROM chip - * @userdata2[32:63] Attribute Enumeration - * @devdesc ATTR_EEPROM_SBE_PRIMARY_INFO Attribute - * was not found + * @userdata2 EEPROM chip + * @devdesc EEPROM Attribute was not found */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, EEPROM_READATTRIBUTES, - EEPROM_SBE_PRIMARY_INFO_NOT_FOUND, + EEPROM_ATTR_INFO_NOT_FOUND, TARGETING::get_huid(i_target), - TWO_UINT32_TO_UINT64( - o_i2cInfo.chip, - TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO)); + o_i2cInfo.chip); break; - } + + } + + // Successful reading of Attribute, so extract the data + o_i2cInfo.port = eepromData.port; + o_i2cInfo.devAddr = eepromData.devAddr; + o_i2cInfo.engine = eepromData.engine; + o_i2cInfo.i2cMasterPath = eepromData.i2cMasterPath; + o_i2cInfo.writePageSize = eepromData.writePageSize; + o_i2cInfo.devSize_KB = eepromData.maxMemorySizeKB; + + // Convert attribute info to eeprom_addr_size_t enum + if ( eepromData.byteAddrOffset == 0x2 ) + { + o_i2cInfo.addrSize = TWO_BYTE_ADDR; } - else if( SBE_BACKUP == o_i2cInfo.chip ) + else if ( eepromData.byteAddrOffset == 0x1 ) { - // Read Attributes from EEPROM_SBE_BACKUP_INFO - TARGETING::EepromSbeBackupInfo eepromData; - if( i_target->tryGetAttr<TARGETING::ATTR_EEPROM_SBE_BACKUP_INFO> - ( eepromData ) ) - { - o_i2cInfo.chipTypeEnum = SBE_BACKUP; - o_i2cInfo.port = eepromData.port; - o_i2cInfo.devAddr = eepromData.devAddr; - o_i2cInfo.engine = eepromData.engine; - o_i2cInfo.i2cMasterPath = eepromData.i2cMasterPath; - - // @todo RTC:72715 - More attributes to be read - o_i2cInfo.deviceType = TWO_BYTE_ADDR; - o_i2cInfo.writePageSize = 128; - } - else - { - TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromReadAttributes() - ERROR reading " - "attributes for chip %d! (SBE_BACKUP)", - o_i2cInfo.chip ); + o_i2cInfo.addrSize = ONE_BYTE_ADDR; + } + else if ( eepromData.byteAddrOffset == 0x0 ) + { + o_i2cInfo.addrSize = ZERO_BYTE_ADDR; + } + else + { + TRACFCOMP( g_trac_eeprom, + ERR_MRK"eepromReadAttributes() - INVALID ADDRESS " + "OFFSET SIZE %d!", + o_i2cInfo.addrSize ); /*@ * @errortype - * @reasoncode EEPROM_SBE_BACKUP_INFO_NOT_FOUND + * @reasoncode EEPROM_INVALID_ADDR_OFFSET_SIZE * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid EEPROM_READATTRIBUTES * @userdata1 HUID of target - * @userdata2[0:31] EEPROM chip - * @userdata2[32:63] Attribute Enumeration - * @devdesc ATTR_EEPROM_SBE_BACKUP_INFO Attribute - * was not found + * @userdata2 Address Offset Size + * @devdesc Invalid Address Offset Size */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, EEPROM_READATTRIBUTES, - EEPROM_SBE_BACKUP_INFO_NOT_FOUND, + EEPROM_INVALID_ADDR_OFFSET_SIZE, TARGETING::get_huid(i_target), - TWO_UINT32_TO_UINT64( - o_i2cInfo.chip, - TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO)); + o_i2cInfo.addrSize); break; - } - } - else - { - TRACFCOMP( g_trac_eeprom, - ERR_MRK"eepromReadAttributes() - Invalid chip (%d) to read " - "attributes from!", - o_i2cInfo.chip ); - - /*@ - * @errortype - * @reasoncode EEPROM_INVALID_CHIP - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE - * @moduleid EEPROM_READATTRIBUTES - * @userdata1 EEPROM Chip - * @userdata2 HUID of target - * @devdesc Invalid EEPROM chip to access - */ - err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - EEPROM_READATTRIBUTES, - EEPROM_INVALID_CHIP, - o_i2cInfo.chip, - TARGETING::get_huid(i_target) ); - break; } + } while( 0 ); + TRACUCOMP(g_trac_eeprom,"eepromReadAttributes() %d/%d/0x%X " + "wpw=0x%X, dsKb=0x%X, aS=%d (%d)", + o_i2cInfo.port, o_i2cInfo.engine, o_i2cInfo.devAddr, + o_i2cInfo.writePageSize, o_i2cInfo.devSize_KB, + o_i2cInfo.addrSize, eepromData.byteAddrOffset); + + TRACDCOMP( g_trac_eeprom, EXIT_MRK"eepromReadAttributes()" ); @@ -831,7 +813,7 @@ errlHndl_t eepromGetI2CMasterTarget ( TARGETING::Target * i_target, ERRORLOG::ERRL_SEV_UNRECOVERABLE, EEPROM_GETI2CMASTERTARGET, EEPROM_DIMM_I2C_MASTER_PATH_ERROR, - i_i2cInfo.chipTypeEnum, + i_i2cInfo.chip, TARGETING::get_huid(i_target) ); break; @@ -858,7 +840,7 @@ errlHndl_t eepromGetI2CMasterTarget ( TARGETING::Target * i_target, err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, EEPROM_GETI2CMASTERTARGET, EEPROM_TARGET_NULL, - i_i2cInfo.chipTypeEnum, + i_i2cInfo.chip, TARGETING::get_huid(i_target) ); break; diff --git a/src/usr/i2c/eepromdd.H b/src/usr/i2c/eepromdd.H index 7464e1881..d30862b62 100755 --- a/src/usr/i2c/eepromdd.H +++ b/src/usr/i2c/eepromdd.H @@ -44,10 +44,11 @@ namespace EEPROM */ typedef enum { - TWO_BYTE_ADDR, - ONE_BYTE_ADDR, + ZERO_BYTE_ADDR = 0, + ONE_BYTE_ADDR = 1, + TWO_BYTE_ADDR = 2, LAST_DEVICE_TYPE -} eeprom_device_t; +} eeprom_addr_size_t; /** * @brief Structure of common parameters needed by different parts of @@ -60,10 +61,10 @@ typedef struct uint64_t devAddr; int64_t chip; uint64_t offset; - eeprom_device_t deviceType; + eeprom_addr_size_t addrSize; TARGETING::EntityPath i2cMasterPath; uint64_t writePageSize; // in bytes - eeprom_chip_types_t chipTypeEnum; + uint64_t devSize_KB; // in kilobytes } eeprom_addr_t; /** @@ -156,8 +157,8 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, * existing buffer (for Writes), or as a separate write operation * (for Reads). * - * @param[out] o_buffer - The buffer to be written as a byte address to - * the EEPROM device. + * @param[in/out] io_buffer - The buffer to be written as a byte address to + * the EEPROM device. Must be pre-allocated to MAX_BYTE_ADDR size. * * @param[out] o_bufSize - The size of the buffer to be written. * @@ -167,7 +168,7 @@ errlHndl_t eepromWrite ( TARGETING::Target * i_target, * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ -errlHndl_t eepromPrepareAddress ( void * o_buffer, +errlHndl_t eepromPrepareAddress ( void * io_buffer, size_t & o_bufSize, eeprom_addr_t i_i2cInfo ); diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 66d39bc6e..19403c9b4 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -36,6 +36,7 @@ #include <trace/interface.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> +#include <errl/errludtarget.H> #include <targeting/common/targetservice.H> #include <devicefw/driverif.H> #include <targeting/common/predicates/predicates.H> @@ -97,12 +98,14 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, va_list i_args ) { errlHndl_t err = NULL; - bool l_withStop = false; - bool l_skipModeSetup = false; + + mutex_t * engineLock = NULL; + bool mutex_needs_unlock = false; // Get the input args our of the va_list // Address, Port, Engine, Device Addr. - input_args_t args; + // Other args set below + misc_args_t args; args.port = va_arg( i_args, uint64_t ); args.engine = va_arg( i_args, uint64_t ); args.devAddr = va_arg( i_args, uint64_t ); @@ -132,6 +135,7 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, (uint64_t) i_opType, i_accessType, args.port, args.engine, args.devAddr, io_buflen, l_offset_length, l_offset_buffer); + do { // Check for Master Sentinel chip @@ -160,10 +164,8 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, break; } - // @todo RTC:72715 - Check that target is an I2C master // Get the mutex for the requested engine - mutex_t * engineLock = NULL; switch( args.engine ) { case 0: @@ -191,10 +193,21 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, INFO_MRK"Obtaining lock for engine: %d", args.engine ); (void)mutex_lock( engineLock ); + mutex_needs_unlock = true; TRACUCOMP( g_trac_i2c, INFO_MRK"Locked on engine: %d", args.engine ); + + // Calculate variables related to I2C Bus Speed in 'args' struct + err = i2cSetBusVariables( i_target, READ_I2C_BUS_ATTRIBUTES, args); + + if( err ) + { + break; + } + + for( int attempt = 0; attempt < I2C_COMMAND_ATTEMPTS; attempt++ ) { if( err ) @@ -227,25 +240,30 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, { // First WRITE offset to device without a stop - l_withStop = false; + args.read_not_write = false; + args.with_stop = false; + args.skip_mode_setup = false; err = i2cWrite( i_target, l_offset_buffer, l_offset_length, - l_withStop, args ); - - - // Now do the READ with a stop (reads always have 'stop') - // Skip mode setup on this cmd - already set with previous cmd - l_skipModeSetup = true; - - err = i2cRead( i_target, - io_buffer, - io_buflen, - l_skipModeSetup, - args ); + if( err == NULL ) + { + // Now do the READ with a stop + args.read_not_write = true; + args.with_stop = true; + + // Skip mode setup on this cmd - + // already set with previous cmd + args.skip_mode_setup = true; + + err = i2cRead( i_target, + io_buffer, + io_buflen, + args ); + } } else if( i_opType == DeviceFW::WRITE && @@ -264,14 +282,14 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, // Now add the data the user wanted to write memcpy( &newBuffer[l_offset_length], io_buffer, io_buflen); - // Other parms: - l_withStop = true; - l_skipModeSetup = false; + // Write parms: + args.read_not_write = false; + args.with_stop = true; + args.skip_mode_setup = false; err = i2cWrite( i_target, newBuffer, newBufLen, - l_withStop, args ); @@ -283,13 +301,14 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, l_offset_length == 0 ) { // Do a direct READ - l_skipModeSetup = false; + args.read_not_write = true; + args.with_stop = true; + args.skip_mode_setup = false; err = i2cRead( i_target, io_buffer, io_buflen, - l_skipModeSetup, - args ); + args); } @@ -297,12 +316,14 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, l_offset_length == 0 ) { // Do a direct WRITE with a stop - l_withStop = true; + args.read_not_write = false; + args.with_stop = true; + args.skip_mode_setup = false; + err = i2cWrite( i_target, io_buffer, io_buflen, - l_withStop, - args ); + args); } else { @@ -342,17 +363,27 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, } } + if( err ) + { + break; + } + } while( 0 ); + + // Check if we need to unlock the mutex + if ( mutex_needs_unlock == true ) + { // Unlock (void) mutex_unlock( engineLock ); TRACUCOMP( g_trac_i2c, INFO_MRK"Unlocked engine: %d", args.engine ); + } - if( err ) - { - break; - } - } while( 0 ); + // If there is an error, add target to log + if ( (err != NULL) && (i_target != NULL) ) + { + ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(err); + } TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cPerformOp() - %s", @@ -367,40 +398,35 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, errlHndl_t i2cRead ( TARGETING::Target * i_target, void * o_buffer, size_t & i_buflen, - bool & i_skipModeSetup, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; - size_t size = sizeof(uint64_t); uint64_t bytesRead = 0x0; + size_t size = sizeof(uint64_t); - uint64_t engine = i_args.engine; - uint64_t devAddr = i_args.devAddr; - uint64_t port = i_args.port; - // @todo RTC:72715 - Add multiple bus speed support (set to 400KHz for now) - uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ ); - uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval ); + // Use Local Variables (timeoutCount gets derecmented) + uint64_t interval = i_args.timeout_interval; + uint64_t timeoutCount = i_args.timeout_count; // Define the regs we'll be using - statusreg status; - fiforeg fifo; + status_reg_t status; + fifo_reg_t fifo; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cRead()" ); TRACSCOMP( g_trac_i2cr, "I2C READ START : engine %.2X : port %.2X : devAddr %.2X : len %d", - engine, port, devAddr, i_buflen ); + i_args.engine, i_args.port, i_args.devAddr, i_buflen ); do { // Do Command/Mode reg setups. + i_args.read_not_write = true; + err = i2cSetup( i_target, i_buflen, - true, // i_readNotWrite - true, // i_withStop - i_skipModeSetup, i_args ); if( err ) @@ -455,8 +481,8 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, ERR_MRK"i2cRead() - Timed out waiting for data in FIFO!" ); uint64_t userdata2 = i_args.port; - userdata2 = (userdata2 << 16) | engine; - userdata2 = (userdata2 << 16) | devAddr; + userdata2 = (userdata2 << 16) | i_args.engine; + userdata2 = (userdata2 << 16) | i_args.devAddr; /*@ * @errortype @@ -464,8 +490,7 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, * @severity ERRL_SEV_UNRECOVERABLE * @moduleid I2C_READ * @userdata1 Status Register Value - * @userdata2[0:15] <UNUSED> - * @userdata2[16:31] Master Port + * @userdata2[0:31] Master Port * @userdata2[32:47] Master Engine * @userdata2[48:63] Slave Device Address * @devdesc Timed out waiting for data in FIFO to read @@ -490,11 +515,12 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, err = deviceRead( i_target, &fifo.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].fifo ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].fifo ) ); TRACUCOMP( g_trac_i2c, INFO_MRK"i2cRead() - FIFO[0x%lx] = 0x%016llx", - masterAddrs[engine].fifo, fifo.value); + masterAddrs[i_args.engine].fifo, fifo.value); if( err ) { @@ -509,7 +535,7 @@ 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)", - engine, port, devAddr, bytesRead, + i_args.engine, i_args.port, i_args.devAddr, bytesRead, fifo.byte_0, fifo.value ); } @@ -530,7 +556,7 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, TRACSCOMP( g_trac_i2cr, "I2C READ END : engine %.2X : port %.2x : devAddr %.2X : len %d", - engine, port, devAddr, i_buflen ); + i_args.engine, i_args.port, i_args.devAddr, i_buflen ); TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cRead()" ); @@ -544,36 +570,30 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, errlHndl_t i2cWrite ( TARGETING::Target * i_target, void * i_buffer, size_t & io_buflen, - bool & i_withStop, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; - size_t size = sizeof(uint64_t); uint64_t bytesWritten = 0x0; - - uint64_t engine = i_args.engine; - uint64_t devAddr = i_args.devAddr; - uint64_t port = i_args.port; + size_t size = sizeof(uint64_t); // Define regs we'll be using - fiforeg fifo; + fifo_reg_t fifo; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cWrite()" ); TRACSCOMP( g_trac_i2cr, "I2C WRITE START : engine %.2X : port %.2X : devAddr %.2X : len %d", - engine, port, devAddr, io_buflen ); + i_args.engine, i_args.port, i_args.devAddr, io_buflen ); do { // Do Command/Mode reg setups + i_args.read_not_write = false; + err = i2cSetup( i_target, io_buflen, - false, // i_readNotWrite - i_withStop, - false, // i_skipModeSetup, - i_args ); + i_args); if( err ) { @@ -598,7 +618,8 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, err = deviceWrite( i_target, &fifo.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].fifo ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].fifo ) ); if( err ) { @@ -608,8 +629,8 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, TRACUCOMP( g_trac_i2cr, "I2C WRITE DATA : engine %.2X : port %.2X : " "devAddr %.2X : byte %d : %.2X (0x%lx)", - engine, port, devAddr, bytesWritten, - fifo.byte_0, fifo.value ); + i_args.engine, i_args.port, i_args.devAddr, + bytesWritten, fifo.byte_0, fifo.value ); } if( err ) @@ -632,7 +653,7 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, TRACSCOMP( g_trac_i2cr, "I2C WRITE END : engine %.2X: port %.2X : devAddr %.2X : len %d", - engine, port, devAddr, io_buflen ); + i_args.engine, i_args.port, i_args.devAddr, io_buflen ); TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cWrite()" ); @@ -645,25 +666,19 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, // ------------------------------------------------------------------ errlHndl_t i2cSetup ( TARGETING::Target * i_target, size_t & i_buflen, - bool i_readNotWrite, - bool i_withStop, - bool i_skipModeSetup, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; size_t size = sizeof(uint64_t); - uint64_t port = i_args.port; - uint64_t engine = i_args.engine; - uint64_t devAddr = i_args.devAddr; - TRACDCOMP( g_trac_i2c, - ENTER_MRK"i2cSetup(): buf_len=%d, r_nw=%d, w_stop=%d", - i_buflen, i_readNotWrite, i_withStop ); + 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); // Define the registers that we'll use - modereg mode; - cmdreg cmd; + mode_reg_t mode; + command_reg_t cmd; do { @@ -680,25 +695,24 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, // Skip mode setup on 2nd of 2 cmd strung together - like when sending // device offset first before read or write - if ( i_skipModeSetup == false) + if ( i_args.skip_mode_setup == false) { // Write Mode Register: - // - bit rate divisor + // - bit rate divisor (set in i2cSetClockVariables() ) // - port number + mode.value = 0x0ull; + mode.bit_rate_div = i_args.bit_rate_divisor; + mode.port_num = i_args.port; - // @todo RTC:72715 - Add multiple bus speed support - // Hard code to 400KHz until we get attributes in place to get - // this from the target. - mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ; - mode.port_num = port; TRACUCOMP( g_trac_i2c,"i2cSetup(): set mode = 0x%lx", mode.value); err = deviceWrite( i_target, &mode.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].mode)); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].mode)); if( err ) { @@ -714,7 +728,7 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, // - length cmd.value = 0x0ull; cmd.with_start = 1; - cmd.with_stop = (i_withStop ? 1 : 0); + cmd.with_stop = (i_args.with_stop ? 1 : 0); cmd.with_addr = 1; // cmd.device_addr is 7 bits @@ -722,9 +736,9 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, // -- value stored in LSB byte of uint64_t // -- LS-bit is unused, creating the 7 bit cmd.device_addr // So will be masking for LSB, and then shifting to push off LS-bit - cmd.device_addr = (0x000000FF & devAddr) >> 1; + cmd.device_addr = (0x000000FF & i_args.devAddr) >> 1; - cmd.read_not_write = (i_readNotWrite ? 1 : 0); + cmd.read_not_write = (i_args.read_not_write ? 1 : 0); cmd.length_b = i_buflen; TRACUCOMP( g_trac_i2c,"i2cSetup(): set cmd = 0x%lx", cmd.value); @@ -732,7 +746,8 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, err = deviceWrite( i_target, &cmd.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].command ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].command ) ); if( err ) { @@ -750,7 +765,7 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, // i2cWaitForCmdComp // ------------------------------------------------------------------ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; uint64_t engine = i_args.engine; @@ -759,11 +774,11 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, ENTER_MRK"i2cWaitForCmdComp()" ); // Define the registers that we'll use - statusreg status; + status_reg_t status; - // @todo RTC:72715 - Add multiple bus speed support (set to 400KHz for now) - uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ ); - uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval ); + // Use Local Variables (timeoutCount gets derecmented) + uint64_t interval = i_args.timeout_interval; + uint64_t timeoutCount = i_args.timeout_count; TRACUCOMP(g_trac_i2c, "i2cWaitForCmdComp(): timeoutCount=%d, interval=%d", timeoutCount, interval); @@ -824,12 +839,11 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, // i2cReadStatusReg // ------------------------------------------------------------------ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, - input_args_t i_args, - statusreg & o_statusReg ) + misc_args_t & i_args, + status_reg_t & o_statusReg ) { errlHndl_t err = NULL; size_t size = sizeof(uint64_t); - uint64_t engine = i_args.engine; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cReadStatusReg()" ); @@ -840,7 +854,8 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, err = deviceRead( i_target, &o_statusReg.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].status ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].status ) ); if( err ) { @@ -849,7 +864,7 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, TRACUCOMP(g_trac_i2c,"i2cReadStatusReg(): " INFO_MRK"status[0x%lx]: 0x%016llx", - masterAddrs[engine].status, o_statusReg.value ); + masterAddrs[i_args.engine].status, o_statusReg.value ); // Check for Errors @@ -875,8 +890,8 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, // i2cCheckForErrors // ------------------------------------------------------------------ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, - input_args_t i_args, - statusreg i_statusVal ) + misc_args_t & i_args, + status_reg_t i_statusVal ) { errlHndl_t err = NULL; bool errorFound = false; @@ -1003,16 +1018,16 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, // i2cWaitForFifoSpace // ------------------------------------------------------------------ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, - input_args_t i_args ) + misc_args_t & i_args ) { errlHndl_t err = NULL; - // @todo RTC:72715 - support multiple bus speeds (set to 400KHz for now) - uint64_t interval = I2C_TIMEOUT_INTERVAL( I2C_CLOCK_DIVISOR_400KHZ ); - uint64_t timeoutCount = I2C_TIMEOUT_COUNT( interval ); + // Use Local Variables (timeoutCount gets derecmented) + uint64_t interval = i_args.timeout_interval; + uint64_t timeoutCount = i_args.timeout_count; // Define regs we'll be using - statusreg status; + status_reg_t status; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cWaitForFifoSpace()" ); @@ -1096,19 +1111,18 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, // i2cReset // ------------------------------------------------------------------ errlHndl_t i2cReset ( TARGETING::Target * i_target, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; size_t size = sizeof(uint64_t); // Get Args - uint64_t engine = i_args.engine; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cReset()" ); // Writing to the Status Register does a full I2C reset. - statusreg reset; + status_reg_t reset; do { @@ -1116,12 +1130,13 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target, TRACUCOMP(g_trac_i2c,"i2cReset() " "reset[0x%lx]: 0x%016llx", - masterAddrs[engine].reset, reset.value ); + masterAddrs[i_args.engine].reset, reset.value ); err = deviceWrite( i_target, &reset.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].reset ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].reset ) ); if( err ) { @@ -1152,16 +1167,14 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target, // i2cSendSlaveStop // ------------------------------------------------------------------ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, - input_args_t i_args ) + misc_args_t & i_args) { errlHndl_t err = NULL; size_t size = sizeof(uint64_t); - uint64_t engine = i_args.engine; - uint64_t port = i_args.port; // Master Registers - modereg mode; - cmdreg cmd; + mode_reg_t mode; + command_reg_t cmd; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cSendSlaveStop()" ); @@ -1170,11 +1183,8 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, { mode.value = 0x0ull; - // @todo RTC:72715 - support multiple bus speeds - // Hard code to 400KHz until we get attributes in place to get - // this from the target. - mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ; - mode.port_num = port; + mode.bit_rate_div = i_args.bit_rate_divisor; + mode.port_num = i_args.port; mode.enhanced_mode = 1; TRACUCOMP(g_trac_i2c,"i2cSendSlaveStop(): " @@ -1184,7 +1194,8 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, err = deviceWrite( i_target, &mode.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].mode ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].mode ) ); if( err ) { @@ -1201,7 +1212,8 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, err = deviceWrite( i_target, &cmd.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].command ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].command ) ); if( err ) { @@ -1229,15 +1241,14 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, // i2cGetInterrupts // ------------------------------------------------------------------ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, - input_args_t i_args, + misc_args_t & i_args, uint64_t & o_intRegValue ) { errlHndl_t err = NULL; size_t size = sizeof(uint64_t); - uint64_t engine = i_args.engine; // Master Regs - interruptreg intreg; + interrupt_reg_t intreg; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cGetInterrupts()" ); @@ -1248,7 +1259,8 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, err = deviceRead( i_target, &intreg.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].interrupt ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[i_args.engine].interrupt ) ); if( err ) { @@ -1277,10 +1289,12 @@ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, errlHndl_t i2cSetupMasters ( void ) { errlHndl_t err = NULL; - - modereg mode; size_t size = sizeof(uint64_t); + misc_args_t io_args; + + mode_reg_t mode; + TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cSetupMasters()" ); @@ -1346,14 +1360,32 @@ errlHndl_t i2cSetupMasters ( void ) // Write Mode Register: mode.value = 0x0ull; - // @todo RTC:72715 - support multiple bus speeds - // Hard code to 400KHz until we get attributes in place - // to get this from the target. - mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ; + // Hardcode to 400KHz for PHYP + err = i2cSetBusVariables ( centList[centaur], + SET_I2C_BUS_400KHZ, + io_args ); + + if( err ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK"i2cSetupMasters: Error Setting Bus " + "Speed Variables-Centaur, engine: %d", + engine ); + + // If we get error skip setting this target, but still need + // to continue to program the I2C Bus Divisor for the rest + errlCommit( err, + I2C_COMP_ID ); + continue; + } + + mode.bit_rate_div = io_args.bit_rate_divisor; + err = deviceWrite( centList[centaur], &mode.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].mode ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[engine].mode)); if( err ) { @@ -1434,14 +1466,33 @@ errlHndl_t i2cSetupMasters ( void ) // Write Mode Register: mode.value = 0x0ull; - // @todo RTC:72715 - support multiple bus speeds - // Hard code to 400KHz until we get attributes in place - // to get this from the target. - mode.bit_rate_div = I2C_CLOCK_DIVISOR_400KHZ; + // Hardcode to 400KHz for PHYP + err = i2cSetBusVariables ( procList[proc], + SET_I2C_BUS_400KHZ, + io_args ); + + if( err ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK"i2cSetupMasters: Error Setting Bus " + "Speed Variables-Processor, engine: %d", + engine ); + + // If we get error skip setting this target, but still need + // to continue to program the I2C Bus Divisor for the rest + errlCommit( err, + I2C_COMP_ID ); + + continue; + } + + mode.bit_rate_div = io_args.bit_rate_divisor; + err = deviceWrite( procList[proc], &mode.value, size, - DEVICE_SCOM_ADDRESS( masterAddrs[engine].mode ) ); + DEVICE_SCOM_ADDRESS( + masterAddrs[engine].mode)); if( err ) { @@ -1476,4 +1527,85 @@ errlHndl_t i2cSetupMasters ( void ) } + +// ------------------------------------------------------------------ +// i2cSetClockVariables +// ------------------------------------------------------------------ +errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target, + i2c_bus_setting_mode_t i_mode, + misc_args_t & io_args) +{ + errlHndl_t err = NULL; + + TRACDCOMP( g_trac_i2c, + ENTER_MRK"i2cSetBusVariables()" ); + + do + { + + // @todo RTC:80614 - Read I2C bus speed attributes from I2C Master + // For now, hardcode to 400KHz + i_mode = SET_I2C_BUS_400KHZ; + + if (i_mode == SET_I2C_BUS_400KHZ) + { + + io_args.bus_speed = 400; + io_args.bit_rate_divisor = I2C_CLOCK_DIVISOR_400KHZ; + io_args.timeout_interval = I2C_TIMEOUT_INTERVAL( + I2C_CLOCK_DIVISOR_400KHZ); + io_args.timeout_count = I2C_TIMEOUT_COUNT( + io_args.timeout_interval); + + + } + + /* @todo RTC:80614 - sync up reading attributes with MRW + else if (i_mode == READ_I2C_BUS_ATTRIBUTES) + { + + } + */ + + else + { + TRACFCOMP( g_trac_i2c, ERR_MRK"i2cSetBusVariables: " + "Invalid Bus Speed Mode Input!" ); + + /*@ + * @errortype + * @reasoncode I2C_INVALID_BUS_SPEED_MODE + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid I2C_SET_BUS_VARIABLES + * @userdata1 I2C Bus Setting Mode Enum + * @userdata2 <UNUSED> + * @frucallout <NONE> + * @devdesc Invalid I2C bus speed mode input + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + I2C_SET_BUS_VARIABLES, + I2C_INVALID_BUS_SPEED_MODE, + i_mode, + 0x0 ); + break; + + } + + + } while( 0 ); + + + TRACUCOMP(g_trac_i2c,"i2cSetBusVariables(): e/p/dA=%d/%d/0x%x: " + "mode=%d: b_sp=%d, b_r_d=0x%x, to_i=%d, to_c = %d", + io_args.engine, io_args.port, io_args.devAddr, + i_mode, io_args.bus_speed, io_args.bit_rate_divisor, + io_args.timeout_interval, io_args.timeout_count); + + TRACDCOMP( g_trac_i2c, + EXIT_MRK"i2cSetBusVariables()" ); + + return err; +} + + } // end namespace I2C diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H index d1b3b2afd..e864df093 100755 --- a/src/usr/i2c/i2c.H +++ b/src/usr/i2c/i2c.H @@ -105,7 +105,7 @@ namespace I2C /** * @brief I2C Master register structure and address definition */ -typedef struct +struct i2c_addrs_t { uint64_t fifo; uint64_t command; @@ -114,9 +114,11 @@ typedef struct uint64_t interrupt; uint64_t status; uint64_t reset; -} i2c_addrs_t; +}; -// Addresses for each of the registers in each engine. +/** + * @brief Addresses for each of the registers in each engine. + */ static i2c_addrs_t masterAddrs[] = { { /* Master 0 */ @@ -148,6 +150,34 @@ static i2c_addrs_t masterAddrs[] = } }; +/** + * @brief Structure used to pass important variables between functions + */ +struct misc_args_t +{ + uint8_t port; + uint8_t engine; + uint64_t devAddr; + bool skip_mode_setup; + bool with_stop; + bool read_not_write; + uint64_t bus_speed; // in kbits/sec (ie 400KHz) + uint16_t bit_rate_divisor; // uint16_t to match size in mode register + uint64_t timeout_interval; + uint64_t timeout_count; +}; + +/** + * @brief Different ways of setting the I2C Bus Speed + */ +enum i2c_bus_setting_mode_t +{ + READ_I2C_BUS_ATTRIBUTES, + SET_I2C_BUS_400KHZ, + LAST_BUS_SETTING_MODE_TYPE +}; + + // ----------------------------------------------------------------------- // NOTE: Addressing listed below is from the PIB I2C Master Addressing @@ -159,7 +189,7 @@ static i2c_addrs_t masterAddrs[] = * @brief I2C FIFO register definition * Address 0x04 */ -union fiforeg +union fifo_reg_t { uint64_t value; struct @@ -167,13 +197,13 @@ union fiforeg uint64_t byte_0 : 8; uint64_t padding : 56; } PACKED; -} fifo_reg_t; +}; /** * @brief I2C Command register definition * Address 0x05 */ -union cmdreg +union command_reg_t { uint64_t value; struct @@ -188,13 +218,13 @@ union cmdreg uint64_t length_b : 16; uint64_t padding : 32; } PACKED; -} command_reg_t; +}; /** * @brief I2C Mode register definition * Address 0x06 */ -union modereg +union mode_reg_t { uint64_t value; struct @@ -208,13 +238,13 @@ union modereg uint64_t wrap_mode : 1; uint64_t padding : 32; } PACKED; -} mode_reg_t; +}; /** * @brief Watermark register definition * Address 0x07 */ -union watermarkreg +union watermark_reg_t { uint64_t value; struct @@ -226,13 +256,13 @@ union watermarkreg uint64_t reserved2 : 4; uint64_t padding : 32; } PACKED; -} watermark_reg_t; +}; /** * @brief Interrupt Mask register definition * Address 0x08 */ -union intmaskreg +union interrupt_mask_reg_t { uint64_t value; struct @@ -256,13 +286,13 @@ union intmaskreg uint64_t sda_eq_0 : 1; uint64_t padding : 32; } PACKED; -} interrupt_mask_reg_t; +}; /** * @brief Interrupt Condition register definition * Address 0x09 */ -union intcondreg +union interrupt_cond_reg_t { uint64_t value; struct @@ -286,13 +316,13 @@ union intcondreg uint64_t sda_eq_0 : 1; uint64_t padding : 32; } PACKED; -} interrupt_cond_reg_t; +}; /** * @brief Interrupt register definition * Address 0x0A */ -union interruptreg +union interrupt_reg_t { uint64_t value; struct @@ -316,13 +346,13 @@ union interruptreg uint64_t sda_eq_0 : 1; uint64_t padding: 32; } PACKED; -} interrupt_reg_t; +}; /** * @brief Status register definition * Address 0x0B */ -union statusreg +union status_reg_t { uint64_t value; struct @@ -347,13 +377,13 @@ union statusreg uint64_t fifo_entry_count : 8; uint64_t padding : 32; } PACKED; -} status_reg_t; +}; /** * @brief Extended Status register definition * Address 0x0C */ -union extstatusreg +union extended_status_reg_t { uint64_t value; struct @@ -375,13 +405,13 @@ union extstatusreg uint64_t i2c_version : 5; uint64_t padding : 32; } PACKED; -} extended_status_reg_t; +}; /** * @brief Residual Front/Back end length register definition * Address 0x0D */ -union residuallengthreg +union residual_length_reg_t { uint64_t value; struct @@ -390,14 +420,8 @@ union residuallengthreg uint64_t back_end_length : 16; uint64_t padding : 32; } PACKED; -} residual_length_reg_t; +}; -typedef struct -{ - uint64_t port; - uint64_t engine; - uint64_t devAddr; -} input_args_t; /** @@ -451,9 +475,6 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, * @param[in] i_buflen - The size of the data to read and place in the * buffer. * - * @param[in] i_skipModeSetup - true if mode register setup needs to be - * skipped - * * @param[in] i_args - Structure containing arguments needed for a command * transaction. * @@ -463,8 +484,7 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType, errlHndl_t i2cRead ( TARGETING::Target * i_target, void * o_buffer, size_t & i_buflen, - bool & i_skipModeSetup, - input_args_t i_args ); + misc_args_t & i_args); /** * @brief This function will do the real work of writinging to the I2C @@ -478,9 +498,6 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, * @param[in/out] io_buflen - INPUT: The size of the data to write to the * target device. OUTPUT: The size of the data buffer written. * - * @param[in] i_withStop - true if with_stop bit is to be set on operation; - * otherwise, with_stop bit will be set to zero. - * * @param[in] i_args - Structure containing arguments needed for a command * transaction. * @@ -491,8 +508,7 @@ errlHndl_t i2cRead ( TARGETING::Target * i_target, errlHndl_t i2cWrite ( TARGETING::Target * i_target, void * i_buffer, size_t & io_buflen, - bool & i_withStop, - input_args_t i_args ); + misc_args_t & i_args); /** * @brief This function will do the I2C setup of the Address/Command registers @@ -502,15 +518,6 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, * * @param[in] i_buflen - The size of the data that will be read/written. * - * @param[in] i_readNotWrite - true if doing a read operation, false if - * doing a write operation. - * - * @param[in] i_withStop - true if with_stop bit is to be set, otherwise - * with_stop will be set to zero. - * - * @param[in] i_skipModeSetup - true if mode register setup needs to be - * skipped - * * @param[in] i_args - Structure containing arguments needed for a command * transaction. * @@ -519,10 +526,7 @@ errlHndl_t i2cWrite ( TARGETING::Target * i_target, */ errlHndl_t i2cSetup ( TARGETING::Target * i_target, size_t & i_buflen, - bool i_readNotWrite, - bool i_withStop, - bool i_skipModeSetup, - input_args_t i_args ); + misc_args_t & i_args); /** * @brief This function will wait for the command to be complete or @@ -537,7 +541,7 @@ errlHndl_t i2cSetup ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, - input_args_t i_args ); + misc_args_t & i_args); /** * @brief This function will read the I2C Master engine status register @@ -554,8 +558,8 @@ errlHndl_t i2cWaitForCmdComp ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, - input_args_t i_args, - statusreg & o_statusReg ); + misc_args_t & i_args, + status_reg_t & o_statusReg ); /** * @brief This function will check for errors in the status register @@ -572,8 +576,8 @@ errlHndl_t i2cReadStatusReg ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, - input_args_t i_args, - statusreg i_statusVal ); + misc_args_t & i_args, + status_reg_t i_statusVal ); /** * @brief This function will read the status register and not return @@ -590,7 +594,7 @@ errlHndl_t i2cCheckForErrors ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, - input_args_t i_args ); + misc_args_t & i_args); /** * @brief This function will reset the I2C Master engine specified @@ -606,7 +610,7 @@ errlHndl_t i2cWaitForFifoSpace ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cReset ( TARGETING::Target * i_target, - input_args_t i_args ); + misc_args_t & i_args ); /** * @brief This function will send the Stop command to the slave device @@ -621,7 +625,7 @@ errlHndl_t i2cReset ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, - input_args_t i_args ); + misc_args_t & i_args ); /** * @brief This function will read the interrupt register and return the @@ -639,9 +643,27 @@ errlHndl_t i2cSendSlaveStop ( TARGETING::Target * i_target, * the error log. */ errlHndl_t i2cGetInterrupts ( TARGETING::Target * i_target, - input_args_t i_args, + misc_args_t & i_args, uint64_t & o_intRegValue ); +/** + * @brief This function calculates the different variables related to the + * I2C Bus Speed that are used in the other functions + * + * @param[in] i_target - The I2C master target. + * + * @param[in] i_mode - States how bus setting will be determined + * + * @param[in/out] io_args - Structure containing arguments needed for a command + * transaction. Clock arguments set in this function. + * + * @return errHndl_t - NULL if successful, otherwise a pointer to + * the error log. + */ +errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target, + i2c_bus_setting_mode_t i_mode, + misc_args_t & io_args ); + }; // end I2C namespace diff --git a/src/usr/i2c/test/eepromddtest.H b/src/usr/i2c/test/eepromddtest.H index 48b6329cc..d8e0fef9f 100755 --- a/src/usr/i2c/test/eepromddtest.H +++ b/src/usr/i2c/test/eepromddtest.H @@ -28,14 +28,15 @@ * * @brief Test cases for the eeprom dd code */ -#include <sys/time.h> +#include <sys/time.h> #include <cxxtest/TestSuite.H> #include <errl/errlmanager.H> #include <errl/errlentry.H> #include <devicefw/driverif.H> #include <i2c/eepromddreasoncodes.H> #include <targeting/common/commontargeting.H> +#include <pnor/pnorif.H> #include "i2ctest.H" #include "../eepromdd.H" @@ -47,7 +48,6 @@ using namespace TARGETING; using namespace EEPROM; - class EEPROMTest: public CxxTest::TestSuite { public: @@ -63,10 +63,6 @@ class EEPROMTest: public CxxTest::TestSuite int fails = 0; int num_ops = 0; - uint8_t* testBuffer = NULL; - uint8_t* testBuffer_read = NULL; - - TRACFCOMP( g_trac_eeprom, "testEEPROMReadWrite - Start" ); @@ -151,8 +147,8 @@ class EEPROMTest: public CxxTest::TestSuite for( uint32_t j = 0; j < fullList.size(); j++ ) { // Skip this target if EEPROM isn't available. or if non functional - if( !isI2CAvailable( fullList[j] ) || - !fullList[j]->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) + if( !fullList[j]->getAttr<TARGETING::ATTR_HWAS_STATE>()\ + .functional) { continue; } @@ -208,93 +204,256 @@ class EEPROMTest: public CxxTest::TestSuite } } - // Test EEPROM Write of large size - // @todo RTC:69113 - will clean this up: - // 1) Make its own testcase function - // 2) Will use a larger data set: Plan on using 4K header of - // test_signed_container and putting it into un-used area of - // SBE_BACKUP - // 3) Will restore original data just in case - uint64_t testBufLen = 0xF1; - testBuffer = static_cast<uint8_t*>(malloc(testBufLen)); - memset(testBuffer, 0xFE, testBufLen); - - // Randomize the Data a bit - for (uint64_t i = 0; - i < ((testBufLen / 8) + 1); - i++) - testBuffer[i*8] = i; - - for (uint64_t k = 0; k < 8; k++) - testBuffer[k] = k; - - // do the Write operation - err = deviceOp( DeviceFW::WRITE, - fullList[0], - testBuffer, - testBufLen, - DEVICE_EEPROM_ADDRESS(SBE_BACKUP,0x0)); - if( err ) - { - TS_FAIL( "testEEPROMReadWrite - FAIL on large Data Write"); - errlCommit( err, - EEPROM_COMP_ID ); - delete err; - break; - } + } while( 0 ); - // Read Back and Compare - testBuffer_read = static_cast<uint8_t*>(malloc( testBufLen )); + TRACFCOMP( g_trac_eeprom, + "testEEPROMReadWrite - End: %d/%d fails", + fails, num_ops ); + } - // clear read buffer - memset (testBuffer_read, 0, testBufLen); - // do the Read operation - err = deviceOp( DeviceFW::READ, - fullList[0], - testBuffer_read, - testBufLen, - DEVICE_EEPROM_ADDRESS(SBE_BACKUP,0x0)); + /** + * @brief EEPROM Read/Write Large Test + * This test will read and write 1KB of data to SBE Backup + * VPD. It will attempt to restore the original data at + * the end of the test. + * + * Note: 1st 1K of SBE EEPROM data is currently blank, so this + * test will read and write to that address space + */ + void testEEPROMReadWriteLarge ( void ) + { + errlHndl_t err = NULL; + int fails = 0; + int num_ops = 0; + int cmds = 0; + + // Create 1KB buffers + size_t testBufLen = 1024; + uint8_t testBuffer[testBufLen]; + uint8_t new_data[testBufLen]; + uint8_t original_data[testBufLen]; + + + TRACFCOMP( g_trac_eeprom, + "testEEPROMReadWriteLarge - Start" ); + + // Skipping EEPROM test altogether in VBU/VPO environment + if( TARGETING::is_vpo() ) + { + return; + } + + do + { + // Get a processor Target + TARGETING::TargetService& l_targetService = + TARGETING::targetService(); + TARGETING::Target* testTarget = NULL; + l_targetService.masterProcChipTargetHandle( testTarget ); + assert(testTarget != NULL); + TargetHandleList fullList; + fullList.push_back( testTarget ); + + // 5 operations of 1K data per target (details below) + const uint32_t NUM_CMDS = 5; + + // Number of total operations + num_ops = fullList.size() * NUM_CMDS; + + /************************************************************/ + /* Using PNOR to return the extended image to use as new_data */ + /**************************************************************/ + // Jumping 32K into extended image for more dense data + static const uint64_t HEADER_OFFSET = 0x8000; + PNOR::SectionInfo_t pnorSectionInfo; - if( err ) + err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, + PNOR::CURRENT_SIDE, + pnorSectionInfo); + + if ( err || + (pnorSectionInfo.size < HEADER_OFFSET + testBufLen) + ) { - TS_FAIL( "testEEPROMReadWrite - FAIL on large Data Read"); - errlCommit( err, - EEPROM_COMP_ID ); + TS_FAIL("testEEPROMReadWriteLarge: PNOR::getSectionInfo failed or size too small: pnorSize=0x%X, HEADER_OFFSET=0x%X, testBufLen = 0x%X", pnorSectionInfo.size, HEADER_OFFSET, testBufLen); + errlCommit(err, EEPROM_COMP_ID); delete err; + fails++; break; } - // Compare the data - if ( memcmp( testBuffer, testBuffer_read, testBufLen) ) + void* tmp_ptr = reinterpret_cast<void*>(pnorSectionInfo.vaddr + + HEADER_OFFSET); + + if (tmp_ptr == NULL) { - TS_FAIL( "testEEPROMReadWrite - MISCOMPARE on large Data"); + TS_FAIL("testEEPROMReadWriteLarge: Couldn't get tmp_ptr for new data"); + errlCommit(err, EEPROM_COMP_ID); + delete err; + fails++; break; + } - else + + // Valid Buffer, so memcpy the first 1KB + memcpy( new_data, tmp_ptr, testBufLen ); + + + /************************************************************/ + /* Loop through targets and perform operations */ + /************************************************************/ + + for( uint32_t i = 0; i < fullList.size(); i++ ) { - TRACUCOMP( g_trac_eeprom, "testEEPROMReadWrite - large " - "Data R/W Successful"); - } + // Skip this target if EEPROM isn't available + // or if non functional + if( !fullList[i]->getAttr<TARGETING::ATTR_HWAS_STATE>()\ + .functional) + { + continue; + } - } while( 0 ); - // Clean up malloc'ed buffers - if ( testBuffer != NULL) - { - free(testBuffer); - } + // Before starting, clear original data buffer + memset(original_data, 0x0, testBufLen); - if ( testBuffer_read != NULL) - { - free(testBuffer_read); - } + for (uint8_t j = 1; j <= NUM_CMDS; j++) + { + + // Details: 5 operations of 1K data per target + // 1) Read Original Data and Save It + // 2) Write New Data + // 3) Read New Data and Compare + // 4) Write Back Original Data + // 5) Read Back Original Data and Compare + + // Clear data buffer before reads + if ( (j == 1) || (j == 3) || (j == 5) ) + { + memset(testBuffer, 0x0, testBufLen); + } + + // For Loop 2: set data to new data + if ( j == 2 ) + { + memcpy(testBuffer, new_data, testBufLen); + } + // For Loop 4: set data to original_data + if ( j == 4 ) + { + memcpy(testBuffer, original_data, testBufLen); + } + + // increment cmd op counter + cmds++; + + // do the Operation + err = deviceOp( + (j%2) ? DeviceFW::READ : DeviceFW::WRITE, + fullList[0], + testBuffer, + testBufLen, + DEVICE_EEPROM_ADDRESS(SBE_BACKUP,0x0)); + + if( err ) + { + TS_FAIL( "testEEPROMReadWriteLarge = OP %d FAILED " + "- cmd %d out of %d", + j, i, NUM_CMDS ); + errlCommit( err, + EEPROM_COMP_ID ); + delete err; + fails++; + continue; + } + + + // Handle loop-specific results + + // For Loop 1: save original data + if ( j == 1 ) + { + memcpy(original_data, testBuffer, testBufLen); + + TRACUCOMP(g_trac_eeprom,"testEEPROMReadWriteLarge:" + " saving original data. i=%d, j=%d", + i, j); + } + + // For Loop 3: compare new data + if ( j == 3 ) + { + // Compare the data + if ( memcmp(testBuffer, new_data, testBufLen) ) + { + TRACFCOMP(g_trac_eeprom, + "testEEPROMReadWriteLarge: MISCOMPARE" + " of new data, len=0x%X", testBufLen); + + TRACFBIN( g_trac_eeprom, "testBuffer=", + testBuffer, testBufLen); + TRACFBIN( g_trac_eeprom, "new_data=", + new_data, testBufLen); + TS_FAIL( "testEEPROMReadWriteLarge - MISCOMPARE" + " on writing new data"); + fails++; + + // Don't break - try to write back original data + continue; + } + else + { + TRACUCOMP(g_trac_eeprom, + "testEEPROMReadWriteLarge: New " + "Data R/W Successful i=%d,j=%d", + i, j); + } + } + + + // For Loop 5: compare writing-back original data + if ( j == 5 ) + { + // Compare the data + if ( memcmp(testBuffer, original_data, testBufLen) ) + { + TRACFCOMP(g_trac_eeprom, + "testEEPROMReadWriteLarge: MISCOMPARE" + " of original data, len=0x%X", + testBufLen); + + TRACFBIN( g_trac_eeprom, "testBuffer=", + testBuffer, testBufLen); + TRACFBIN( g_trac_eeprom, "orig_data=", + original_data, testBufLen); + + TS_FAIL( "testEEPROMReadWriteLarge - MISCOMPARE" + " on writing back original data"); + fails++; + + break; + } + else + { + TRACUCOMP(g_trac_eeprom, + "testEEPROMReadWriteLarge: Original " + "Data R/W Successful i=%d,j=%d", + i, j); + } + } + + } // end of 'j' loop: 5 ops per target + + } // end of 'i' loop: target loop + + } while( 0 ); TRACFCOMP( g_trac_eeprom, - "testEEPROMReadWrite - %d/%d fails", + "testEEPROMReadWriteLarge - End: %d/%d fails", fails, num_ops ); } @@ -310,6 +469,9 @@ class EEPROMTest: public CxxTest::TestSuite uint64_t data = 0x0ull; size_t dataSize = 8; + TRACFCOMP( g_trac_eeprom, + "testEEPROMInvalidOperation - Start" ); + do { // Get a processor Target @@ -318,10 +480,9 @@ class EEPROMTest: public CxxTest::TestSuite tS.masterProcChipTargetHandle( testTarget ); assert(testTarget != NULL); - // Skip this target if EEPROM isn't available or target is non - // functional - if( !isI2CAvailable( testTarget ) || - !testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) + // Skip this target if target is non-functional + if(!testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().\ + functional) { continue; } @@ -337,23 +498,96 @@ class EEPROMTest: public CxxTest::TestSuite if( NULL == err ) { fails++; - TS_FAIL( "Error should've resulted in Operation type of LAST_OP_TYPE!" ); + TS_FAIL( "testEEPROMInvalidOperation - Error should've " + " resulted in Operation type of LAST_OP_TYPE!" ); } else { + TRACUCOMP(g_trac_eeprom, "testEEPROMInvalidOperation - " + "Error log returned as expected. RC=0x%X", + err->reasonCode() ); delete err; err = NULL; } } while( 0 ); TRACFCOMP( g_trac_eeprom, - "testEEPROMInvalidOperation - %d/%d fails", + "testEEPROMInvalidOperation - End: %d/%d fails", fails, num_ops ); } + + /** + * @brief EEPROM Overflow Test + * This test will pass in a target which does not have an + * EEPROM attribute associated with it. It is expected that i + * an error log is to be returned. + */ + void testEEPROMOverflow ( void ) + { + errlHndl_t err = NULL; + int64_t fails = 0, num_ops = 0; + uint64_t data = 0x0ull; + size_t dataSize = 0; + uint64_t offset = 0x0ull; + + TRACFCOMP( g_trac_eeprom, + "testEEPROMOverflow - Start" ); + + do + { + // Get a processor Target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target* testTarget = NULL; + tS.masterProcChipTargetHandle( testTarget ); + assert(testTarget != NULL); + + // Skip this target if target is non-functional + if(!testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>() + .functional) + { + continue; + } + + // Set max length and offset + dataSize = 0xFFFFFFFFFFFFFFFF; + offset = 0xFFFFFFFFFFFFFFFF; + + num_ops++; + err = deviceOp( DeviceFW::WRITE, + testTarget, + &data, + dataSize, + DEVICE_EEPROM_ADDRESS( 0x0, + offset ) ); + + if( NULL == err ) + { + fails++; + TS_FAIL( "testEEPROMOverflow - Error should've " + "resulted from overflow offset and length: " + "offset=0x%X, length = 0x%x", + offset, dataSize); + } + else + { + TRACUCOMP(g_trac_eeprom, "testEEPROMOverflow - " + "Error log returned as expectede. RC=0x%X", + err->reasonCode() ); + delete err; + err = NULL; + } + } while( 0 ); + + TRACFCOMP( g_trac_eeprom, + "testEEPROMInvalidChip - End: %d/%d fails", + fails, num_ops ); + } + + /** * @brief EEPROM Invalid Chip Test * This test will pass in an invalid chip identifier which should - * result in an error being returned back from + * result in an error being returned. */ void testEEPROMInvalidChip ( void ) { @@ -362,19 +596,21 @@ class EEPROMTest: public CxxTest::TestSuite uint64_t data = 0x0ull; size_t dataSize = 8; + TRACFCOMP( g_trac_eeprom, + "testEEPROMInvalidChip - Start" ); do { + // Get a processor Target TARGETING::TargetService& tS = TARGETING::targetService(); TARGETING::Target* testTarget = NULL; tS.masterProcChipTargetHandle( testTarget ); assert(testTarget != NULL); - // Skip this target if EEPROM isn't available. or target is non - // functional - if( !isI2CAvailable( testTarget ) || - !testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) + // Skip this target if target is non-functional + if(!testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>() + .functional) { continue; } @@ -390,21 +626,28 @@ class EEPROMTest: public CxxTest::TestSuite if( NULL == err ) { fails++; - TS_FAIL( "Error should've resulted in using EEPROM chip %d!", + TS_FAIL( "testEEPROMInvalidChip - Error should've " + "resulted in using EEPROM chip %d!", LAST_CHIP_TYPE ); } else { + TRACUCOMP(g_trac_eeprom, "testEEPROMInvalidChip - " + "Error log returned as expected. RC=0x%x ", + err->reasonCode() ); delete err; err = NULL; } + } while( 0 ); TRACFCOMP( g_trac_eeprom, - "testEEPROMInvalidChip - %d/%d fails", + "testEEPROMInvalidChip - End: %d/%d fails", fails, num_ops ); } + + }; #endif diff --git a/src/usr/i2c/test/i2ctest.H b/src/usr/i2c/test/i2ctest.H index 12b12385f..15fe1f226 100755 --- a/src/usr/i2c/test/i2ctest.H +++ b/src/usr/i2c/test/i2ctest.H @@ -35,6 +35,7 @@ #include <errl/errlentry.H> #include <devicefw/driverif.H> #include <i2c/i2creasoncodes.H> +#include <i2c/i2cif.H> #include <targeting/common/predicates/predicates.H> #include <targeting/common/attributes.H> @@ -50,33 +51,6 @@ using namespace TARGETING; // Used to ignore comparing data on reads #define I2C_TEST_IGNORE_DATA_COMPARE 0xFFFFFFFFFFFFFFFF -// @todo RTC:72715: Re-visit the use of this function when we have full -// Attribute support -bool isI2CAvailable( TARGETING::Target * i_target ) -{ - bool avail = true; - - // Rudimentary Check - Every I2C Master has VPD Primary Attribute - EepromVpdPrimaryInfo eepromData; - if( i_target->tryGetAttr<ATTR_EEPROM_VPD_PRIMARY_INFO>( eepromData ) ) - { - - if( ( 0x80 == eepromData.port ) && - ( 0x80 == eepromData.devAddr ) && - ( 0x80 == eepromData.engine ) ) - { - // Default values, thus, not present - avail = false; - } - } - else - { - // Didn't find attribute, thus, not present - avail = false; - } - - return avail; -} class I2CTest: public CxxTest::TestSuite { @@ -296,28 +270,21 @@ class I2CTest: public CxxTest::TestSuite break; default: - TS_FAIL( "Invalid Chip type specificed in testData!" ); + TS_FAIL( "testI2CDirect - Invalid Chip type " + "specificed in testData!" ); fails++; continue; break; }; - // Check to see if I2C function is there - if( !isI2CAvailable( theTarget ) ) - { - TRACFCOMP( g_trac_i2c, - "testI2CDirect Operation - no i2c function" ); - continue; - } - - // check to see if the target is functional before we + // Check to see if the target is functional before we // continue.. if (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) { TRACFCOMP( g_trac_i2c, - "testI2CDirect Operation - target not functional"); + "testI2CDirect - target not functional"); continue; } @@ -363,7 +330,7 @@ class I2CTest: public CxxTest::TestSuite } while( 0 ); TRACFCOMP( g_trac_i2c, - "testI2CDirect - %d/%d fails", + "testI2CDirect - End: %d/%d fails", fails, cmds ); } @@ -494,29 +461,22 @@ class I2CTest: public CxxTest::TestSuite break; default: - TS_FAIL( "Invalid Chip type specificed in testData!" ); + TS_FAIL( "testI2COffset - Invalid Chip type " + "specificed in testData!" ); fails++; continue; break; }; - // Check to see if I2C function is there - if( !isI2CAvailable( theTarget ) ) - { - TRACFCOMP( g_trac_i2c, - "testI2COfset Operation - no i2c function" ); - continue; - } - - // check to see if the target is functional before we + // Check to see if the target is functional before we // continue.. if (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) { TRACFCOMP( g_trac_i2c, - "testI2COffset Operation - target not functional"); + "testI2COffset - target not functional"); continue; } @@ -603,7 +563,8 @@ class I2CTest: public CxxTest::TestSuite "Data Compare Fail: wrote=%016llx, " "read back=%016llx. cmd: %d/%d (%d)", testData[i].data, data, i, NUM_CMDS, j); - TS_FAIL( "testI2COffset - Failure comparing new data!" ); + TS_FAIL( "testI2COffset - Failure comparing " + "new data!" ); fails++; // Don't break - try to write back original data @@ -626,7 +587,8 @@ class I2CTest: public CxxTest::TestSuite "Data Compare Fail: original=%016llx, " "read back=%016llx. cmd: %d/%d (%d)", original_data, data, i, NUM_CMDS, j); - TS_FAIL( "testI2COffset - Failure comparing original data!" ); + TS_FAIL( "testI2COffset - Failure comparing " + "original data!" ); fails++; // Break: stop testing if we can't write back @@ -642,11 +604,41 @@ class I2CTest: public CxxTest::TestSuite } while( 0 ); TRACFCOMP( g_trac_i2c, - "testI2COffset - %d/%d fails", + "testI2COffset - End: %d/%d fails", fails, cmds ); } + /** + * @brief Call I2C Setup Masters Function + * This function is part of the shutdown path and is + * needed by PHYP to ensure that the I2C masters are + * setup correctly on the system. + */ + void testI2CSetupMasters ( void ) + { + errlHndl_t err = NULL; + int fails = 0; + const int NUM_CMDS = 1; + + TRACFCOMP( g_trac_i2c, + "testI2CSetupMasters - Start" ); + + err = I2C::i2cSetupMasters(); + + if( err ) + { + TS_FAIL( "testI2CSetupMasters - Error returned from " + "i2cSetupMasters()"); + fails++; + delete err; + } + + TRACFCOMP( g_trac_i2c, + "testI2CSetupMasters - End: %d/%d fails", + fails, NUM_CMDS ); + } + /** * @brief I2C Invalid Target test @@ -678,7 +670,8 @@ class I2CTest: public CxxTest::TestSuite if( !err ) { - TS_FAIL( "Failure to return error using Master Sentinel Chip!" ); + TS_FAIL( "testI2CInvalidTarget - Failure to return error " + "using Master Sentinel Chip!" ); fails++; } else @@ -688,7 +681,7 @@ class I2CTest: public CxxTest::TestSuite } TRACFCOMP( g_trac_i2c, - "testI2CInvalidTarget - %d/%d fails", + "testI2CInvalidTarget - End: %d/%d fails", fails, NUM_CMDS ); } @@ -704,6 +697,9 @@ class I2CTest: public CxxTest::TestSuite uint64_t data = 0x0ull; size_t dataSize = 8; + TRACFCOMP( g_trac_i2c, + "testI2CInvalidOperation - Start" ); + do { // Get a processor Target @@ -712,15 +708,6 @@ class I2CTest: public CxxTest::TestSuite tS.masterProcChipTargetHandle( testTarget ); assert(testTarget != NULL); - // Check to see if I2C function is there - if( !isI2CAvailable( testTarget ) ) - { - TRACFCOMP( g_trac_i2c, - "testI2CInvalid Operation - no i2c function" ); - - - continue; - } // check to see if the target is functional before we // continue.. @@ -728,7 +715,7 @@ class I2CTest: public CxxTest::TestSuite (!testTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional) { TRACFCOMP( g_trac_i2c, - "testI2CInvalide Operation - not functional" ); + "testI2CInvalidOperation - not functional" ); continue; @@ -746,7 +733,8 @@ class I2CTest: public CxxTest::TestSuite if( NULL == err ) { fails++; - TS_FAIL( "Error should've resulted in Operation type of LAST_OP_TYPE!" ); + TS_FAIL( "testI2CInvalidOperation - Error should've " + "resulted in Operation type of LAST_OP_TYPE!" ); } else { @@ -755,7 +743,7 @@ class I2CTest: public CxxTest::TestSuite } } while( 0 ); TRACFCOMP( g_trac_i2c, - "testI2CInvalidOperation - %d/%d fails", + "testI2CInvalidOperation - End: %d/%d fails", fails, num_ops ); } |