summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c/test/i2ctest.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/i2c/test/i2ctest.H')
-rwxr-xr-xsrc/usr/i2c/test/i2ctest.H325
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
OpenPOWER on IntegriCloud