From ade5f3e69bf455b78e10da68c0ac0d2d5fdb1f6c Mon Sep 17 00:00:00 2001 From: "Terry J. Opie" Date: Wed, 7 Mar 2012 13:39:53 -0600 Subject: MVPD Device Driver - MVPD test cases - Add temp binary image file - Adjust SPD/DIMM Pres Detect tests to operate on 1 DIMM. Change-Id: Iaaacd4787ba8e8a8d74f3c427507d98a5f0b218c RTC: 35329 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/777 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- img/.gitignore | 1 + src/include/usr/devicefw/userif.H | 11 + src/include/usr/hbotcompid.H | 18 +- src/include/usr/mvpd/mvpdenums.H | 124 +++ src/include/usr/mvpd/mvpdreasoncodes.H | 79 ++ src/makefile | 10 +- src/usr/initservice/extinitsvc/extinitsvctasks.H | 12 + src/usr/makefile | 2 +- src/usr/mvpd/makefile | 32 + src/usr/mvpd/mvpd.C | 940 +++++++++++++++++++++++ src/usr/mvpd/mvpd.H | 366 +++++++++ src/usr/mvpd/test/makefile | 28 + src/usr/mvpd/test/mvpdtest.H | 727 ++++++++++++++++++ src/usr/spd/spd.C | 6 +- src/usr/spd/test/dimmPrestest.H | 110 ++- src/usr/spd/test/spdtest.H | 280 +++---- 16 files changed, 2516 insertions(+), 230 deletions(-) create mode 100644 src/include/usr/mvpd/mvpdenums.H create mode 100644 src/include/usr/mvpd/mvpdreasoncodes.H create mode 100644 src/usr/mvpd/makefile create mode 100755 src/usr/mvpd/mvpd.C create mode 100755 src/usr/mvpd/mvpd.H create mode 100644 src/usr/mvpd/test/makefile create mode 100755 src/usr/mvpd/test/mvpdtest.H 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, }; @@ -96,6 +97,16 @@ namespace DeviceFW #define DEVICE_MBOX_ADDRESS(o_status) \ DeviceFW::MAILBOX, static_cast((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(( i_record )),\ + static_cast(( i_keyword )) + /** * @brief Perform a hardware read operation. * 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 + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * @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 + * @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 + +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 + +#include +#include +#include +#include +#include + +#include +#include +#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(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 -//#include - #include #include #include @@ -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(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(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 ); -- cgit v1.2.1