summaryrefslogtreecommitdiffstats
path: root/src/usr/vpd/test
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-01-07 12:31:20 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-01-15 11:57:02 -0600
commitf0036f0c657e090d38b58b8cd95b4ddde1d55b33 (patch)
tree1601dc566fe7083603494a2b22d61fadf7fe5c03 /src/usr/vpd/test
parenta84cc4b307526e9895747f2e78bb36c93582d796 (diff)
downloadtalos-hostboot-f0036f0c657e090d38b58b8cd95b4ddde1d55b33.tar.gz
talos-hostboot-f0036f0c657e090d38b58b8cd95b4ddde1d55b33.zip
Refactor VPD code to eliminate redundancies
After noticing some redundant code and some odd include gymnastics I pulled all of the VPD related code (spd,mvpd) into a single vpd directory/module/component. This should make the addition of the centaur fru vpd simpler as well. Note: this is part of Story 39177 but not all of it, merging this early to not hold up the work for Story 44009. Change-Id: I7637a94d22e188050403ed5600b2d7f304c3d006 RTC: 39177 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2863 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/vpd/test')
-rwxr-xr-xsrc/usr/vpd/test/dimmPrestest.H188
-rw-r--r--src/usr/vpd/test/makefile28
-rwxr-xr-xsrc/usr/vpd/test/mvpdtest.H930
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H765
4 files changed, 1911 insertions, 0 deletions
diff --git a/src/usr/vpd/test/dimmPrestest.H b/src/usr/vpd/test/dimmPrestest.H
new file mode 100755
index 000000000..ff8c3e4cb
--- /dev/null
+++ b/src/usr/vpd/test/dimmPrestest.H
@@ -0,0 +1,188 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/test/dimmPrestest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __DIMMPRESTEST_H
+#define __DIMMPRESTEST_H
+
+/**
+ * @file dimmPrestest.H
+ *
+ * @brief Test cases for DIMM Presence detect
+ */
+#include <sys/time.h>
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <targeting/common/predicates/predicates.H>
+
+#include <vpd/vpdreasoncodes.H>
+#include <vpd/spdenums.H>
+#include "spdtest.H"
+#include "../spd.H"
+
+extern trace_desc_t* g_trac_spd;
+
+using namespace TARGETING;
+using namespace SPD;
+
+class DIMMPresTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief This test is for testing the DIMM Presence detect logic.
+ */
+ void testDimmPres ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ bool present = false;
+ size_t presentSize = sizeof(present);
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testDimmPres()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testDimmPres() - No DIMMs found!" );
+ break;
+ }
+
+ // Test only on first DIMM.
+ cmds++;
+ theTarget = dimmList[0];
+
+ // Check presence
+ err = deviceRead( theTarget,
+ &present,
+ presentSize,
+ DEVICE_PRESENT_ADDRESS() );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testDimmPres() - Error returned from DIMM Presence "
+ "Detect call!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+ else if( presentSize != sizeof(present) )
+ {
+ fails++;
+ TS_FAIL( "testDimmPrs() - Size of Presence buffer is not size "
+ "of boolean!" );
+ continue;
+ }
+ else
+ {
+ // Test was good.
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testDimmPres - %d/%d fails",
+ fails, cmds );
+ }
+
+
+ /**
+ * @brief This test tests that invalid sizes for Presence detect
+ * return errors.
+ */
+ void testDimmPresInvalidSize ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ bool present = false;
+ size_t presentSize = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testDimmPresInvalidSize()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testDimmPresInvalidSize() - No DIMMs found!" );
+ break;
+ }
+
+ // Test on first DIMM only
+ cmds++;
+ theTarget = dimmList[0];
+
+ // Check presence
+ err = deviceRead( theTarget,
+ &present,
+ presentSize,
+ DEVICE_PRESENT_ADDRESS() );
+
+ if( !err )
+ {
+ fails++;
+ TS_FAIL( "testDimmPresInvalidSize() - Error not flagged for "
+ "invalid size!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+ else
+ {
+ // Delete the error and continue
+ delete err;
+ err = NULL;
+ continue;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testDimmPresInvalidSize() - %d/%d fails",
+ fails, cmds );
+ }
+
+
+};
+
+#endif
diff --git a/src/usr/vpd/test/makefile b/src/usr/vpd/test/makefile
new file mode 100644
index 000000000..2ef83c69c
--- /dev/null
+++ b/src/usr/vpd/test/makefile
@@ -0,0 +1,28 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/vpd/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012,2013
+#
+# 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 otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+ROOTPATH = ../../../..
+
+MODULE = testvpd
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/vpd/test/mvpdtest.H b/src/usr/vpd/test/mvpdtest.H
new file mode 100755
index 000000000..9480f2881
--- /dev/null
+++ b/src/usr/vpd/test/mvpdtest.H
@@ -0,0 +1,930 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/test/mvpdtest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __MVPDTEST_H
+#define __MVPDTEST_H
+
+/**
+ * @file mvpdtest.H
+ *
+ * @brief Test cases for MVPD code
+ */
+#include <sys/time.h>
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <targeting/common/predicates/predicatectm.H>
+
+#include <vpd/mvpdenums.H>
+#include <vpd/vpdreasoncodes.H>
+#include "../mvpd.H"
+
+
+extern trace_desc_t* g_trac_mvpd;
+
+using namespace TARGETING;
+using namespace MVPD;
+
+/**
+ * @brief Structure to define record/keyword pairs for MVPD tests.
+ */
+struct mvpdTestData
+{
+ mvpdRecord record;
+ mvpdKeyword keyword;
+};
+
+/**
+ * @brief Data sample to be used for MVPD testing.
+ * NOTE: By reading this entire list, it also validates that the records
+ * and keywords that we expect to be there are actually there...
+ */
+mvpdTestData mvpdData[] =
+{
+ { CRP0, VD },
+ { CRP0, ED },
+ { CRP0, TE },
+ { CRP0, DD },
+// { CRP0, pdP }, // TODO - no #P in test data, pull for now RTC 51716
+ { CRP0, ST },
+// { CRP0, DN, 0x03 }, // TODO - This doesn't match documentation,
+// pulling out for now
+ { CP00, VD },
+ { CP00, PG },
+// { CP00, PK }, // TODO - no PK in test data. pull for now RTC 51716
+ { CP00, pdR },
+ { CP00, pdG },
+ { CP00, pdV },
+ { CP00, pdH },
+// { CP00, pdP }, // TODO - no #P in test data, pull for now RTC 51716
+ { CP00, SB },
+ { CP00, MK },
+ { CP00, PB },
+/* // TODO no LRP0,LRP1,LRP2,LRP3 in test data, pull for now RTC 51716
+ { LRP0, VD },
+ { LRP0, pdV },
+ { LRP0, pdP },
+ { LRP0, pdM },
+ { LRP0, CH },
+ { LRP1, VD },
+ { LRP1, pdV },
+ { LRP1, pdP },
+ { LRP1, pdM },
+ { LRP1, CH },
+ { LRP2, VD },
+ { LRP2, pdV },
+ { LRP2, pdP },
+ { LRP2, pdM },
+ { LRP2, CH },
+ { LRP3, VD },
+ { LRP3, pdV },
+ { LRP3, pdP },
+ { LRP3, pdM },
+ { LRP3, CH },
+*/
+ { LRP4, VD },
+ { LRP4, pdV },
+ { LRP4, pdP },
+ { LRP4, pdM },
+ { LRP4, CH },
+ { LRP5, VD },
+ { LRP5, pdV },
+ { LRP5, pdP },
+ { LRP5, pdM },
+ { LRP5, CH },
+ { LRP6, VD },
+ { LRP6, pdV },
+ { LRP6, pdP },
+ { LRP6, pdM },
+ { LRP6, CH },
+/* // TODO no LRP7,LRP8,LRP9,LRPA,LRPB,LWPO,LWP1,LWP2,LWP3 in test data, pull for now RTC 51716
+ { LRP7, VD },
+ { LRP7, pdV },
+ { LRP7, pdP },
+ { LRP7, pdM },
+ { LRP7, CH },
+ { LRP8, VD },
+ { LRP8, pdV },
+ { LRP8, pdP },
+ { LRP8, pdM },
+ { LRP8, CH },
+ { LRP9, VD },
+ { LRP9, pdV },
+ { LRP9, pdP },
+ { LRP9, pdM },
+ { LRP9, CH },
+ { LRPA, VD },
+ { LRPA, pdV },
+ { LRPA, pdP },
+ { LRPA, pdM },
+ { LRPA, CH },
+ { LRPB, VD },
+ { LRPB, pdV },
+ { LRPB, pdP },
+ { LRPB, pdM },
+ { LRPB, CH },
+ { LRPC, VD },
+ { LRPC, pdV },
+ { LRPC, pdP },
+ { LRPC, pdM },
+ { LRPC, CH },
+ { LRPD, VD },
+ { LRPD, pdV },
+ { LRPD, pdP },
+ { LRPD, pdM },
+ { LRPD, CH },
+ { LRPE, VD },
+ { LRPE, pdV },
+ { LRPE, pdP },
+ { LRPE, pdM },
+ { LRPE, CH },
+ { LWP0, VD },
+ { LWP0, pd2 },
+ { LWP0, pd3 },
+ { LWP0, IN },
+ { LWP1, VD },
+ { LWP1, pd2 },
+ { LWP1, pd3 },
+ { LWP1, IN },
+ { LWP2, VD },
+ { LWP2, pd2 },
+ { LWP2, pd3 },
+ { LWP2, IN },
+ { LWP3, VD },
+ { LWP3, pd2 },
+ { LWP3, pd3 },
+ { LWP3, IN },
+*/
+ { LWP4, VD },
+ { LWP4, pd2 },
+ { LWP4, pd3 },
+ { LWP4, IN },
+ { LWP5, VD },
+ { LWP5, pd2 },
+ { LWP5, pd3 },
+ { LWP5, IN },
+ { LWP6, VD },
+ { LWP6, pd2 },
+ { LWP6, pd3 },
+ { LWP6, IN },
+/* // TODO no LWP7,LWP8,LWP9,LWPA,LWPB in test data, pull for now RTC 51716
+ { LWP7, VD },
+ { LWP7, pd2 },
+ { LWP7, pd3 },
+ { LWP7, IN },
+ { LWP8, VD },
+ { LWP8, pd2 },
+ { LWP8, pd3 },
+ { LWP8, IN },
+ { LWP9, VD },
+ { LWP9, pd2 },
+ { LWP9, pd3 },
+ { LWP9, IN },
+ { LWPA, VD },
+ { LWPA, pd2 },
+ { LWPA, pd3 },
+ { LWPA, IN },
+ { LWPB, VD },
+ { LWPB, pd2 },
+ { LWPB, pd3 },
+ { LWPB, IN },
+ { LWPC, VD },
+ { LWPC, pd2 },
+ { LWPC, pd3 },
+ { LWPC, IN },
+ { LWPD, VD },
+ { LWPD, pd2 },
+ { LWPD, pd3 },
+ { LWPD, IN },
+ { LWPE, VD },
+ { LWPE, pd2 },
+ { LWPE, pd3 },
+ { LWPE, IN },
+*/
+ { VINI, DR },
+ { VINI, VZ },
+ { VINI, CC },
+ { VINI, CE },
+ { VINI, FN },
+ { VINI, PN },
+ { VINI, SN },
+ { VINI, PR },
+ { VINI, HE },
+ { VINI, CT },
+ { VINI, HW },
+ // TODO - Add VWML when available.
+};
+
+void getProcTargets( TargetHandleList & o_procList )
+{
+ // Get top level system target
+ TARGETING::TargetService & tS = TARGETING::targetService();
+ TARGETING::Target * sysTarget = NULL;
+ tS.getTopLevelTarget( sysTarget );
+ assert( sysTarget != NULL );
+
+ // Get a Proc Target
+ TARGETING::PredicateCTM predProc( TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC );
+ tS.getAssociated( o_procList,
+ sysTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL,
+ &predProc );
+
+ TRACDCOMP( g_trac_mvpd,
+ "getProcTargets() - found %d Processors",
+ o_procList.size() );
+
+ return;
+}
+
+class MVPDTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief This function will test MVPD reads.
+ */
+ void testMvpdRead ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint64_t theRecord = 0x0;
+ uint64_t theKeyword = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdRead()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdRead() - No Proc Targets found!" );
+
+ continue; // add continue because have no proc targets
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdRead() - Proc Target [0] non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+ const uint32_t numCmds = sizeof(mvpdData)/sizeof(mvpdData[0]);
+ for( uint32_t curCmd = 0; curCmd < numCmds; curCmd++ )
+ {
+ cmds++;
+ theRecord = (uint64_t)mvpdData[curCmd].record;
+ theKeyword = (uint64_t)mvpdData[curCmd].keyword;
+ err = deviceRead( theTarget,
+ NULL,
+ theSize,
+ DEVICE_MVPD_ADDRESS( theRecord,
+ theKeyword ) );
+
+ if( err )
+ {
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdRead() - failure reading "
+ "keyword size!! rec: 0x%04x, kwd: 0x%04x",
+ theRecord,
+ theKeyword );
+ TS_FAIL( "testMvpdRead() - Failure reading keyword size!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ // Read record/keyword pair
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( theRecord,
+ theKeyword ) );
+
+ if( err )
+ {
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdRead() - Failure on Record: "
+ "0x%04x, keyword: 0x%04x, of size: 0x%04x "
+ "- test %d",
+ theRecord,
+ theKeyword,
+ theSize, curCmd );
+ TS_FAIL( "testMvpdRead() - Failure during MVPD read!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+
+ // Free the data
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+ continue;
+ }
+
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"testMvpdRead Results:" );
+ for( uint32_t i = 0; i < theSize; i++ )
+ {
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK" Byte[%d]: 0x%02x",
+ i, theData[i] );
+ }
+
+ // Free the data
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdRead - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test MVPD writes.
+ */
+ void testMvpdWrite ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdWrite()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdWrite() - No Proc Targets found!" );
+
+ continue; // no proc targets.
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdWrite() - Proc Target [0] non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ size_t theSize = 1;
+ uint8_t * theData = new uint8_t[theSize];
+
+ cmds++;
+ err = deviceWrite( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( CRP0,
+ pdP ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdWrite - Expected error from write "
+ "attempt since its not supported!" );
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdWrite - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test that an error is generated when a record
+ * is passed in that cannot be found in the structure that defines the
+ * Records string representation.
+ */
+ void testMvpdInvalidRecord ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdInvalidRecord()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidRecord() - No Proc Targets "
+ "found!" );
+
+ continue;
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidRecord() - Proc Target [0] non "
+ "functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ size_t theSize = 1;
+ uint8_t * theData = new uint8_t[theSize];
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( MVPD_LAST_RECORD,
+ pdP ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdInvalidRecord() - Error expected with "
+ "record of type MVPD_LAST_RECORD (0x%04x), but "
+ "no error returned!",
+ MVPD_LAST_RECORD );
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidRecord - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test for a record which is not in the TOC of
+ * the MVPD area.
+ */
+ void testMvpdMissingRecord ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdMissingRecord()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+
+ "testMvpdMissingRecord() - No Proc Targets found!" );
+
+ continue;
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdMissingRecord() - Proc Target [0] "
+ "non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ size_t theSize = 1;
+ uint8_t * theData = new uint8_t[theSize];
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( MVPD_TEST_RECORD,
+ pdP ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdMissingRecord() - ");
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdMissingRecord - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test for a keyword that cannot be found
+ * in the expected record
+ */
+ void testMvpdMissingKeyword ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdMissingKeyword()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+
+ "testMvpdMissingKeyword() - No Proc Targets found!" );
+
+ continue;
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdMissingKeyword() - Proc Target [0] "
+ "non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ size_t theSize = 1;
+ uint8_t * theData = new uint8_t[theSize];
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( MVPD_FIRST_RECORD,
+ MVPD_TEST_KEYWORD ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdMissingKeyword() - Expected error from "
+ "invalid Keyword missing from associated record!" );
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdMissingKeyword - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test that an error is generated when a keyword
+ * is passed in that cannot be found in the structure that defines the
+ * Keywords string representation.
+ */
+ void testMvpdInvalidKeyword ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdInvalidKeyword()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+
+ "testMvpdInvalidKeyword() - No Proc Targets found!" );
+
+ continue;
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidKeyword() - Proc Target [0] "
+ "non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ size_t theSize = 1;
+ uint8_t * theData = new uint8_t[theSize];
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( CRP0,
+ MVPD_LAST_KEYWORD ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdInvalidKeyword() - Error expected with "
+ "keyword of type MVPD_LAST_KEYWORD (0x%04x), but "
+ "no error returned!",
+ MVPD_LAST_KEYWORD );
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidKeyword - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test that an error is generated when a buffer
+ * that has an insufficient size is passed in to read a record/keyword.
+ */
+ void testMvpdInvalidBufferSize ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdInvalidBufferSize()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get the processor targets
+ TargetHandleList procList;
+ getProcTargets( procList );
+
+ if( ( 0 == procList.size() ) ||
+ ( NULL == procList[0] ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidBufferSize() - No Proc Targets "
+ "found!" );
+
+ continue;
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ // check to see if the target is functional
+ if
+ (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ {
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidBufferSize() - Proc Target [0] "
+ "non functional!" );
+
+ continue; // add continue because target is non functional
+ }
+
+ uint8_t * theData = new uint8_t[1];
+ size_t theSize = 0;
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( CRP0,
+ DD ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testMvpdInvalidBufferSize() - Error was expected "
+ "for an invalid size of 0x0 for a MVPD read!" );
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdInvalidBufferSize - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief This function will test the numerical order of the mvpdRecords
+ * and mvpdKeywords structures.
+ */
+ void testMvpdCheckStructOrder ( void )
+ {
+ uint64_t fails = 0x0;
+ mvpdRecord prevRecord = MVPD_FIRST_RECORD;
+ mvpdKeyword prevKeyword = MVPD_FIRST_KEYWORD;
+
+ TRACFCOMP( g_trac_mvpd,
+ ENTER_MRK"testMvpdCheckStructOrder()" );
+
+ // Check the mvpdRecords structure for proper order
+ uint32_t entry = 0x0;
+ for( entry = 0;
+ entry < (sizeof(mvpdRecords)/sizeof(mvpdRecords[0]));
+ entry++ )
+ {
+ if( !(mvpdRecords[entry].record >= prevRecord) )
+ {
+ fails++;
+ TS_FAIL( "testMvpdCheckStructOrder() - Record table out of "
+ "order! Cur Record: 0x%04x, Prev Record: 0x%04x",
+ mvpdRecords[entry].record,
+ prevRecord );
+ }
+ prevRecord = mvpdRecords[entry].record;
+ }
+
+ // Check the mvpdKeywords structure for proper order
+ for( entry = 0;
+ entry < (sizeof(mvpdKeywords)/sizeof(mvpdKeywords[0]));
+ entry++ )
+ {
+ if( !(mvpdKeywords[entry].keyword >= prevKeyword) )
+ {
+ fails++;
+ TS_FAIL( "testMvpdCheckStructOrder() - Keyword table out of "
+ "order! Cur Keyword: 0x%04x, Prev Keyword: 0x%04x",
+ mvpdKeywords[entry].keyword,
+ prevKeyword );
+ }
+ prevKeyword = mvpdKeywords[entry].keyword;
+ }
+
+ TRACFCOMP( g_trac_mvpd,
+ "testMvpdCheckStructOrder - %d fails",
+ fails );
+ }
+
+};
+
+#endif
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
new file mode 100755
index 000000000..38b53bf23
--- /dev/null
+++ b/src/usr/vpd/test/spdtest.H
@@ -0,0 +1,765 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/test/spdtest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* 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 otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SPDTEST_H
+#define __SPDTEST_H
+
+/**
+ * @file spdtest.H
+ *
+ * @brief Test cases for SPD code
+ */
+#include <sys/time.h>
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <targeting/common/predicates/predicates.H>
+#include <targeting/common/utilFilter.H>
+
+#include <vpd/vpdreasoncodes.H>
+#include <vpd/spdenums.H>
+#include "../spdDDR3.H"
+#include "../spd.H"
+
+extern trace_desc_t* g_trac_spd;
+
+using namespace TARGETING;
+using namespace SPD;
+
+void getDIMMTargets ( TargetHandleList & o_dimmList )
+{
+ // Get Dimm list.
+ getAllLogicalCards( o_dimmList,
+ TARGETING::TYPE_DIMM );
+ TRACDCOMP( g_trac_spd,
+ "getDIMMTargets() - found %d DIMMs",
+ o_dimmList.size() );
+ return;
+}
+
+errlHndl_t getMemType( TARGETING::Target * i_target,
+ uint8_t & i_memType )
+{
+ errlHndl_t err = NULL;
+ size_t theSize = 0x1;
+ err = deviceRead( i_target,
+ &i_memType,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+
+ return err;
+}
+
+class SPDTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief This test reads all of the keywords for all of the
+ * DIMMs found.
+ */
+ void testSpdRead ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint8_t * theData = NULL;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdRead()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - No DIMMs found!" );
+ break;
+ }
+
+ // Operate on first DIMM.
+ theTarget = dimmList[0];
+ size_t theSize = 0;
+ uint32_t entry = 0x0;
+
+ // Get the DDR revision
+ uint8_t memType = 0x0;
+ err = getMemType( theTarget,
+ memType );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdRead- Failure reading Basic memory type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;;
+ }
+
+ for( uint64_t keyword = SPD::SPD_FIRST_NORM_KEYWORD;
+ keyword < SPD::SPD_LAST_NORM_KEYWORD; keyword++ )
+ {
+ cmds++;
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+
+ // Get the required size of the buffer
+ theSize = 0;
+ if( SPD_DDR3 == memType )
+ {
+ for( entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( keyword == ddr3Data[entry].keyword )
+ {
+ theSize = ddr3Data[entry].length;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Nothing else supported yet!
+ // Not really a fail, just not supported
+ cmds--;
+ continue;
+ }
+
+ if( 0x0 == theSize )
+ {
+ fails++;
+ TS_FAIL( "testSpdRead - Keyword (0x%04x) size = 0x0",
+ entry );
+ continue;
+ }
+
+ // Allocate the buffer
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( keyword ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdRead - Failure on keyword: %04x",
+ keyword );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+
+ // Read was successful, print out first byte of data read
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: %02x, size: %d",
+ keyword, theData[0], theSize );
+
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+ }
+
+ if( err )
+ {
+ break;
+ }
+ } while( 0 );
+
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief Test a SPD Write
+ */
+ void testSpdWrite ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint8_t * theData = NULL;
+ uint8_t * origData = NULL;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdWrite()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdWrite - No DIMMs found!" );
+ break;
+ }
+
+ // Operate on first DIMM
+ cmds++;
+ theTarget = dimmList[0];
+ size_t theSize = 0;
+
+ // Get Memory Type
+ uint8_t memType = 0x0;
+ err = getMemType( theTarget,
+ memType );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - failed to read memtype!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // Get the size
+ if( SPD_DDR3 == memType )
+ {
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( SPD::DIMM_BAD_DQ_DATA == ddr3Data[entry].keyword )
+ {
+ theSize = ddr3Data[entry].length;
+ break;
+ }
+ }
+ }
+ else
+ {
+ fails++;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWrite - memory type: 0x%04x",
+ memType );
+ TS_FAIL( "testSpdWrite - Unsupported Memory Type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // Allocate data buffer
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ // Read the data out first
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - failed to read DIMM Bad DQ data!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ origData = static_cast<uint8_t*>(malloc( theSize ));
+ memcpy( origData, theData, theSize );
+
+ // Write the data back
+ err = deviceWrite( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
+
+ if( err )
+ {
+ // No error returned, failure
+ fails++;
+ TS_FAIL( "testSpdWrite - Error writing data to DIMM Bad DQ "
+ "data" );
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ // Read the data out again to check it
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - failed to read DIMM Bad DQ data! [2]" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ if( memcmp( theData, origData, theSize ) )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - DIMM Bad DQ data does not match what we wrote!" );
+ TRACFBIN( g_trac_spd, "orig=", origData, theSize );
+ TRACFBIN( g_trac_spd, "read=", theData, theSize );
+ }
+
+ } while( 0 );
+
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+
+ if( NULL != origData )
+ {
+ free( origData );
+ theData = NULL;
+ }
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdWrite - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief Test an invalid Keyword to a DIMM target.
+ */
+ void testSpdInvalidKeyword ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdInvalidKeyword()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidKeyword - No DIMMs found!" );
+ break;
+ }
+
+ // Test on first DIMM only.
+ theTarget = dimmList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0x0;
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::INVALID_SPD_KEYWORD ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testSpdInvalidKeyword - No error returned!" );
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidKeyword - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ * @brief Test an invalid size for an SPD read.
+ */
+ void testSpdInvalidSize ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdInvalidSize()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidSize - No DIMMs found!" );
+ break;
+ }
+
+ // Test on first DIMM only.
+ theTarget = dimmList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0x0; // Invalid size of 0x0
+
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::SPD_FIRST_NORM_KEYWORD ) );
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testSpdInvalidSize - No error for invalid size!" );
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidSize - %d/%d fails",
+ fails, cmds );
+ }
+
+ /**
+ */
+ void testSpdInvalidWrite ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdInvalidWrite()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidSize - No DIMMs found!" );
+ break;
+ }
+
+ // Test on first DIMM only.
+ theTarget = dimmList[0];
+ size_t theSize = 0x10;
+ uint8_t * theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ cmds++;
+ err = deviceWrite( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::SPD_FIRST_NORM_KEYWORD ) );
+
+ // clean up the data
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "No failure for Invalid Write attempt to "
+ "SPD_FIRST_NORM_KEYWORD" );
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidWrite - %d/%d fails",
+ fails, cmds );
+ }
+
+
+ /**
+ * @brief This test will test reading the Module specific keywords.
+ */
+ void testspdDDR3ModSpecKwds( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint8_t memType = 0x0;
+ uint8_t modType = 0x0;
+ uint8_t * theData = NULL;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testspdDDR3ModSpecKwds()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testspdDDR3ModSpecKwds - No DIMMs found!" );
+ break;
+ }
+
+ // Operate on first DIMM.
+ theTarget = dimmList[0];
+ size_t theSize = 0;
+ uint32_t entry = 0x0;
+
+ // Get the DDR revision
+ size_t tmpSize = 0x1;
+ err = deviceRead( theTarget,
+ &memType,
+ tmpSize,
+ DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR3ModSpecKwds- Failure reading Basic "
+ "memory type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // Get the Module Type
+ err = deviceRead( theTarget,
+ &modType,
+ tmpSize,
+ DEVICE_SPD_ADDRESS( SPD::MODULE_TYPE ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR3ModSpecKwds - Failure reading Module "
+ "type" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // The real Keyword read testing
+ for( uint64_t keyword = SPD::SPD_FIRST_MOD_SPEC;
+ keyword < SPD::SPD_LAST_MOD_SPEC; keyword++ )
+ {
+ cmds++;
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+
+ // Get the required size of the buffer
+ theSize = 0;
+ KeywordData kwdData;
+ if( SPD_DDR3 == memType )
+ {
+ for( entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( keyword == ddr3Data[entry].keyword )
+ {
+ kwdData = ddr3Data[entry];
+ theSize = ddr3Data[entry].length;
+ break;
+ }
+ }
+
+ // Check type of module.
+ TRACFCOMP( g_trac_spd,
+ INFO_MRK"SPD Error traces will follow!!! "
+ "Not all module specific keywords will be "
+ "valid for all types of modules. IGNORE!!" );
+ err = checkModSpecificKeyword( kwdData,
+ memType,
+ theTarget );
+
+ if( err )
+ {
+ // This keyword isn't supported with this module
+ // type
+ cmds--;
+ delete err;
+ err = NULL;
+ continue;
+ }
+ }
+ else
+ {
+ // Nothing else supported yet!
+ // Not really a fail, just not supported
+ cmds--;
+ continue;
+ }
+
+ if( 0x0 == theSize )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR3ModSpecKwds - Keyword (0x%04x) "
+ "size = 0x0",
+ entry );
+ continue;
+ }
+
+ // Allocate the buffer
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( keyword ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR3ModSpecKwds - Failure on keyword"
+ "d: %04x",
+ keyword );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+
+ // Read was successful, print out first 2 bytes of data read
+ TRACFCOMP( g_trac_spd,
+ "testspdDDR3ModSpecKwds - kwd: 0x%04x, val: "
+ "%02x, size: %d",
+ keyword, theData[0], theSize );
+
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+ }
+ } while( 0 );
+
+ if( NULL != theData )
+ {
+ free( theData );
+ theData = NULL;
+ }
+
+ TRACFCOMP( g_trac_spd,
+ "testspdDDR3ModSpecKwds - %d/%d fails",
+ fails, cmds );
+ }
+
+
+ /**
+ * @brief This test will ensure that the DDR3 lookup table is in a sorted
+ * order, according to the keyword enumeration, to enable the search
+ * algorithm to work correctly.
+ */
+ void testspdDDR3TableOrder ( void )
+ {
+ uint64_t prevKeyword = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testspdDDR3TableOrder()" );
+
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( !(ddr3Data[entry].keyword >= prevKeyword) )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR3TableOrder - DDR3 table out of order! Cur kwd: "
+ "0x%04x, Pre kwd: 0x%04x",
+ ddr3Data[entry].keyword,
+ prevKeyword );
+ }
+ prevKeyword = ddr3Data[entry].keyword;
+ }
+
+ TRACFCOMP( g_trac_spd,
+ EXIT_MRK"testspdDDR3TableOrder() - fails: %d",
+ fails );
+ }
+
+
+};
+
+#endif
OpenPOWER on IntegriCloud