diff options
Diffstat (limited to 'src/usr/i2c/test/i2ctest.H')
-rwxr-xr-x | src/usr/i2c/test/i2ctest.H | 325 |
1 files changed, 250 insertions, 75 deletions
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 |