summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--img/.gitignore1
-rw-r--r--src/include/usr/devicefw/userif.H11
-rw-r--r--src/include/usr/hbotcompid.H18
-rw-r--r--src/include/usr/mvpd/mvpdenums.H124
-rw-r--r--src/include/usr/mvpd/mvpdreasoncodes.H79
-rw-r--r--src/makefile10
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H12
-rw-r--r--src/usr/makefile2
-rw-r--r--src/usr/mvpd/makefile32
-rwxr-xr-xsrc/usr/mvpd/mvpd.C940
-rwxr-xr-xsrc/usr/mvpd/mvpd.H366
-rw-r--r--src/usr/mvpd/test/makefile28
-rwxr-xr-xsrc/usr/mvpd/test/mvpdtest.H727
-rwxr-xr-xsrc/usr/spd/spd.C6
-rwxr-xr-xsrc/usr/spd/test/dimmPrestest.H110
-rwxr-xr-xsrc/usr/spd/test/spdtest.H280
16 files changed, 2516 insertions, 230 deletions
diff --git a/img/.gitignore b/img/.gitignore
index 476e0915d..5b27db6d4 100644
--- a/img/.gitignore
+++ b/img/.gitignore
@@ -15,3 +15,4 @@ errlparser
*.csv
dimmspd.dat
*.pnor
+procmvpd.dat
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index 8d95db3a9..acd5d5ada 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -48,6 +48,7 @@ namespace DeviceFW
PRESENT,
FSI,
SPD,
+ MVPD,
LAST_ACCESS_TYPE,
};
@@ -97,6 +98,16 @@ namespace DeviceFW
DeviceFW::MAILBOX, static_cast<uint64_t*>((o_status))
/**
+ * Construct the device addressing parameters for the MVPD device ops.
+ * @param[in] i_record - The enumeration of the MVPD record to access.
+ * @param[in] i_keyword - The enumeration of the MVPD keyword, located
+ * within the i_record Record to access.
+ */
+ #define DEVICE_MVPD_ADDRESS( i_record, i_keyword )\
+ DeviceFW::MVPD, static_cast<uint64_t>(( i_record )),\
+ static_cast<uint64_t>(( i_keyword ))
+
+ /**
* @brief Perform a hardware read operation.
*
* @param[in] i_target Device target to operate on.
diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H
index df0280f14..7888327f3 100644
--- a/src/include/usr/hbotcompid.H
+++ b/src/include/usr/hbotcompid.H
@@ -171,7 +171,7 @@ const char INTR_COMP_NAME[] = "intr";
//@}
/** @name SPD
- * EEPROM device driver component
+ * DIMM SPD device driver component
*/
//@{
const compId_t SPD_COMP_ID = 0x1000;
@@ -186,9 +186,19 @@ const compId_t HBMBOX_COMP_ID = 0x1100;
const char HBMBOX_COMP_NAME[] = "mbox";
//@}
-/** @name FIPS_ERRL
- * Used to add component trace to an error log
- * so that it can be decoded by the FSP errlog parser
+/** @name MVPD
+ * MVPD device driver component
+ */
+//@{
+const compId_t MVPD_COMP_ID = 0x1200;
+const char MVPD_COMP_NAME[] = "mvpd";
+//@}
+
+/** @name RESERVED
+ * Reserved component ID. x3100 is the component ID
+ * of FipS ERRL component. Due to our use of
+ * of the FipS errl tool, let no Hostboot component
+ * use this component ID.
*/
//@{
const compId_t FIPS_ERRL_COMP_ID = 0x3100;
diff --git a/src/include/usr/mvpd/mvpdenums.H b/src/include/usr/mvpd/mvpdenums.H
new file mode 100644
index 000000000..fdb9486ca
--- /dev/null
+++ b/src/include/usr/mvpd/mvpdenums.H
@@ -0,0 +1,124 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/mvpd/mvpdenums.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2012
+//
+// 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
+/**
+ * @file MVpdenums.H
+ *
+ * @brief Enums for the MVPD fields to be requested.
+ *
+ */
+#ifndef __MVPDENUMS_H
+#define __MVPDENUMS_H
+
+namespace MVPD
+{
+
+/**
+* @brief Enumeration for the MVPD Records that contain
+* the keyword enumerations below.
+*/
+enum mvpdRecord
+{
+ MVPD_FIRST_RECORD = 0x00,
+ CRP0 = MVPD_FIRST_RECORD,
+ CP00 = 0x01,
+ VINI = 0x02,
+ LRP0 = 0x03,
+ LRP1 = 0x04,
+ LRP2 = 0x05,
+ LRP3 = 0x06,
+ LRP4 = 0x07,
+ LRP5 = 0x08,
+ LRP6 = 0x09,
+ LRP7 = 0x0a,
+ LRP8 = 0x0b,
+ LRP9 = 0x0c,
+ LRPA = 0x0d,
+ LRPB = 0x0e,
+ LWP0 = 0x0f,
+ LWP1 = 0x10,
+ LWP2 = 0x11,
+ LWP3 = 0x12,
+ LWP4 = 0x13,
+ LWP5 = 0x14,
+ LWP6 = 0x15,
+ LWP7 = 0x16,
+ LWP8 = 0x17,
+ LWP9 = 0x18,
+ LWPA = 0x19,
+ LWPB = 0x1a,
+ VWML = 0x1b,
+
+ // Last Record
+ MVPD_LAST_RECORD,
+ MVPD_TEST_RECORD, // Test purposes ONLY!
+ MVPD_INVALID_RECORD = 0xFFFF,
+};
+
+/**
+* @brief Enumerations for MVPD keywords that can be
+* accessed in the MVPD.
+*/
+enum mvpdKeyword
+{
+ MVPD_FIRST_KEYWORD = 0x00,
+ VD = MVPD_FIRST_KEYWORD,
+ ED = 0x01,
+ TE = 0x02,
+ DD = 0x03,
+ pdP = 0x04,
+ ST = 0x05,
+ DN = 0x06,
+ PG = 0x07,
+ PK = 0x08,
+ pdR = 0x09,
+ pdV = 0x0a,
+ pdH = 0x0b,
+ SB = 0x0c,
+ DR = 0x0d,
+ VZ = 0x0e,
+ CC = 0x0f,
+ CE = 0x10,
+ FN = 0x11,
+ PN = 0x12,
+ SN = 0x13,
+ PR = 0x14,
+ HE = 0x15,
+ CT = 0x16,
+ HW = 0x17,
+ pdM = 0x18,
+ IN = 0x19,
+ pd2 = 0x1a,
+ pd3 = 0x1b,
+ OC = 0x1c,
+ FO = 0x1d,
+ pdI = 0x1e,
+
+ // Last Keyword
+ MVPD_LAST_KEYWORD,
+ MVPD_TEST_KEYWORD, // Test purposes ONLY!
+ INVALID_MVPD_KEYWORD = 0xFFFF,
+};
+
+}; // end MVPD
+
+#endif
diff --git a/src/include/usr/mvpd/mvpdreasoncodes.H b/src/include/usr/mvpd/mvpdreasoncodes.H
new file mode 100644
index 000000000..8e9317b1a
--- /dev/null
+++ b/src/include/usr/mvpd/mvpdreasoncodes.H
@@ -0,0 +1,79 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/mvpd/mvpdreasoncodes.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2012
+//
+// 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
+/**
+ * @file mvpdreasoncodes.H
+ *
+ * @brief Reason codes and module ids for the MVPD device driver
+ *
+ */
+#ifndef __MVPDREASONCODES_H
+#define __MVPDREASONCODES_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#include <hbotcompid.H>
+
+namespace MVPD
+{
+
+/**
+* @enum mvpdModuleid
+*
+* @brief Module Ids used in created errorlogs. Indicates which
+* functions an error log was created in.
+*
+*/
+enum mvpdModuleId
+{
+ MVPD_INVALID_MODULE = 0x00,
+ MVPD_READ_BINARY_FILE = 0x01,
+ MVPD_READ = 0x02,
+ MVPD_WRITE = 0x03,
+ MVPD_TRANSLATE_RECORD = 0x04,
+ MVPD_TRANSLATE_KEYWORD = 0x05,
+ MVPD_FIND_RECORD_OFFSET = 0x06,
+ MVPD_RETRIEVE_KEYWORD = 0x07,
+ MVPD_FETCH_DATA = 0x08,
+ MVPD_CHECK_BUFFER_SIZE = 0x09,
+};
+
+/**
+ * @enum mvpdReasonCode
+ *
+ * @brief Reasoncodes used to describe what errors are being indicated.
+ *
+ */
+enum mvpdReasonCode
+{
+ MVPD_INVALID_REASONCODE = MVPD_COMP_ID | 0x00, // Invalid Reasoncode
+ MVPD_INSUFFICIENT_FILE_SIZE = MVPD_COMP_ID | 0x01,
+ MVPD_OPERATION_NOT_SUPPORTED = MVPD_COMP_ID | 0x02,
+ MVPD_RECORD_NOT_FOUND = MVPD_COMP_ID | 0x03,
+ MVPD_KEYWORD_NOT_FOUND = MVPD_COMP_ID | 0x04,
+ MVPD_RECORD_MISMATCH = MVPD_COMP_ID | 0x05,
+ MVPD_INSUFFICIENT_BUFFER_SIZE = MVPD_COMP_ID | 0x06,
+};
+
+}; // end MVPD
+
+#endif
diff --git a/src/makefile b/src/makefile
index 321b48574..e15e46e26 100644
--- a/src/makefile
+++ b/src/makefile
@@ -54,9 +54,9 @@ BASE_MODULES = trace errl devicefw scom xscom initservice \
EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \
extinitsvc istepdisp hwas fsi fsiscom i2c intr \
- spd dmi_training fapiporeve poreve util \
- sbe_centaur_init mc_init dram_training \
- mdia mbox
+ spd dmi_training fapiporeve poreve util \
+ sbe_centaur_init mc_init dram_training \
+ mdia mbox mvpd
DIRECT_BOOT_MODULES = example
RUNTIME_MODULES =
@@ -65,7 +65,7 @@ TESTCASE_MODULES = cxxtest testerrl testdevicefw testsyslib \
testscom testxscom testtargeting testinitservice testkernel \
testhwpf testecmddatabuffer initsvctesttask testcxxtest \
testpnor testi2c testfsi testvfs testhwas testintr testspd \
- testpore testutil testmbox testmdia
+ testpore testutil testmbox testmdia testmvpd
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
@@ -76,7 +76,7 @@ hbicore_EXTENDED_MODULES = ${EXTENDED_MODULES}
# The sbe_pnor.bin is manually built from CVS SBE procedure files in CVS then copy
# into HostBoot for now. HostBoot build team will have a process of building sbe_pnor
# image later.
-hbicore_DATA_MODULES = sample.if dimmspd.dat sbe_pnor.bin
+hbicore_DATA_MODULES = sample.if dimmspd.dat sbe_pnor.bin procmvpd.dat
hbicore_LIDNUMBER = 80f00100
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index 7d40421e4..00c46b220 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -138,6 +138,18 @@ const TaskInfo g_exttaskinfolist[] = {
}
},
+ /**
+ * @brief mvpd task
+ */
+ {
+ "libmvpd.so", // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended module
+ }
+ },
+
// TODO: Added this in order to successfull init.. Need to remove this and put
// the module load and unload from a the istep dispatcher
// PW - Is this really TODO? Don't we need the hwas module from errl to do
diff --git a/src/usr/makefile b/src/usr/makefile
index 02f209082..669a20fc4 100644
--- a/src/usr/makefile
+++ b/src/usr/makefile
@@ -27,6 +27,6 @@ OBJS = module_init.o
SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \
scom.d xscom.d targeting.d initservice.d hwpf.d \
ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d \
- intr.d spd.d pore.d util.d mbox.d diag.d
+ intr.d spd.d pore.d util.d mbox.d diag.d mvpd.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/mvpd/makefile b/src/usr/mvpd/makefile
new file mode 100644
index 000000000..06df7a80b
--- /dev/null
+++ b/src/usr/mvpd/makefile
@@ -0,0 +1,32 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/mvpd/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012
+#
+# 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
+ROOTPATH = ../../..
+MODULE = mvpd
+
+OBJS = mvpd.o
+
+SUBDIRS = test.d
+
+BINARY_FILES = $(IMGDIR)/procmvpd.dat:9db474cbbd661c54957cb3a6c83cfc768f457d0c
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/mvpd/mvpd.C b/src/usr/mvpd/mvpd.C
new file mode 100755
index 000000000..9b83414e4
--- /dev/null
+++ b/src/usr/mvpd/mvpd.C
@@ -0,0 +1,940 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/mvpd/mvpd.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2012
+//
+// 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
+/**
+ * @file mvpd.C
+ *
+ * @brief Implementation of the MVPD device driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/targetservice.H>
+#include <devicefw/driverif.H>
+#include <vfs/vfs.H>
+#include <mvpd/mvpdreasoncodes.H>
+#include <mvpd/mvpdenums.H>
+
+#include "mvpd.H"
+
+// ----------------------------------------------
+// Globals
+// ----------------------------------------------
+bool g_loadModule = true;
+mutex_t g_mvpdMutex = MUTEX_INITIALIZER;
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+trace_desc_t* g_trac_mvpd = NULL;
+TRAC_INIT( & g_trac_mvpd, "MVPD", 4096 );
+
+// ------------------------
+// Macros for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+
+// ----------------------------------------------
+// Defines
+// ----------------------------------------------
+
+
+namespace MVPD
+{
+
+/**
+* @brief This function compares 2 mvpd record values. Used for binary
+* search to find a match.
+*
+* @param[in] e1 - Entry 1 to be compared.
+*
+* @param[in] e2 - Entry 2 to be compared.
+*
+* @return bool - Whether or not the e2 value is larger than the e1 value.
+*/
+bool compareKeywords ( const mvpdKeywordInfo e1,
+ const mvpdKeywordInfo e2 );
+
+/**
+* @brief This function compares 2 mvpd keyword values. Used for binary
+* search to find a match.
+*
+* @param[in] e1 - Entry 1 to be compared.
+*
+* @param[in] e2 - Entry 2 to be compared.
+*
+* @return bool - Whether or not the e2 value is larger than the e1 value.
+ */
+bool compareRecords ( const mvpdRecordInfo e1,
+ const mvpdRecordInfo e2 );
+
+/**
+ * @brief Swap the 16 bit size read from MVPD since it is stored in the
+ * MVPD byte swapped.
+ *
+ * @param[in] i_size - The size value to be byte swapped.
+ *
+ * @return uint16_t - The byte swapped value.
+ */
+uint16_t swapByteSize ( uint16_t i_size );
+
+/**
+ * @brief This function compares sizes to be sure buffers are large enough
+ * to handle the data to be put in them. If it is not, it will return
+ * an error.
+ *
+ * @param[in] i_bufferSize - The size of the buffer to check.
+ *
+ * @param[in] i_expectedSize - The minimum size the buffer should be.
+ *
+ * @return errlHndl_t - An error log will be returned if the buffer is not
+ * large enough.
+ */
+errlHndl_t checkBufferSize( size_t i_bufferSize,
+ size_t i_expectedSize );
+
+
+// Register with the routing code
+DEVICE_REGISTER_ROUTE( DeviceFW::READ,
+ DeviceFW::MVPD,
+ TARGETING::TYPE_PROC,
+ mvpdRead );
+DEVICE_REGISTER_ROUTE( DeviceFW::WRITE,
+ DeviceFW::MVPD,
+ TARGETING::TYPE_PROC,
+ mvpdRead );
+
+
+// ------------------------------------------------------------------
+// mvpdRead
+// ------------------------------------------------------------------
+errlHndl_t mvpdRead ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t err = NULL;
+ const char * recordName = NULL;
+ const char * keywordName = NULL;
+ uint16_t recordOffset = 0x0;
+ input_args_t args;
+ args.record = ((mvpdRecord)va_arg( i_args, uint64_t ));
+ args.keyword = ((mvpdKeyword)va_arg( i_args, uint64_t ));
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdRead()" );
+
+ do
+ {
+ // Get the Record/keyword names
+ err = mvpdTranslateRecord( args.record,
+ recordName );
+
+ if( err )
+ {
+ break;
+ }
+
+ err = mvpdTranslateKeyword( args.keyword,
+ keywordName );
+
+ if( err )
+ {
+ break;
+ }
+
+ TRACSCOMP( g_trac_mvpd,
+ INFO_MRK"Read record (%s) and Keyword (%s)",
+ recordName, keywordName );
+
+ // Get the offset of the record requested
+ err = mvpdFindRecordOffset( recordName,
+ recordOffset,
+ i_target,
+ args );
+
+ if( err )
+ {
+ break;
+ }
+
+ // use record offset to find/read the keyword
+ err = mvpdRetrieveKeyword( keywordName,
+ recordName,
+ recordOffset,
+ i_target,
+ io_buffer,
+ io_buflen,
+ args );
+
+ if( err )
+ {
+ break;
+ }
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdRead()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdWrite
+// ------------------------------------------------------------------
+errlHndl_t mvpdWrite ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t err = NULL;
+ input_args_t args;
+ args.record = ((mvpdRecord)va_arg( i_args, uint64_t ));
+ args.keyword = ((mvpdKeyword)va_arg( i_args, uint64_t ));
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdWrite()" );
+
+ do
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"MVPD Writes are not supported yet!" );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_OPERATION_NOT_SUPPORTED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_WRITE
+ * @userdata1 Requested Record
+ * @userdata2 Requested Keyword
+ * @devdesc MVPD Writes are not supported currently.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_WRITE,
+ MVPD_OPERATION_NOT_SUPPORTED,
+ args.record,
+ args.keyword );
+
+ break;
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdWrite()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdTranslateRecord
+// ------------------------------------------------------------------
+errlHndl_t mvpdTranslateRecord ( mvpdRecord i_record,
+ const char *& o_record )
+{
+ errlHndl_t err = NULL;
+ uint32_t arraySize = 0x0;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdTranslateRecord()" );
+
+ do
+ {
+ arraySize = (sizeof(mvpdRecords)/sizeof(mvpdRecords[0]));
+ mvpdRecordInfo tmpRecord;
+ tmpRecord.record = i_record;
+ const mvpdRecordInfo * entry = std::lower_bound( mvpdRecords,
+ &mvpdRecords[arraySize],
+ tmpRecord,
+ compareRecords );
+
+ if( ( entry == &mvpdRecords[arraySize] )||
+ ( i_record != entry->record ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"No matching Record (0x%04x) found!",
+ i_record );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_RECORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_TRANSLATE_RECORD
+ * @userdata1 Record enumeration.
+ * @userdata2 <UNUSED>
+ * @devdesc The record enumeration did not have a
+ * corresponding string value.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_TRANSLATE_RECORD,
+ MVPD_RECORD_NOT_FOUND,
+ i_record,
+ 0x0 );
+
+ break;
+ }
+
+ o_record = entry->recordName;
+ TRACDCOMP( g_trac_mvpd,
+ "record name: %s",
+ entry->recordName );
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdTranslateRecord()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdTranslateKeyword
+// ------------------------------------------------------------------
+errlHndl_t mvpdTranslateKeyword ( mvpdKeyword i_keyword,
+ const char *& o_keyword )
+{
+ errlHndl_t err = NULL;
+ uint32_t arraySize = 0x0;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdTranslateKeyword()" );
+
+ do
+ {
+ arraySize = (sizeof(mvpdKeywords)/sizeof(mvpdKeywords[0]));
+ mvpdKeywordInfo tmpKeyword;
+ tmpKeyword.keyword = i_keyword;
+ const mvpdKeywordInfo * entry = std::lower_bound( mvpdKeywords,
+ &mvpdKeywords[arraySize],
+ tmpKeyword,
+ compareKeywords );
+
+ if( ( entry == &mvpdKeywords[arraySize] ) ||
+ ( i_keyword != entry->keyword ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"No matching Keyword found!" );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_KEYWORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_TRANSLATE_KEYWORD
+ * @userdata1 Keyword Enumeration
+ * @userdata2 <UNUSED>
+ * @devdesc The keyword enumeration did not have a
+ * corresponding string value.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_TRANSLATE_KEYWORD,
+ MVPD_KEYWORD_NOT_FOUND,
+ i_keyword,
+ 0x0 );
+
+ break;
+ }
+
+ o_keyword = entry->keywordName;
+ TRACDCOMP( g_trac_mvpd,
+ "keyword name: %s",
+ entry->keywordName );
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdTranslateKeyword()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdFindRecordOffset
+// ------------------------------------------------------------------
+errlHndl_t mvpdFindRecordOffset ( const char * i_record,
+ uint16_t & o_offset,
+ TARGETING::Target * i_target,
+ input_args_t i_args )
+{
+ errlHndl_t err = NULL;
+ uint64_t tmpOffset = 0x0;
+// uint8_t * record = NULL;
+ char record[RECORD_BYTE_SIZE] = { '\0' };
+ uint16_t offset = 0x0;
+ bool matchFound = false;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdFindRecordOffset()" );
+
+ do
+ {
+ // --------------------------------------
+ // Start reading at beginning of file
+ // First 256 bytes are the TOC
+ // --------------------------------------
+ // TOC Format is as follows:
+ // 8 bytes per entry - 32 entries possible
+ // Entry:
+ // byte 0 - 3: ASCII Record Name
+ // byte 4 - 5: Size (byte swapped)
+ // byte 6 - 7: UNUSED
+ // --------------------------------------
+ while( ( tmpOffset < 0x100 ) &&
+ !matchFound )
+ {
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"read offset: 0x%08x",
+ tmpOffset );
+
+ // Read Record Name
+ err = mvpdFetchData( tmpOffset,
+ RECORD_BYTE_SIZE,
+ record,
+ i_target );
+ tmpOffset += RECORD_BYTE_SIZE;
+
+ if( err )
+ {
+ break;
+ }
+
+ if( !(memcmp( record, i_record, RECORD_BYTE_SIZE )) )
+ {
+ matchFound = true;
+
+ // Read the matching records offset
+ err = mvpdFetchData( tmpOffset,
+ RECORD_ADDR_BYTE_SIZE,
+ &offset,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+ }
+ tmpOffset += (RECORD_ADDR_BYTE_SIZE + RECORD_TOC_UNUSED);
+ }
+
+ if( err )
+ {
+ break;
+ }
+ } while( 0 );
+
+ if( !matchFound )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"No matching Record (%s) found in TOC!",
+ i_record );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_RECORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_FIND_RECORD_OFFSET
+ * @userdata1 Requested Record
+ * @userdata2 Requested Keyword
+ * @devdesc The requested record was not found in the MVPD TOC.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_FIND_RECORD_OFFSET,
+ MVPD_RECORD_NOT_FOUND,
+ i_args.record,
+ i_args.keyword );
+ // Add trace to the log so we know what record was being requested.
+ err->collectTrace( "MVPD" );
+ }
+
+ // Return the offset found, after byte swapping it.
+ o_offset = swapByteSize( offset );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdFindRecordOffset()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdRetrieveKeyword
+// ------------------------------------------------------------------
+errlHndl_t mvpdRetrieveKeyword ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ input_args_t i_args )
+{
+ errlHndl_t err = NULL;
+ uint16_t offset = i_offset;
+ uint16_t recordSize = 0x0;
+ uint16_t keywordSize = 0x0;
+// uint8_t * record = NULL;
+// uint8_t * keyword = NULL;
+ char record[RECORD_BYTE_SIZE] = { '\0' };
+ char keyword[KEYWORD_BYTE_SIZE] = { '\0' };
+ bool matchFound = false;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdRetrieveKeyword()" );
+
+ do
+ {
+ // Read size of Record
+ err = mvpdFetchData( offset,
+ RECORD_ADDR_BYTE_SIZE,
+ &recordSize,
+ i_target );
+ offset += RECORD_ADDR_BYTE_SIZE;
+
+ if( err )
+ {
+ break;
+ }
+
+ // Byte Swap
+ recordSize = swapByteSize( recordSize );
+
+ // Skip 3 bytes - RT
+ // Read 4 bytes ( Record name ) - compare with expected
+ offset += RT_SKIP_BYTES;
+ err = mvpdFetchData( offset,
+ RECORD_BYTE_SIZE,
+ record,
+ i_target );
+ offset += RECORD_BYTE_SIZE;
+
+ if( err )
+ {
+ break;
+ }
+
+ if( memcmp( record, i_recordName, RECORD_BYTE_SIZE ) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"Record(%s) for offset (0x%04x) did not match "
+ "expected record(%s)!",
+ record,
+ i_offset,
+ i_recordName );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_RECORD_MISMATCH
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_RETRIEVE_KEYWORD
+ * @userdata1 Current offset into MVPD
+ * @userdata2 Start of Record offset
+ * @devdesc Record name does not match value expected for
+ * offset read.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_RETRIEVE_KEYWORD,
+ MVPD_RECORD_MISMATCH,
+ offset,
+ i_offset );
+ // Add trace so we see what record was being compared
+ err->collectTrace( "MVPD" );
+
+ break;
+ }
+
+ // While size < size of record
+ // Size of record is the input offset, plus the record size, plus
+ // 2 bytes for the size value.
+ while( ( offset < (recordSize + i_offset + RECORD_ADDR_BYTE_SIZE) ) )
+ {
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"Looking for keyword, reading offset: 0x%04x",
+ offset );
+
+ // read keyword name (2 bytes)
+ err = mvpdFetchData( offset,
+ KEYWORD_BYTE_SIZE,
+ keyword,
+ i_target );
+ offset += KEYWORD_BYTE_SIZE;
+
+ if( err )
+ {
+ break;
+ }
+
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"Read keyword name: %s",
+ keyword );
+
+ // Check if we're reading a '#' keyword. They have a 2 byte size
+ uint32_t keywordLength = KEYWORD_SIZE_BYTE_SIZE;
+ bool isPoundKwd = false;
+ if( !(memcmp( keyword, "#", 1 )) )
+ {
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"Reading # keyword, adding 1 byte to size "
+ "to read!" );
+ isPoundKwd = true;
+ keywordLength++;
+ }
+
+ // Read keyword size
+ err = mvpdFetchData( offset,
+ keywordLength,
+ &keywordSize,
+ i_target );
+ offset += keywordLength;
+
+ if( err )
+ {
+ break;
+ }
+
+ if( isPoundKwd )
+ {
+ // Swap it since 2 byte sizes are byte swapped.
+ keywordSize = swapByteSize( keywordSize );
+ }
+ else
+ {
+ keywordSize = keywordSize >> 8;
+ }
+
+ TRACDCOMP( g_trac_mvpd,
+ INFO_MRK"Read keyword size: 0x%04x",
+ keywordSize );
+
+ // if keyword equal i_keywordName
+ if( !(memcmp( keyword, i_keywordName, KEYWORD_BYTE_SIZE ) ) )
+ {
+ matchFound = true;
+ // check size of usr buffer with io_buflen
+ err = checkBufferSize( io_buflen,
+ (size_t)keywordSize );
+
+ if( err )
+ {
+ break;
+ }
+
+ // Read keyword data into io_buffer
+ err = mvpdFetchData( offset,
+ keywordSize,
+ io_buffer,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+ io_buflen = keywordSize;
+
+ // found our match, break out
+ break;
+ }
+ else
+ {
+ // set offset to next keyword (based on current keyword size)
+ offset += keywordSize;
+ }
+ }
+
+ if( err )
+ {
+ break;
+ }
+ } while( 0 );
+
+ // If keyword not found in expected Record, flag error.
+ if( !matchFound &&
+ NULL == err )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"No matching %s keyword found within %s record!",
+ i_keywordName,
+ i_recordName );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_KEYWORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_RETRIEVE_KEYWORD
+ * @userdata1 Start of Record Offset
+ * @userdata2[0:31] Requested Record
+ * @userdata2[32:63] Requested Keyword
+ * @devdesc Keyword was not found in Record starting at given
+ * offset.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_RETRIEVE_KEYWORD,
+ MVPD_KEYWORD_NOT_FOUND,
+ i_offset,
+ TWO_UINT32_TO_UINT64( i_args.record,
+ i_args.keyword ) );
+
+ // Add trace so we know what Record/Keyword was missing
+ err->collectTrace( "MVPD" );
+ }
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdRetrieveKeyword()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdFetchData
+// ------------------------------------------------------------------
+errlHndl_t mvpdFetchData ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target )
+{
+ errlHndl_t err = NULL;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdFetchData()" );
+
+ do
+ {
+ // --------------------------------------------------------------------
+ // TODO - For now this code will call to read a specific binary file
+ // for every request. Eventually that will be replaced with a function
+ // that will read from the actual PNOR section that contains MVPD for
+ // each of the processors in the system.
+ // This will be done with Story 35835.
+ // --------------------------------------------------------------------
+ err = mvpdReadBinaryFile( i_byteAddr,
+ i_numBytes,
+ o_data );
+
+ if( err )
+ {
+ break;
+ }
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdFetchData()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdReadBinaryFile
+// ------------------------------------------------------------------
+errlHndl_t mvpdReadBinaryFile ( uint64_t i_offset,
+ size_t i_numBytes,
+ void * o_data )
+{
+ errlHndl_t err = NULL;
+ const char * fileName = "procmvpd.dat";
+ const char * startAddr = NULL;
+ size_t fileSize;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdReadBinaryFile()" );
+
+ do
+ {
+ if( g_loadModule )
+ {
+ mutex_lock( &g_mvpdMutex );
+
+ if( g_loadModule )
+ {
+ // Load the file
+ TRACUCOMP( g_trac_mvpd,
+ "Load file" );
+ err = VFS::module_load( fileName );
+
+ if( err )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"Error opening binary MVPD file: %s",
+ fileName );
+ mutex_unlock( &g_mvpdMutex );
+
+ break;
+ }
+
+ g_loadModule = false;
+ }
+ mutex_unlock( &g_mvpdMutex );
+ }
+
+ // Get the starting address of the file/module
+ TRACUCOMP( g_trac_mvpd,
+ "Get starting address/size" );
+ err = VFS::module_address( fileName,
+ startAddr,
+ fileSize );
+
+ if( err )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"Error getting starting address of binary MVPD "
+ "file: %s",
+ fileName );
+
+ break;
+ }
+
+ // Check that we can read the amount of data we need to from the
+ // file we just loaded
+ TRACUCOMP( g_trac_mvpd,
+ "Check Size vs file size" );
+ if( (i_offset + i_numBytes) > fileSize )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"Unable to read %d bytes from %s at offset 0x%08x "
+ "because file size is only %d bytes!",
+ i_numBytes,
+ fileName,
+ i_offset,
+ fileSize );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_INSUFFICIENT_FILE_SIZE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_READ_BINARY_FILE
+ * @userdata1 File Size
+ * @userdata2[0:31] Starting offset into file
+ * @userdata2[32:63] Number of bytes to read
+ * @devdesc File is not sufficiently large to read number of
+ * bytes at offset given without overrunning file.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_READ_BINARY_FILE,
+ MVPD_INSUFFICIENT_FILE_SIZE,
+ fileSize,
+ TWO_UINT32_TO_UINT64( i_offset,
+ fileSize ) );
+
+ break;
+ }
+
+ // Retrieve the data requested
+ TRACUCOMP( g_trac_mvpd,
+ "Copy data out of file" );
+ memcpy( o_data, (startAddr + i_offset), i_numBytes );
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdReadBinaryFile()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// checkBufferSize
+// ------------------------------------------------------------------
+errlHndl_t checkBufferSize( size_t i_bufferSize,
+ size_t i_expectedSize )
+{
+ errlHndl_t err = NULL;
+
+ if( !(i_bufferSize >= i_expectedSize) )
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"Buffer size (%d) is not larger than expected size "
+ "(%d)",
+ i_bufferSize,
+ i_expectedSize );
+
+ /*@
+ * @errortype
+ * @reasoncode MVPD_INSUFFICIENT_BUFFER_SIZE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MVPD_CHECK_BUFFER_SIZE
+ * @userdata1 Buffer Size
+ * @userdata2 Expected Buffer Size
+ * @devdesc Buffer size was not greater than or equal to
+ * expected buffer size.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MVPD_CHECK_BUFFER_SIZE,
+ MVPD_INSUFFICIENT_BUFFER_SIZE,
+ i_bufferSize,
+ i_expectedSize );
+ }
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// compareRecords
+// ------------------------------------------------------------------
+bool compareRecords ( const mvpdRecordInfo e1,
+ const mvpdRecordInfo e2 )
+{
+ if( e2.record > e1.record )
+ return true;
+ else
+ return false;
+}
+
+
+// ------------------------------------------------------------------
+// compareKeywords
+// ------------------------------------------------------------------
+bool compareKeywords ( const mvpdKeywordInfo e1,
+ const mvpdKeywordInfo e2 )
+{
+ if( e2.keyword > e1.keyword )
+ return true;
+ else
+ return false;
+}
+
+
+// ------------------------------------------------------------------
+// swapByteSize
+// ------------------------------------------------------------------
+uint16_t swapByteSize ( uint16_t i_size )
+{
+ uint16_t swappedSize = i_size & 0x00FF;
+ uint16_t tmp = i_size & 0xFF00;
+ tmp = tmp >> 8;
+ swappedSize = swappedSize << 8;
+ swappedSize = swappedSize | tmp;
+ return swappedSize;
+}
+
+} // end namespace MVPD
diff --git a/src/usr/mvpd/mvpd.H b/src/usr/mvpd/mvpd.H
new file mode 100755
index 000000000..195016c1c
--- /dev/null
+++ b/src/usr/mvpd/mvpd.H
@@ -0,0 +1,366 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/mvpd/mvpd.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2012
+//
+// 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 __MVPD_H
+#define __MVPD_H
+
+/**
+ * @file mvpd.H
+ *
+ * @brief Provides the interfaces for the MVPD device driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <errl/errlentry.H>
+
+namespace MVPD
+{
+
+/**
+* @brief Miscelaneous MVPD definitions
+*/
+enum
+{
+ RECORD_BYTE_SIZE = 4,
+ RECORD_ADDR_BYTE_SIZE = 2,
+ KEYWORD_BYTE_SIZE = 2,
+ KEYWORD_SIZE_BYTE_SIZE = 1,
+ RECORD_TOC_UNUSED = 2,
+ RT_SKIP_BYTES = 3,
+
+};
+
+/**
+* @brief Structure for all MVPD dd input parameter arguments
+*/
+typedef struct
+{
+ mvpdRecord record;
+ mvpdKeyword keyword;
+} input_args_t;
+
+/**
+ * @brief Structure of information needed to access requested
+ * record/keyword combinations.
+ */
+typedef struct
+{
+ mvpdRecord record;
+ char recordName[MVPD_LAST_RECORD];
+} mvpdRecordInfo;
+
+/**
+ */
+typedef struct
+{
+ mvpdKeyword keyword;
+ char keywordName[MVPD_LAST_KEYWORD];
+} mvpdKeywordInfo;
+
+
+/**
+ * @brief Conversion of MVPD Records to corresponding character representation.
+ */
+const mvpdRecordInfo mvpdRecords[] =
+{
+ // -------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! There will be a
+ // testcase that checks this. When adding new entries to the
+ // list, be sure that the keyword in each entry (value 0)
+ // are in ascending order.
+ // -------------------------------------------------------------------
+ { CRP0, "CRP0" },
+ { CP00, "CP00" },
+ { VINI, "VINI" },
+ { LRP0, "LRP0" },
+ { LRP1, "LRP1" },
+ { LRP2, "LRP2" },
+ { LRP3, "LRP3" },
+ { LRP4, "LRP4" },
+ { LRP5, "LRP5" },
+ { LRP6, "LRP6" },
+ { LRP7, "LRP7" },
+ { LRP8, "LRP8" },
+ { LRP9, "LRP9" },
+ { LRPA, "LRPA" },
+ { LRPB, "LRPB" },
+ { LWP0, "LWP0" },
+ { LWP1, "LWP1" },
+ { LWP2, "LWP2" },
+ { LWP3, "LWP3" },
+ { LWP4, "LWP4" },
+ { LWP5, "LWP5" },
+ { LWP6, "LWP6" },
+ { LWP7, "LWP7" },
+ { LWP8, "LWP8" },
+ { LWP9, "LWP9" },
+ { LWPA, "LWPA" },
+ { LWPB, "LWPB" },
+ { VWML, "VWML" },
+ // -------------------------------------------------------------------
+ // DO NOT USE!! This is for test purposes ONLY!
+ { MVPD_TEST_RECORD, "TEST" },
+ // -------------------------------------------------------------------
+};
+
+/**
+ * @brief Conversion of MVPD Keywords to corresponding character representation.
+ */
+const mvpdKeywordInfo mvpdKeywords[] =
+{
+ // -------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! There will be a
+ // testcase that checks this. When adding new entries to
+ // the list, be sure that the keyword in each entry (value 0)
+ // are in ascending order.
+ // -------------------------------------------------------------------
+ { VD, "VD" },
+ { ED, "ED" },
+ { TE, "TE" },
+ { DD, "DD" },
+ { pdP, "#P" },
+ { ST, "ST" },
+ { DN, "DN" },
+ { PG, "PG" },
+ { PK, "PK" },
+ { pdR, "#R" },
+ { pdV, "#V" },
+ { pdH, "#H" },
+ { SB, "SB" },
+ { DR, "DR" },
+ { VZ, "VZ" },
+ { CC, "CC" },
+ { CE, "CE" },
+ { FN, "FN" },
+ { PN, "PN" },
+ { SN, "SN" },
+ { PR, "PR" },
+ { HE, "HE" },
+ { CT, "CT" },
+ { HW, "HW" },
+ { pdM, "#M" },
+ { IN, "IN" },
+ { pd2, "#2" },
+ { pd3, "#3" },
+ { OC, "OC" },
+ { FO, "FO" },
+ { pdI, "#I" },
+ // -------------------------------------------------------------------
+ // DO NOT USE!! This is for test purposes ONLY!
+ { MVPD_TEST_KEYWORD, "TEST" },
+ // -------------------------------------------------------------------
+};
+
+
+/**
+ * @brief This function will perform the steps required to do a read from
+ * the Hostboot MVPD data.
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param[in] i_target - Processor Target device
+ *
+ * @param [in/out] io_buffer - Pointer to the data that was read from
+ * the target device. It will also be used to contain data to
+ * be written to the device.
+ *
+ * @param [in/out] io_buflen - Length of the buffer to be read or written
+ * to/from the target. This value should indicate the size of the
+ * io_buffer parameter that has been allocated. Being returned it will
+ * indicate the number of valid bytes in the buffer being returned.
+ *
+ * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+ * usrif.H
+ *
+ * @param [in] i_args - This is an argument list for the device driver
+ * framework.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t mvpdRead ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
+/**
+ * @brief This function will perform the steps required to do a write to
+ * the Hostboot MVPD data.
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param[in] i_target - Processor Target device
+ *
+ * @param [in/out] io_buffer - Pointer to the data that was read from
+ * the target device. It will also be used to contain data to
+ * be written to the device.
+ *
+ * @param [in/out] io_buflen - Length of the buffer to be read or written
+ * to/from the target. This value should indicate the size of the
+ * io_buffer parameter that has been allocated. Being returned it will
+ * indicate the number of valid bytes in the buffer being returned.
+ *
+ * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+ * usrif.H
+ *
+ * @param [in] i_args - This is an argument list for the device driver
+ * framework.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t mvpdWrite ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
+/**
+ * @brief This function actually reads the data from the source of the MVPD
+ * data.
+ *
+ * @param[in] i_byteAddr - The offset to be read.
+ *
+ * @param[in] i_numBytes - The number of bytes to read.
+ *
+ * @param[out] o_data - The data buffer where the data will be placed.
+ *
+ * @param[in] i_target - Processor Target device.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t mvpdFetchData ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target );
+
+/**
+ * @brief This function reads a binary file that contains the MVPD data for
+ * all targets.
+ *
+ * @param[in] i_offset - The offset to read.
+ *
+ * @param[in] i_numBytes - The number of bytes to read.
+ *
+ * @param[out] o_data - The Data buffer where the data will be placed.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t mvpdReadBinaryFile ( uint64_t i_offset,
+ size_t i_numBytes,
+ void * o_data );
+
+/**
+ * @brief This function will translate the enumeration for the MVPD record
+ * into a char * variable to be used for comparing what was read from
+ * the MVPD data.
+ *
+ * @param[in] i_record - The record enumeration.
+ *
+ * @param[out] o_record - The char representation of the record.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdTranslateRecord ( mvpdRecord i_record,
+ const char *& o_record );
+
+/**
+ * @brief This function will translate the enumeration for the MVPD keyword
+ * into a char * variable to be used for comparing what was read from
+ * the MVPD data.
+ *
+ * @param[in] i_keyword - The keyword enumeration.
+ *
+ * @param[out] o_keyword - The char representation of the record.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdTranslateKeyword ( mvpdKeyword i_keyword,
+ const char *& o_keyword );
+
+/**
+ * @brief This function will read the MVPD TOC to find the offset where the
+ * given record is located within the chunk of data.
+ *
+ * @param[in] i_record - String value for the record to look for.
+ *
+ * @param[out] o_offset - The offset where the record is located.
+ *
+ * @param[in] i_target - The target to retrieve the data for.
+ *
+ * @param[in] i_args - The input arguments.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdFindRecordOffset ( const char * i_record,
+ uint16_t & o_offset,
+ TARGETING::Target * i_target,
+ input_args_t i_args );
+
+/**
+ * @brief This function will read the required keyword from the MVPD data.
+ *
+ * @param[in] i_keywordName - String representation of the keyword.
+ *
+ * @param[in] i_recordName - String representation of the record.
+ *
+ * @param[in] i_offset - The offset to start reading.
+ *
+ * @param[in] i_target - The target to retrieve data for.
+ *
+ * @param[out] io_buffer - The buffer to place the data in.
+ *
+ * @param[in/out] io_buflen - Length of the buffer to be read or written
+ * to/from the target. This value should indicate the size of the
+ * io_buffer parameter that has been allocated. Being returned it will
+ * indicate the number of valid bytes in the buffer being returned.
+ *
+ * @param[in] i_args - The input arguments.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdRetrieveKeyword ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ input_args_t i_args );
+
+
+}; // end MVPD namespace
+
+#endif // __MVPD_H
diff --git a/src/usr/mvpd/test/makefile b/src/usr/mvpd/test/makefile
new file mode 100644
index 000000000..8c7f74570
--- /dev/null
+++ b/src/usr/mvpd/test/makefile
@@ -0,0 +1,28 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/mvpd/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012
+#
+# 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
+ROOTPATH = ../../../..
+
+MODULE = testmvpd
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/mvpd/test/mvpdtest.H b/src/usr/mvpd/test/mvpdtest.H
new file mode 100755
index 000000000..6386dabff
--- /dev/null
+++ b/src/usr/mvpd/test/mvpdtest.H
@@ -0,0 +1,727 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/mvpd/test/mvpdtest.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2012
+//
+// 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 __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/predicates/predicatectm.H>
+
+#include <mvpd/mvpdenums.H>
+#include <mvpd/mvpdreasoncodes.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;
+
+ // NOTE: current sizes will be based off of dummy data that we have
+ // now plus approximately 10% as a buffer for future growth. These
+ // may need to be tweaked later.
+ size_t size;
+};
+
+/**
+ * @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, 0x04 },
+ { CRP0, ED, 0x23 },
+ { CRP0, TE, 0x13 },
+ { CRP0, DD, 0x07 },
+ { CRP0, pdP, 0x150 },
+ { CRP0, ST, 0x05 },
+// { CRP0, DN, 0x03 }, // TODO - This doesn't match documentation,
+// pulling out for now
+ { CP00, VD, 0x04 },
+ { CP00, PG, 0x44 },
+ { CP00, PK, 0x45 },
+ { CP00, pdR, 0x5f90 },
+ { CP00, pdV, 0x130 },
+ { CP00, pdH, 0x190 },
+ { CP00, pdP, 0x1c0 },
+ { CP00, SB, 0x15 },
+ { LRP0, VD, 0x04 },
+ { LRP0, pdV, 0x150 },
+ { LRP0, pdP, 0x380 },
+ { LRP0, pdM, 0x220},
+ { LRP1, VD, 0x04 },
+ { LRP1, pdV, 0x150 },
+ { LRP1, pdP, 0x380 },
+ { LRP1, pdM, 0x220},
+ { LRP2, VD, 0x04 },
+ { LRP2, pdV, 0x150 },
+ { LRP2, pdP, 0x380 },
+ { LRP2, pdM, 0x220},
+ { LRP3, VD, 0x04 },
+ { LRP3, pdV, 0x150 },
+ { LRP3, pdP, 0x380 },
+ { LRP3, pdM, 0x220},
+ { LRP4, VD, 0x04 },
+ { LRP4, pdV, 0x150 },
+ { LRP4, pdP, 0x380 },
+ { LRP4, pdM, 0x220},
+ { LRP5, VD, 0x04 },
+ { LRP5, pdV, 0x150 },
+ { LRP5, pdP, 0x380 },
+ { LRP5, pdM, 0x220},
+ { LRP6, VD, 0x04 },
+ { LRP6, pdV, 0x150 },
+ { LRP6, pdP, 0x380 },
+ { LRP6, pdM, 0x220},
+ { LRP7, VD, 0x04 },
+ { LRP7, pdV, 0x150 },
+ { LRP7, pdP, 0x380 },
+ { LRP7, pdM, 0x220},
+ { LRP8, VD, 0x04 },
+ { LRP8, pdV, 0x150 },
+ { LRP8, pdP, 0x380 },
+ { LRP8, pdM, 0x220},
+ { LRP9, VD, 0x04 },
+ { LRP9, pdV, 0x150 },
+ { LRP9, pdP, 0x380 },
+ { LRP9, pdM, 0x220},
+ { LRPA, VD, 0x04 },
+ { LRPA, pdV, 0x150 },
+ { LRPA, pdP, 0x380 },
+ { LRPA, pdM, 0x220},
+ { LRPB, VD, 0x04 },
+ { LRPB, pdV, 0x150 },
+ { LRPB, pdP, 0x380 },
+ { LRPB, pdM, 0x220},
+ { LWP0, VD, 0x04 },
+ { LWP0, pd2, 0x60 },
+ { LWP0, pd3, 0x60 },
+ { LWP0, IN, 0x19 },
+ { LWP1, VD, 0x04 },
+ { LWP1, pd2, 0x60 },
+ { LWP1, pd3, 0x60 },
+ { LWP1, IN, 0x19 },
+ { LWP2, VD, 0x04 },
+ { LWP2, pd2, 0x60 },
+ { LWP2, pd3, 0x60 },
+ { LWP2, IN, 0x19 },
+ { LWP3, VD, 0x04 },
+ { LWP3, pd2, 0x60 },
+ { LWP3, pd3, 0x60 },
+ { LWP3, IN, 0x19 },
+ { LWP4, VD, 0x04 },
+ { LWP4, pd2, 0x60 },
+ { LWP4, pd3, 0x60 },
+ { LWP4, IN, 0x19 },
+ { LWP5, VD, 0x04 },
+ { LWP5, pd2, 0x60 },
+ { LWP5, pd3, 0x60 },
+ { LWP5, IN, 0x19 },
+ { LWP6, VD, 0x04 },
+ { LWP6, pd2, 0x60 },
+ { LWP6, pd3, 0x60 },
+ { LWP6, IN, 0x19 },
+ { LWP7, VD, 0x04 },
+ { LWP7, pd2, 0x60 },
+ { LWP7, pd3, 0x60 },
+ { LWP7, IN, 0x19 },
+ { LWP8, VD, 0x04 },
+ { LWP8, pd2, 0x60 },
+ { LWP8, pd3, 0x60 },
+ { LWP8, IN, 0x19 },
+ { LWP9, VD, 0x04 },
+ { LWP9, pd2, 0x60 },
+ { LWP9, pd3, 0x60 },
+ { LWP9, IN, 0x19 },
+ { LWPA, VD, 0x04 },
+ { LWPA, pd2, 0x60 },
+ { LWPA, pd3, 0x60 },
+ { LWPA, IN, 0x19 },
+ { LWPB, VD, 0x04 },
+ { LWPB, pd2, 0x60 },
+ { LWPB, pd3, 0x60 },
+ { LWPB, IN, 0x19 },
+ { VINI, DR, 0x12 },
+ { VINI, VZ, 0x04 },
+ { VINI, CC, 0x06 },
+ { VINI, CE, 0x03 },
+ { VINI, FN, 0x09 },
+ { VINI, PN, 0x09 },
+ { VINI, SN, 0x0f },
+ { VINI, PR, 0x0a },
+ { VINI, HE, 0x06 },
+ { VINI, CT, 0x06 },
+ { VINI, HW, 0x04 },
+ // 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+
+ 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++ )
+ {
+ theSize = mvpdData[curCmd].size;
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ // Read record/keyword pair
+ cmds++;
+ theRecord = (uint64_t)mvpdData[curCmd].record;
+ theKeyword = (uint64_t)mvpdData[curCmd].keyword;
+ 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",
+ mvpdData[curCmd].record,
+ mvpdData[curCmd].keyword,
+ theSize, curCmd );
+ TS_FAIL( "testMvpdRead() - Failure during MVPD read!" );
+ errlCommit( err,
+ MVPD_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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+
+ 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;
+ }
+ } 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+
+ 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;
+ }
+ } 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+
+ 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;
+ }
+ } 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+
+ 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;
+ }
+ } 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+
+ 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;
+ }
+ } 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!" );
+ }
+
+ // Use the first Proc in the list
+ theTarget = procList[0];
+ uint8_t * theData = NULL;
+ 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;
+ }
+ } 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/spd/spd.C b/src/usr/spd/spd.C
index a421a14b9..3a4147025 100755
--- a/src/usr/spd/spd.C
+++ b/src/usr/spd/spd.C
@@ -30,9 +30,6 @@
// ----------------------------------------------
// Includes
// ----------------------------------------------
-//#include <string.h>
-//#include <sys/time.h>
-
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
@@ -359,7 +356,8 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
tmpKwdData,
compareEntries );
- if( entry == &kwdData[arraySize] )
+ if( ( entry == &kwdData[arraySize] ) ||
+ ( i_keyword != entry->keyword ) )
{
TRACFCOMP( g_trac_spd,
ERR_MRK"No matching keyword entry found!" );
diff --git a/src/usr/spd/test/dimmPrestest.H b/src/usr/spd/test/dimmPrestest.H
index 46dad62c5..624e30786 100755
--- a/src/usr/spd/test/dimmPrestest.H
+++ b/src/usr/spd/test/dimmPrestest.H
@@ -80,42 +80,35 @@ class DIMMPresTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
- {
- cmds++;
- theTarget = dimmList[dimm];
-
- // 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,
- SPD_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.
- }
- }
+ // Test only on first DIMM.
+ cmds++;
+ theTarget = dimmList[0];
+
+ // Check presence
+ err = deviceRead( theTarget,
+ &present,
+ presentSize,
+ DEVICE_PRESENT_ADDRESS() );
if( err )
{
- break;
+ fails++;
+ TS_FAIL( "testDimmPres() - Error returned from DIMM Presence "
+ "Detect call!" );
+ errlCommit( err,
+ SPD_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 );
@@ -156,38 +149,31 @@ class DIMMPresTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
+ // Test on first DIMM only
+ cmds++;
+ theTarget = dimmList[0];
+
+ // Check presence
+ err = deviceRead( theTarget,
+ &present,
+ presentSize,
+ DEVICE_PRESENT_ADDRESS() );
+
+ if( !err )
{
- cmds++;
- theTarget = dimmList[dimm];
-
- // Check presence
- err = deviceRead( theTarget,
- &present,
- presentSize,
- DEVICE_PRESENT_ADDRESS() );
-
- if( !err )
- {
- fails++;
- TS_FAIL( "testDimmPresInvalidSize() - Error not flagged for "
- "invalid size!" );
- errlCommit( err,
- SPD_COMP_ID );
- continue;
- }
- else
- {
- // Delete the error and continue
- delete err;
- err = NULL;
- continue;
- }
+ fails++;
+ TS_FAIL( "testDimmPresInvalidSize() - Error not flagged for "
+ "invalid size!" );
+ errlCommit( err,
+ SPD_COMP_ID );
+ continue;
}
-
- if( err )
+ else
{
- break;
+ // Delete the error and continue
+ delete err;
+ err = NULL;
+ continue;
}
} while( 0 );
diff --git a/src/usr/spd/test/spdtest.H b/src/usr/spd/test/spdtest.H
index 9080f41a2..b8105592e 100755
--- a/src/usr/spd/test/spdtest.H
+++ b/src/usr/spd/test/spdtest.H
@@ -101,104 +101,97 @@ class SPDTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
+ // Operate on first DIMM.
+ theTarget = dimmList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
+ uint32_t entry = 0x0;
+
+ // Get the DDR revision
+ uint8_t memType = 0x0;
+ size_t memTypeSize = 0x1;
+ err = deviceRead( theTarget,
+ &memType,
+ memTypeSize,
+ DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+
+ if( err )
{
- theTarget = dimmList[dimm];
- uint8_t * theData = NULL;
- size_t theSize = 0;
- uint32_t entry = 0x0;
-
- // Get the DDR revision
- uint8_t memType = 0x0;
- size_t memTypeSize = 0x1;
- err = deviceRead( theTarget,
- &memType,
- memTypeSize,
- DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+ fails++;
+ TS_FAIL( "testSpdRead- Failure reading Basic memory type!" );
+ errlCommit( err,
+ SPD_COMP_ID );
+ continue;
+ }
- if( err )
+ for( uint64_t keyword = SPD::SPD_FIRST_KEYWORD;
+ keyword < SPD::SPD_LAST_KEYWORD; keyword++ )
+ {
+ cmds++;
+ if( NULL != theData )
{
- fails++;
- TS_FAIL( "testSpdRead- Failure reading Basic memory type!" );
- errlCommit( err,
- SPD_COMP_ID );
- continue;
+ free( theData );
+ theData = NULL;
}
- for( uint64_t keyword = SPD::SPD_FIRST_KEYWORD;
- keyword < SPD::SPD_LAST_KEYWORD; keyword++ )
+ // Get the required size of the buffer
+ theSize = 0;
+ if( SPD_DDR3 == memType )
{
- cmds++;
- if( NULL != theData )
+ for( entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
{
- 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 )
{
- if( keyword == ddr3Data[entry].keyword )
- {
- theSize = ddr3Data[entry].length;
- break;
- }
+ 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 ));
+ }
+ else
+ {
+ // Nothing else supported yet!
+ // Not really a fail, just not supported
+ cmds--;
+ continue;
+ }
- err = deviceRead( theTarget,
- theData,
- theSize,
- DEVICE_SPD_ADDRESS( keyword ) );
+ if( 0x0 == theSize )
+ {
+ fails++;
+ TS_FAIL( "testSpdRead - Keyword (0x%04x) size = 0x0",
+ entry );
+ continue;
+ }
- if( err )
- {
- fails++;
- TS_FAIL( "testSpdRead - Failure on keyword: %04x",
- keyword );
- errlCommit( err,
- SPD_COMP_ID );
- continue;
- }
+ // Allocate the buffer
+ theData = static_cast<uint8_t*>(malloc( theSize ));
- // Read was successful, print out first 2 bytes of data read
- TRACFCOMP( g_trac_spd,
- "testSpdRead - kwd: 0x%04x, val: %02x%02x, size: %d",
- keyword, theData[0], theData[1], theSize );
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( keyword ) );
- if( NULL != theData )
- {
- free( theData );
- theData = NULL;
- }
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdRead - Failure on keyword: %04x",
+ keyword );
+ errlCommit( err,
+ SPD_COMP_ID );
+ continue;
}
- if( err )
+ // Read was successful, print out first 2 bytes of data read
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: %02x%02x, size: %d",
+ keyword, theData[0], theData[1], theSize );
+
+ if( NULL != theData )
{
- break;
+ free( theData );
+ theData = NULL;
}
}
@@ -241,35 +234,28 @@ class SPDTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
- {
- theTarget = dimmList[dimm];
- uint8_t * theData = NULL;
- size_t theSize = 0;
+ // Operate on first DIMM
+ theTarget = dimmList[0];
+ uint8_t * theData = NULL;
+ size_t theSize = 0;
- cmds++;
- err = deviceWrite( theTarget,
- theData,
- theSize,
- DEVICE_SPD_ADDRESS( SPD_FIRST_KEYWORD ) );
+ cmds++;
+ err = deviceWrite( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD_FIRST_KEYWORD ) );
- if( NULL == err )
- {
- // No error returned, failure
- fails++;
- TS_FAIL( "testSpdWrite - No error returned from deviceWrite()" );
- continue;
- }
- else
- {
- delete err;
- err = NULL;
- }
+ if( NULL == err )
+ {
+ // No error returned, failure
+ fails++;
+ TS_FAIL( "testSpdWrite - No error returned from deviceWrite()" );
+ continue;
}
-
- if( err )
+ else
{
- break;
+ delete err;
+ err = NULL;
}
} while( 0 );
@@ -306,34 +292,27 @@ class SPDTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
- {
- theTarget = dimmList[dimm];
- uint8_t * theData = NULL;
- size_t theSize = 0x0;
+ // 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::SPD_LAST_KEYWORD ) );
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::SPD_LAST_KEYWORD ) );
- if( NULL == err )
- {
- fails++;
- TS_FAIL( "testSpdInvalidKeyword - No error returned!" );
- continue;
- }
- else
- {
- delete err;
- err = NULL;
- }
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testSpdInvalidKeyword - No error returned!" );
+ continue;
}
-
- if( err )
+ else
{
- break;
+ delete err;
+ err = NULL;
}
} while( 0 );
@@ -370,34 +349,27 @@ class SPDTest: public CxxTest::TestSuite
break;
}
- for( uint32_t dimm = 0; dimm < dimmList.size(); dimm++ )
- {
- theTarget = dimmList[dimm];
- uint8_t * theData = NULL;
- size_t theSize = 0x0; // Invalid size of 0x0
+ // 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_KEYWORD ) );
+ cmds++;
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::SPD_FIRST_KEYWORD ) );
- if( NULL == err )
- {
- fails++;
- TS_FAIL( "testSpdInvalidSize - No error for invalid size!" );
- continue;
- }
- else
- {
- delete err;
- err = NULL;
- }
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "testSpdInvalidSize - No error for invalid size!" );
+ continue;
}
-
- if( err )
+ else
{
- break;
+ delete err;
+ err = NULL;
}
} while( 0 );
OpenPOWER on IntegriCloud