diff options
| author | Terry J. Opie <opiet@us.ibm.com> | 2011-10-27 12:48:46 -0500 |
|---|---|---|
| committer | Terry J. Opie <opiet@us.ibm.com> | 2011-12-01 15:47:22 -0600 |
| commit | dddd1ef3658b3a3a846ec64c3e6ba9ba1f7b746e (patch) | |
| tree | 3cad9b232c35e09596f862fc301788a7a4b71339 /src/usr/i2c/test | |
| parent | 4a353d7840f632640e78cafc7052e2e5a99ad564 (diff) | |
| download | talos-hostboot-dddd1ef3658b3a3a846ec64c3e6ba9ba1f7b746e.tar.gz talos-hostboot-dddd1ef3658b3a3a846ec64c3e6ba9ba1f7b746e.zip | |
I2C Bad Machine Path and Cxx Testcases as well as the EEPROM device driver.
Change-Id: Ia89d3aecb3192a2f99ef9fbb5abe0ce1d528a481
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/506
Tested-by: Jenkins Server
Reviewed-by: Terry J. Opie <opiet@us.ibm.com>
Diffstat (limited to 'src/usr/i2c/test')
| -rwxr-xr-x | src/usr/i2c/test/eepromddtest.H | 278 | ||||
| -rwxr-xr-x | src/usr/i2c/test/i2ctest.H | 325 |
2 files changed, 528 insertions, 75 deletions
diff --git a/src/usr/i2c/test/eepromddtest.H b/src/usr/i2c/test/eepromddtest.H new file mode 100755 index 000000000..1cc815a57 --- /dev/null +++ b/src/usr/i2c/test/eepromddtest.H @@ -0,0 +1,278 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/i2c/test/eepromddtest.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#ifndef __EEPROMTEST_H +#define __EEPROMTEST_H + +/** + * @file eepromtest.H + * + * @brief Test cases for the eeprom dd code + */ +#include <sys/time.h> + +#include <cxxtest/TestSuite.H> +#include <errl/errlmanager.H> +#include <errl/errlentry.H> +#include <errl/errltypes.H> +#include <devicefw/driverif.H> +#include <i2c/eepromddreasoncodes.H> +#include <targeting/predicates/predicatectm.H> +#include <targeting/predicates/predicatepostfixexpr.H> + +extern trace_desc_t* g_trac_eeprom; + +using namespace TARGETING; + +class EEPROMTest: public CxxTest::TestSuite +{ + public: + + /** + * @brief EEPROM Read/Write Test + * This test will test a variety of reads/writes and lengths + * across slave devices. + */ + void testEEPROMReadWrite ( void ) + { + errlHndl_t err = NULL; + int fails = 0; + int num_ops = 0; + + TRACFCOMP( g_trac_eeprom, + "testEEPROMReadWrite - Start" ); + + struct + { + uint64_t addr; // Slave Device Address to access + uint64_t chip; // Which EEPROM chip hung off of the target to access + uint64_t data; // Data to write or compare to + size_t size; // Number of bytes to read/write + bool rnw; // Read (true), Write (false) + } testData[] = + { + { 0x1111, 0x0, 0xfedcba9876543210, 8, false }, // Write data + { 0x1111, 0x0, 0xfedcba9876543210, 8, true }, // Read data + { 0x2222, 0x0, 0xaabb000000000000, 2, false }, + { 0x2222, 0x0, 0xaabb000000000000, 2, true }, + { 0x1122, 0x0, 0x1122334400000000, 4, false }, + { 0x1122, 0x0, 0x1122334400000000, 4, true }, + }; + + const uint32_t NUM_CMDS = sizeof(testData)/sizeof(testData[0]); + + 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 ); + + // TODO - The following is what I want to use... BUT, since we + // can't target DIMMs yet, and only Proc 0 has a slave device + // hung off of it, we can't do that yet. Uncomment the following + // when it is supported. +// TARGETING::TargetService& tS = TARGETING::targetService(); +// TARGETING::Target * sysTarget = NULL; +// TargetHandleList fullList; + +// // Get top level system target +// tS.getTopLevelTarget( sysTarget ); +// assert( sysTarget != NULL ); + +// // Predicate for the Procs +// TARGETING::PredicateCTM predProc( TARGETING::CLASS_CHIP, +// TARGETING::TYPE_PROC ); + +// // Predicate for the DIMMs +// TARGETING::PredicateCTM predDimm( TARGETING::CLASS_CARD, +// TARGETING::TYPE_DIMM ); + +// // Expression to get both Procs and DIMMs. +// PredicatePostfixExpr query; +// query.push( &predProc ).push( &predDimm ).Or(); +// tS.getAssociated( fullList, +// sysTarget, +// TARGETING::TargetService::CHILD, +// TARGETING::TargetService::ALL, +// &query ); +// assert( 0 != fullList.size() ); + + // Number of total operations + num_ops = fullList.size() * NUM_CMDS; + + for( uint32_t j = 0; j < fullList.size(); j++ ) + { + for( uint32_t i = 0; i < NUM_CMDS; i++ ) + { + uint64_t data; + + // if a read, initialize data, else, set data to write + if( testData[i].rnw ) + { + data = 0x0ull; + } + else + { + data = testData[i].data; + } + + // do the operation + err = deviceOp( (testData[i].rnw ? DeviceFW::READ : DeviceFW::WRITE), + fullList[j], + &data, + testData[i].size, + DEVICE_EEPROM_ADDRESS( testData[i].addr, + testData[i].chip ) ); + + if( err ) + { + TS_FAIL( "testEEPROMReadWrite - fail on cmd %d out of %d", + i, NUM_CMDS ); + errlCommit( err, + EEPROM_COMP_ID ); + delete err; + fails++; + continue; + } + + // compare data for the read + if( testData[i].rnw ) + { + if( data != testData[i].data ) + { + TRACFCOMP( g_trac_eeprom, + "testEEPROMReadWrite - cmd: %d/%d, Data read: %016llx, " + "expected: %016llx", + i, NUM_CMDS, data, testData[i].data ); + TS_FAIL( "testEEPROMReadWrite - Failure comparing read data!" ); + fails++; + continue; + } + } + } + } + } while( 0 ); + + TRACFCOMP( g_trac_eeprom, + "testEEPROMReadWrite - %d/%d fails", + fails, num_ops ); + } + + /** + * @brief EEPROM Invalid Operation Test + * This test will pass in an invalid Operation type. It + * is expected that an error log is to be returned. + */ + void testEEPROMInvalidOperation ( void ) + { + errlHndl_t err = NULL; + int64_t fails = 0, num_ops = 0; + uint64_t data = 0x0ull; + size_t dataSize = 8; + + do + { + // Get a processor Target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target* testTarget = NULL; + tS.masterProcChipTargetHandle( testTarget ); + assert(testTarget != NULL); + + num_ops++; + err = deviceOp( DeviceFW::LAST_OP_TYPE, + testTarget, + &data, + dataSize, + DEVICE_EEPROM_ADDRESS( 0x0, + 0x0 ) ); + + if( NULL == err ) + { + fails++; + TS_FAIL( "Error should've resulted in Operation type of LAST_OP_TYPE!" ); + } + else + { + delete err; + err = NULL; + } + } while( 0 ); + TRACFCOMP( g_trac_eeprom, + "testEEPROMInvalidOperation - %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 + */ + void testEEPROMInvalidChip ( void ) + { + errlHndl_t err = NULL; + int64_t fails = 0, num_ops = 0; + uint64_t data = 0x0ull; + size_t dataSize = 8; + + const int64_t CHIP_NUM = 20; + + do + { + // Get a processor Target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target* testTarget = NULL; + tS.masterProcChipTargetHandle( testTarget ); + assert(testTarget != NULL); + + num_ops++; + err = deviceOp( DeviceFW::WRITE, + testTarget, + &data, + dataSize, + DEVICE_EEPROM_ADDRESS( 0x0, + CHIP_NUM ) ); + + if( NULL == err ) + { + fails++; + TS_FAIL( "Error should've resulted in using EEPROM chip %d!", + CHIP_NUM ); + } + else + { + delete err; + err = NULL; + } + } while( 0 ); + + TRACFCOMP( g_trac_eeprom, + "testEEPROMInvalidChip - %d/%d fails", + fails, num_ops ); + } + +}; + +#endif diff --git a/src/usr/i2c/test/i2ctest.H b/src/usr/i2c/test/i2ctest.H index dca02d4e5..f5ed88ca2 100755 --- a/src/usr/i2c/test/i2ctest.H +++ b/src/usr/i2c/test/i2ctest.H @@ -26,7 +26,7 @@ /** * @file i2ctest.H * - * @brief Test case for I2C code + * @brief Test cases for I2C code */ #include <sys/time.h> @@ -36,47 +36,83 @@ #include <errl/errltypes.H> #include <devicefw/driverif.H> #include <i2c/i2creasoncodes.H> +#include <targeting/predicates/predicatectm.H> extern trace_desc_t* g_trac_i2c; using namespace TARGETING; -// Address and data to read/write -struct testI2CParms -{ - uint64_t port; - uint64_t engine; - uint64_t addr; - uint64_t devAddr; - uint64_t data; - size_t size; -}; - -// Test table values -const testI2CParms g_i2cWriteCmdTable[] = -{ - { 0x00, 0x00, 0x1234, 0x50, 0xFEDCBA9876543210, 8 }, - { 0x00, 0x00, 0x1234, 0x50, 0xFEDCBA9876543210, 8 }, -}; - -const uint32_t g_i2cWriteCmdTableSz = -sizeof(g_i2cWriteCmdTable)/sizeof(testI2CParms); - - class I2CTest: public CxxTest::TestSuite { public: /** - * @brief I2C test #1 - * Write value and read back to verify - * Currently only 1 operation + * @brief I2C Read/Write Test + * This test will test a variety of reads/writes and lengths + * across slave devices. + * + * TODO - Currently there is only 1 dummy I2C device that is + * accessible via Simics. Once another is added the structure + * used to direct commands will be altered to use the new device + * and also be changed to not be destructive as they are currently. */ - void testI2C1(void) + void testI2CReadWrite ( void ) { + return; errlHndl_t err = NULL; + int cmds = 0; + int fails = 0; + + TRACFCOMP( g_trac_i2c, + "testI2CReadWrite - Start" ); + + typedef enum + { + I2C_PROC_TARGET, + I2C_CENTAUR_TARGET, + } targetType_t; + + struct + { + uint64_t port; // Master engine port + uint64_t engine; // Master engine + uint64_t devAddr; // Slave Device address + uint64_t data; // Data to write or compare to + size_t size; // Number of Bytes to read/write + bool rnw; // Read (true), Write (false) + targetType_t type; // Target Type + } testData[] = + { + // Dummy I2C Device in Simics + { 0x00, 0x00, 0x50, 0x1234BA9876543210, + 8, false, I2C_PROC_TARGET }, // Write data + { 0x00, 0x00, 0x50, 0x1234000000000000, + 2, false, I2C_PROC_TARGET }, // Write addr for read + { 0x00, 0x00, 0x50, 0xba98765432100000, + 6, true, I2C_PROC_TARGET }, // Read data back + { 0x00, 0x00, 0x50, 0x1100556677880000, + 6, false, I2C_PROC_TARGET }, + { 0x00, 0x00, 0x50, 0x1100000000000000, + 2, false, I2C_PROC_TARGET }, + { 0x00, 0x00, 0x50, 0x5566778800000000, + 4, true, I2C_PROC_TARGET }, + + // TODO - Once these commands are working with Simics, they + // can be enabled. No target date. + // Real Centaur Devices +// { 0x00, 0x00, 0x51, 0x1111000000000000, +// 2, false, I2C_CENTAUR_TARGET }, // Write addr of 0x0000 +// { 0x00, 0x00, 0x51, 0x0000000000000000, +// 8, true, I2C_CENTAUR_TARGET }, // Read 8 bytes +// { 0x00, 0x00, 0x53, 0x0000000000000000, +// 2, false, I2C_CENTAUR_TARGET }, // Write addr of 0x0000 +// { 0x00, 0x00, 0x53, 0x0000000000000000, +// 8, true, I2C_CENTAUR_TARGET }, // Read 8 bytes + }; + + const uint32_t NUM_CMDS = sizeof(testData)/sizeof(testData[0]); - //@todo + //@TODO //@VBU workaround - Disable I2C test case on fake target //Test case use fake targets, which will fail when running //on VBU. Need to fix this. @@ -91,72 +127,211 @@ class I2CTest: public CxxTest::TestSuite return; } - TS_TRACE( "I2C Test 1: its running!" ); - do { - TARGETING::TargetService& l_targetService = TARGETING::targetService(); - TARGETING::Target* testTarget = NULL; - l_targetService.masterProcChipTargetHandle( testTarget ); - assert(testTarget != NULL); + // Get top level system target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target * sysTarget = NULL; + TARGETING::Target * theTarget = NULL; + tS.getTopLevelTarget( sysTarget ); + assert( sysTarget != NULL ); - testI2CParms testEntry = g_i2cWriteCmdTable[0]; + // Get the Proc Target + TARGETING::Target* procTarget = NULL; + tS.masterProcChipTargetHandle( procTarget ); - // Perform I2C write - uint64_t data = testEntry.data; - TS_TRACE( "I2C - calling from Write" ); - err = deviceOp( DeviceFW::WRITE, - testTarget, - &data, - testEntry.size, - DEVICE_I2C_ADDRESS( testEntry.addr, - testEntry.port, - testEntry.engine, - testEntry.devAddr ) ); - - TS_TRACE( "I2C - returned from Write" ); - if( err ) + // Get a Centaur Target + TargetHandleList centList; + TARGETING::PredicateCTM predCent( TARGETING::CLASS_CHIP, + TARGETING::TYPE_MEMBUF ); + tS.getAssociated( centList, + sysTarget, + TARGETING::TargetService::CHILD, + TARGETING::TargetService::ALL, + &predCent ); + + for( uint32_t i = 0; i < NUM_CMDS; i++ ) { - break; - } + uint64_t data; - // Perform I2C read - err = deviceOp( DeviceFW::READ, - testTarget, - &data, - testEntry.size, - DEVICE_I2C_ADDRESS( testEntry.addr, - testEntry.port, - testEntry.engine, - testEntry.devAddr ) ); + // if a read, initialize data, else, set data to write + if( testData[i].rnw ) + { + data = 0x0ull; + } + else + { + data = testData[i].data; + } - if( err ) - { - break; - } + // Decide which target to use + switch( testData[i].type ) + { + case I2C_PROC_TARGET: + if( NULL == procTarget ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK"Processor Target is NULL, go to next " + "operation!" ); + continue; + } - // check the data read - if( testEntry.data != data ) - { - TS_FAIL( "testI2C1 failed! - Data read does not match what was written!" ); - TS_TRACE( "testI2C1 - Data Written: %016llx, Data Read: %016llx", - testEntry.data, data ); + theTarget = procTarget; + break; + + case I2C_CENTAUR_TARGET: + if( ( 0 == centList.size() ) || + ( NULL == centList[0] ) ) + { + TRACFCOMP( g_trac_i2c, + ERR_MRK"Centaur List has %d entries. Either " + "empty or first target is NULL!", + centList.size() ); + continue; + } + + theTarget = centList[0]; + break; + + default: + TS_FAIL( "Invalid Chip type specificed in testData!" ); + fails++; + continue; + break; + }; + + // do the operation + cmds++; + err = deviceOp( (testData[i].rnw ? DeviceFW::READ : DeviceFW::WRITE), + theTarget, + &data, + testData[i].size, + DEVICE_I2C_ADDRESS( testData[i].port, + testData[i].engine, + testData[i].devAddr ) ); + if( err ) + { + TS_FAIL( "testI2CReadWrite - fail on cmd %d out of %d", + i, NUM_CMDS ); + errlCommit( err, + I2C_COMP_ID ); + delete err; + fails++; + continue; + } + + // compare data for the read + if( testData[i].rnw ) + { + if( data != testData[i].data ) + { + TRACFCOMP( g_trac_i2c, + "testI2CReadWrite - cmd: %d/%d, Data read: %016llx, " + "expected: %016llx", + i, NUM_CMDS, data, testData[i].data ); + TS_FAIL( "testI2CReadWrite - Failure comparing read data!" ); + fails++; + continue; + } + } } } while( 0 ); - if ( err ) + TRACFCOMP( g_trac_i2c, + "testI2CReadWrite - %d/%d fails", + fails, cmds ); + } + + /** + * @brief I2C Invalid Target test + * This test will pass in the Master Sentinel chip in as a target + * to be sure that an error is returned, and that the error returned + * is the correct error. + */ + void testI2CInvalidTarget ( void ) + { + errlHndl_t err = NULL; + int fails = 0; + const int NUM_CMDS = 1; + + TRACFCOMP( g_trac_i2c, + "testI2CInvalidTarget - Start" ); + + // Set processor chip to the master + TARGETING::Target* testTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + uint64_t data = 0x0ull; + size_t size = sizeof(uint64_t); + + err = deviceOp( DeviceFW::READ, + testTarget, + &data, + size, + DEVICE_I2C_ADDRESS( 0x0, + 0x0, + 0x50 ) ); + + if( !err ) { - TS_FAIL( "testI2C1 failed! Error committed." ); - errlCommit( err, I2C_COMP_ID ); + TS_FAIL( "Failure to return error using Master Sentinel Chip!" ); + fails++; } else { - TS_TRACE( "testI2C1 runs successfully!" ); + delete err; + err = NULL; } - return; + TRACFCOMP( g_trac_i2c, + "testI2CInvalidTarget - %d/%d fails", + fails, NUM_CMDS ); } + + /** + * @brief I2C Invalid Operation Test + * This test will pass in an invalid Operation type. It + * is expected that an error log is to be returned. + */ + void testI2CInvalidOperation ( void ) + { + errlHndl_t err = NULL; + int64_t fails = 0, num_ops = 0; + uint64_t data = 0x0ull; + size_t dataSize = 8; + + do + { + // Get a processor Target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target* testTarget = NULL; + tS.masterProcChipTargetHandle( testTarget ); + assert(testTarget != NULL); + + num_ops++; + err = deviceOp( DeviceFW::LAST_OP_TYPE, + testTarget, + &data, + dataSize, + DEVICE_I2C_ADDRESS( 0x0, + 0x0, + 0x50 ) ); + + if( NULL == err ) + { + fails++; + TS_FAIL( "Error should've resulted in Operation type of LAST_OP_TYPE!" ); + } + else + { + delete err; + err = NULL; + } + } while( 0 ); + TRACFCOMP( g_trac_i2c, + "testI2CInvalidOperation - %d/%d fails", + fails, num_ops ); + } + }; #endif |

