summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c/test
diff options
context:
space:
mode:
authorTerry J. Opie <opiet@us.ibm.com>2011-10-27 12:48:46 -0500
committerTerry J. Opie <opiet@us.ibm.com>2011-12-01 15:47:22 -0600
commitdddd1ef3658b3a3a846ec64c3e6ba9ba1f7b746e (patch)
tree3cad9b232c35e09596f862fc301788a7a4b71339 /src/usr/i2c/test
parent4a353d7840f632640e78cafc7052e2e5a99ad564 (diff)
downloadtalos-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-xsrc/usr/i2c/test/eepromddtest.H278
-rwxr-xr-xsrc/usr/i2c/test/i2ctest.H325
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
OpenPOWER on IntegriCloud