summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-01-09 12:48:13 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-02-06 14:18:33 -0600
commit7696bed6681d260f46d6878b5201560ed78715af (patch)
tree1731e489e444856d0644b17c0b39946988c3f512 /src/usr
parent1ee9befb99004f26dcc81af879ce14907d405ad8 (diff)
downloadtalos-hostboot-7696bed6681d260f46d6878b5201560ed78715af.tar.gz
talos-hostboot-7696bed6681d260f46d6878b5201560ed78715af.zip
Enable MVPD Writes
Add support for writing MVPD keywords to both PNOR and out to the EEPROM (via FSP mailbox). Also enabled a few more test cases related to MVPD. Added MER0 record to the standalone procmvpd.dat file and enabled the support in the code. Change-Id: If16c2863a11daaac3363fcf30bb2c92ad3e92b41 RTC: 39177 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2962 Tested-by: Jenkins Server Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C62
-rw-r--r--src/usr/hwpf/test/fapiwinkletest.H445
-rw-r--r--src/usr/vpd/makefile5
-rwxr-xr-xsrc/usr/vpd/mvpd.C614
-rwxr-xr-xsrc/usr/vpd/mvpd.H67
-rwxr-xr-xsrc/usr/vpd/spd.C117
-rwxr-xr-xsrc/usr/vpd/spd.H2
-rwxr-xr-xsrc/usr/vpd/test/mvpdtest.H186
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H277
-rw-r--r--src/usr/vpd/vpd.C6
10 files changed, 1303 insertions, 478 deletions
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C b/src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C
index 47b1e4c65..7c94e1cd3 100644
--- a/src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C
+++ b/src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C
@@ -1,26 +1,25 @@
- /* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/mvpdRingFuncs.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_TAG
- */
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mvpd_accessors/mvpdRingFuncs.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
/**
* @file mvpdRingFuncs.C
*
@@ -273,16 +272,6 @@ fapi::ReturnCode mvpdRingFunc( const mvpdRingFuncOp i_mvpdRingFuncOp,
i_fapiTarget,
l_recordBuf,
l_recordLen );
-#if 0 // TODO remove once DD supports write RTC 39177,enable for unit test
- if (l_fapirc == FAPI_RC_PLAT_ERR_SEE_DATA)
- {
- FAPI_DBG( "mvpdRingFunc: Fake that fapiSetMvpdField worked" );
- TRACDBIN( g_fapiImpTd, "mvpdRingFunc: Dump Ring Buffer:",
- l_recordBuf,
- 0x100 );
- l_fapirc=FAPI_RC_SUCCESS;
- }
-#endif // RTC 39177
if ( l_fapirc )
{
FAPI_ERR("mvpdRingFunc: fapiSetMvpdField failed");
@@ -374,20 +363,21 @@ fapi::ReturnCode mvpdRingFuncFind( const uint8_t i_chipletId,
break;
}
// dump record info for debug
- FAPI_DBG("mvpdRingFuncFind:%d ringId=0x%x chipletId=0x%x size=0x%x",
+ FAPI_DBG("mvpdRingFuncFind:%d ringId=0x%x chipletId=0x%x ringlen=0x%x size=0x%x",
l_offset,
l_pScanData->iv_ringId,
l_pScanData->iv_chipletId,
+ FAPI_BE32TOH(l_pScanData->iv_length),
FAPI_BE32TOH(l_pScanData->iv_size) );
if ( (l_pScanData->iv_ringId == i_ringId)
&& (l_pScanData->iv_chipletId == i_chipletId) )
{
- FAPI_DBG( "mvpdRingFuncFind: Found it: 0x%x.0x%x, 0x%x",
+ FAPI_DBG( "mvpdRingFuncFind: Found it: ring=0x%x, chiplet=0x%x, ringlen=0x%x",
i_ringId,
i_chipletId,
- FAPI_BE32TOH(l_pScanData->iv_size) );
+ FAPI_BE32TOH(l_pScanData->iv_length) );
if (l_offset+FAPI_BE32TOH(l_pScanData->iv_size)>i_recordBufLen)
{
diff --git a/src/usr/hwpf/test/fapiwinkletest.H b/src/usr/hwpf/test/fapiwinkletest.H
index 5ab22fcca..6ada8741f 100644
--- a/src/usr/hwpf/test/fapiwinkletest.H
+++ b/src/usr/hwpf/test/fapiwinkletest.H
@@ -26,7 +26,6 @@
// set to 1 for doing unit tests, set to 0 for production
#define RTC51716 0
-#define RTC39177 0
/**
* @file fapiwinkletest.H
*
@@ -45,6 +44,11 @@
#include <getMvpdRing.H>
#include <setMvpdRing.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <trace/interface.H>
+
// pull in CompressedScanData def from proc_slw_build HWP
#include <p8_scan_compression.H>
@@ -134,9 +138,14 @@ public:
TS_TRACE( "testGetMvpdPdr exit" );
}
- // @note:
- // ring modifiers are from MVPD #R record, 2012-05-22.
- // This will change and the unit test will need to be changed...
+ // Structure used to save/restore the VPD
+ typedef struct saveRestoreData_t {
+ TARGETING::Target* target;
+ uint8_t* CP00_pdG;
+ size_t CP00_pdG_size;
+ uint8_t* CP00_pdR;
+ size_t CP00_pdR_size;
+ } saveRestoreData_t;
/**
* @brief Fetch Repair Rings
@@ -149,25 +158,36 @@ public:
uint32_t l_ringId = 0;
uint32_t l_chipletId = 0;
uint32_t l_bufsize = 0x200;
-#if RTC51716 // TODO comment out until mvpd test data is fixed. RTC 51716
+ errlHndl_t l_errhdl = NULL;
+
// This data needs to be in sync with the procmvpd.dat file
- // the setMvpdFunc tests use the last row, index = 3. The test
+ // the setMvpdFunc tests use the last row. The test
// expects it to be a mid x20 byte ring in the #G keyword
struct _testRRstr {
- fapi::MvpdRecord record;
fapi::MvpdKeyword keyword;
uint32_t ringIdval;
uint32_t chipletIdval;
uint32_t size;
+ uint32_t rc;
} l_ringModifiers[] = {
- { MVPD_RECORD_CP00, MVPD_KEYWORD_PDG,0xa4, 0xFF , 0x20 }, //last #G
- { MVPD_RECORD_CP00, MVPD_KEYWORD_PDR,0xe0, 0x8 , 0x20 },//first #R
- { MVPD_RECORD_CP00, MVPD_KEYWORD_PDR,0xe2, 0x16 ,0x138 },//big #R
- { MVPD_RECORD_CP00, MVPD_KEYWORD_PDG,0xa2, 0x8 , 0x20 }, //mid #G
+ { MVPD_KEYWORD_PDG, 0xa4, 0xFF, 0x20, //last #G
+ fapi::RC_REPAIR_RING_NOT_FOUND },
+ { MVPD_KEYWORD_PDR, 0xe0, 0x08, 0x20, //first #R
+ FAPI_RC_SUCCESS },
+ { MVPD_KEYWORD_PDR, 0xe2, 0x16, 0x20, //big #R
+ FAPI_RC_SUCCESS },
+ { MVPD_KEYWORD_PDG, 0xa2, 0x08, 0x20, //mid #G
+ FAPI_RC_SUCCESS },
+ { MVPD_KEYWORD_PDR, 0xe1, 0x16, 0x20,//big #R
+ FAPI_RC_SUCCESS },
};
-#endif // RTC 51716
+ const size_t VALID_INDEX = 2;
+ const size_t TEST_INDEX = 4;
+
TS_TRACE( "testRepairRings entry" );
+ std::list<saveRestoreData_t> l_srData;
+
TARGETING::TargetHandleList l_cpuTargetList;
getAllChips(l_cpuTargetList, TYPE_PROC);
@@ -183,6 +203,76 @@ public:
"target HUID %.8X",
TARGETING::get_huid(l_cpu_target));
+ //-- Save the entire VPD record to restore later
+ saveRestoreData_t tmpsave;
+ tmpsave.target = l_cpu_target;
+
+ // do a read with NULL buffer to get the record size
+ l_errhdl = deviceRead( l_cpu_target,
+ NULL,
+ tmpsave.CP00_pdG_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDG ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error finding size of CP00/#G for %.8X",
+ TARGETING::get_huid(l_cpu_target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ continue;
+ }
+
+ // now go get the data
+ tmpsave.CP00_pdG = new uint8_t[tmpsave.CP00_pdG_size];
+ l_errhdl = deviceRead( l_cpu_target,
+ tmpsave.CP00_pdG,
+ tmpsave.CP00_pdG_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDG ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error reading CP00/#G from %.8X",
+ TARGETING::get_huid(l_cpu_target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ delete[] tmpsave.CP00_pdG;
+ continue;
+ }
+
+ // do a read with NULL buffer to get the record size
+ l_errhdl = deviceRead( l_cpu_target,
+ NULL,
+ tmpsave.CP00_pdR_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDR ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error finding size of CP00/#R for %.8X",
+ TARGETING::get_huid(l_cpu_target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ continue;
+ }
+
+ // now go get the data
+ tmpsave.CP00_pdR = new uint8_t[tmpsave.CP00_pdR_size];
+ l_errhdl = deviceRead( l_cpu_target,
+ tmpsave.CP00_pdR,
+ tmpsave.CP00_pdR_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDR ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error reading CP00/#R from %.8X",
+ TARGETING::get_huid(l_cpu_target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ delete[] tmpsave.CP00_pdR;
+ continue;
+ }
+
+ // add to the master list
+ l_srData.push_back(tmpsave);
+
+ //--
+
+
// cast OUR type of target to a FAPI type of target.
fapi::Target l_fapi_cpu_target(
TARGET_TYPE_PROC_CHIP,
@@ -190,7 +280,11 @@ public:
(const_cast<TARGETING::Target*>(l_cpu_target)) );
// allocate some space to put the record(s)
- l_pRingBuf = new uint8_t[ l_bufsize];
+ if( l_pRingBuf != NULL )
+ {
+ delete[] l_pRingBuf;
+ }
+ l_pRingBuf = new uint8_t[l_bufsize];
// ----------------------------------------------------------------
// Pass in 0 for the ring modifier, should return with "not found"
@@ -218,20 +312,17 @@ public:
fapi::RC_REPAIR_RING_NOT_FOUND,
static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
-#if RTC51716 // TODO comment out until mvpd test data is fixed. RTC 51716
- uint8_t i = 2;
// ----------------------------------------------------------------
// Pass in a buffer size that is too small with a valid
- // ringId/chipletId, should return with correct length
- // and invalid size return code.
+ // ringId/chipletId, should return error with correct length
+ // and invalid size return code..
// ----------------------------------------------------------------
TS_TRACE( "testRepairRings: pass buffer too small %d ", i );
l_ringBufsize = 0x0;
- l_ringId = l_ringModifiers[i].ringIdval;
- l_chipletId = l_ringModifiers[i].chipletIdval;
+ l_ringId = l_ringModifiers[VALID_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[VALID_INDEX].chipletIdval;
l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
MVPD_KEYWORD_PDR,
l_fapi_cpu_target,
@@ -246,28 +337,29 @@ public:
if ( l_fapirc != fapi::RC_REPAIR_RING_INVALID_SIZE )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL("testRepairRings: expect invalid size FAIL: 0x%x, 0x%x",
+ TS_FAIL("testRepairRings: expect invalid size FAIL: exp=0x%x, act=0x%x, ring=0x%X",
fapi::RC_REPAIR_RING_INVALID_SIZE,
- static_cast<uint32_t>(l_fapirc));
+ static_cast<uint32_t>(l_fapirc),
+ l_ringId);
fapiLogError(l_fapirc);
- return;
}
- if ( l_ringBufsize != l_ringModifiers[i].size )
+ else if ( l_ringBufsize != l_ringModifiers[VALID_INDEX].size )
{
- TS_FAIL( "testRepairRings: size mismatch FAIL: 0x%x, 0x%x",
- l_ringModifiers[i].size,
+ TS_FAIL( "testRepairRings: size mismatch FAIL1 on ring 0x%X: exp=0x%x, act=0x%x",
+ l_ringId,
+ l_ringModifiers[VALID_INDEX].size,
l_ringBufsize );
- return;
}
+
// ----------------------------------------------------------------
// Pass in a NULL pointer with a valid ringId/chipletId, should
// return with correct length and successful return code.
// ----------------------------------------------------------------
TS_TRACE( "testRepairRings: get size of ring %d ", i );
l_ringBufsize = 0x0;
- l_ringId = l_ringModifiers[i].ringIdval;
- l_chipletId = l_ringModifiers[i].chipletIdval;
+ l_ringId = l_ringModifiers[VALID_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[VALID_INDEX].chipletIdval;
l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
MVPD_KEYWORD_PDR,
l_fapi_cpu_target,
@@ -287,14 +379,13 @@ public:
static_cast<uint32_t>(l_fapirc));
fapiLogError(l_fapirc);
- return;
}
- if ( l_ringBufsize != l_ringModifiers[i].size )
+ else if ( l_ringBufsize != l_ringModifiers[VALID_INDEX].size )
{
- TS_FAIL( "testRepairRings: size mismatch FAIL: 0x%x, 0x%x",
- l_ringModifiers[i].size,
+ TS_FAIL( "testRepairRings: size mismatch FAIL2 on ring 0x%X: exp=0x%x, act=0x%x",
+ l_ringId,
+ l_ringModifiers[VALID_INDEX].size,
l_ringBufsize );
- return;
}
// ----------------------------------------------------------------
@@ -302,12 +393,13 @@ public:
// ----------------------------------------------------------------
const uint32_t numRings =
sizeof(l_ringModifiers)/sizeof(l_ringModifiers[0]);
- for (i=0;i<numRings;i++) {
+ for (size_t i=0;i<numRings;i++)
+ {
TS_TRACE( "testRepairRings: get ring %d", i );
l_ringBufsize = l_bufsize;
l_ringId = l_ringModifiers[i].ringIdval;
l_chipletId = l_ringModifiers[i].chipletIdval;
- l_fapirc = getMvpdRing( l_ringModifiers[i].record,
+ l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
l_ringModifiers[i].keyword,
l_fapi_cpu_target,
l_chipletId,
@@ -317,21 +409,29 @@ public:
TS_TRACE("testRepairRings ringId=0x%x chipletId=0x%x size=0x%x",
l_ringId, l_chipletId, l_ringBufsize );
- if ( l_fapirc )
+ if ( l_fapirc != l_ringModifiers[i].rc )
{
// note: uint32_t below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: getMvpdRing rc FAIL: 0x%x, 0x%x",
- fapi::FAPI_RC_SUCCESS,
- static_cast<uint32_t>(l_fapirc) );
+ TS_FAIL( "testRepairRings: getMvpdRing rc FAIL 1: rc=0x%x, ring=0x%X, chiplet=0x%X, i=%d",
+ static_cast<uint32_t>(l_fapirc),
+ l_ringId,
+ l_chipletId,
+ i );
fapiLogError(l_fapirc);
- return;
+ continue;
}
+ else if( l_fapirc != fapi::FAPI_RC_SUCCESS )
+ {
+ // not an error, but the next check isn't valid
+ continue;
+ }
+
if ( l_ringBufsize != l_ringModifiers[i].size )
{
- TS_FAIL( "testRepairRings: size mismatch FAIL: 0x%x, 0x%x",
- l_ringModifiers[i].size,
- l_ringBufsize );
- return;
+ TS_FAIL( "testRepairRings: size mismatch FAIL3 on ring %X: exp=0x%x, act=0x%x",
+ l_ringId,
+ l_ringModifiers[i].size,
+ l_ringBufsize );
}
// Dump ring buffer here.
@@ -339,25 +439,20 @@ public:
l_pRingBuf,
l_ringBufsize );
}
-#endif // RTC 51716
-#if RTC39177 // TODO comment out til mvpd dd supports write. RTC 39177
// ----------------------------------------------------------------
- // update the data.
- // TODO write different data, once the DD is written(story 39177)
- // read it back to verify, then put the original data back.
- // for now, there is a debug byte dump in mvpdRingFunc to
- // manually verify in unit test
+ // write different data, read it back to verify, then put the
+ // original data back.
// ----------------------------------------------------------------
uint32_t l_offset =0;
uint8_t l_data = 0;
uint8_t *l_pData = NULL;
- i = 3; // use data from last fetch test case.
- TS_TRACE( "testRepairRings: update in place ring %d", i );
- l_ringId = l_ringModifiers[i].ringIdval;
- l_chipletId = l_ringModifiers[i].chipletIdval;
- l_ringBufsize = l_ringModifiers[i].size;
+ // use data from last fetch test case.
+ TS_TRACE( "testRepairRings: update in place ring %d", TEST_INDEX );
+ l_ringId = l_ringModifiers[TEST_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[TEST_INDEX].chipletIdval;
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size;
// put in recognizable data for the debug data dump
l_pData = l_pRingBuf+sizeof(CompressedScanData);
@@ -369,8 +464,8 @@ public:
TRACDBIN( g_trac_test, "testRepairRings: updated ring data:",
l_pRingBuf,
l_ringBufsize );
- l_fapirc = setMvpdRing( l_ringModifiers[i].record,
- l_ringModifiers[i].keyword,
+ l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
l_fapi_cpu_target,
l_chipletId,
l_ringId,
@@ -380,19 +475,17 @@ public:
if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: setMvpdRing rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: setMvpdRing rc FAIL 1: exp=0x%x, rc=0x%x",
fapi::FAPI_RC_SUCCESS,
- static_cast<uint32_t>(l_fapirc) );
-
+ static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
// ----------------------------------------------------------------
// write back a smaller ring to cause a shift left in the record
// ----------------------------------------------------------------
- TS_TRACE( "testRepairRings: shrink a ring %d", i );
- l_ringBufsize = l_ringModifiers[i].size-4;
+ TS_TRACE( "testRepairRings: shrink a ring %d", TEST_INDEX );
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size-4;
reinterpret_cast<CompressedScanData *>(l_pRingBuf)->
iv_size = l_ringBufsize;
@@ -406,8 +499,8 @@ public:
TRACDBIN( g_trac_test, "testRepairRings: updated ring data:",
l_pRingBuf,
l_ringBufsize );
- l_fapirc = setMvpdRing( l_ringModifiers[i].record,
- l_ringModifiers[i].keyword,
+ l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
l_fapi_cpu_target,
l_chipletId,
l_ringId,
@@ -417,19 +510,18 @@ public:
if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: setMvpdRing rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: setMvpdRing rc FAIL 2: exp=0x%x, rc=0x%x",
fapi::FAPI_RC_SUCCESS,
static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
// ----------------------------------------------------------------
// write back a larger ring to cause a shift right in the record
// ----------------------------------------------------------------
- TS_TRACE( "testRepairRings: grow a ring %d", i );
- l_ringBufsize = l_ringModifiers[i].size+16;
+ TS_TRACE( "testRepairRings: grow a ring %d", TEST_INDEX );
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size+16;
reinterpret_cast<CompressedScanData *>(l_pRingBuf)->
iv_size = l_ringBufsize;
@@ -443,8 +535,8 @@ public:
TRACDBIN( g_trac_test, "testRepairRings: updated ring data:",
l_pRingBuf,
l_ringBufsize );
- l_fapirc = setMvpdRing( l_ringModifiers[i].record,
- l_ringModifiers[i].keyword,
+ l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
l_fapi_cpu_target,
l_chipletId,
l_ringId,
@@ -454,12 +546,11 @@ public:
if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: setMvpdRing rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: setMvpdRing rc FAIL 3: exp=0x%x, rc=0x%x",
fapi::FAPI_RC_SUCCESS,
static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
// ----------------------------------------------------------------
@@ -468,7 +559,7 @@ public:
TS_TRACE( "testRepairRings: append a ring" );
l_ringId = 0x77;
l_chipletId = 0x88;
- l_ringBufsize = l_ringModifiers[i].size;
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size;
reinterpret_cast<CompressedScanData *>(l_pRingBuf)->
iv_size = l_ringBufsize;
reinterpret_cast<CompressedScanData *>(l_pRingBuf)->
@@ -486,8 +577,8 @@ public:
TRACDBIN( g_trac_test, "testRepairRings: updated ring data:",
l_pRingBuf,
l_ringBufsize );
- l_fapirc = setMvpdRing( l_ringModifiers[i].record,
- l_ringModifiers[i].keyword,
+ l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
l_fapi_cpu_target,
l_chipletId,
l_ringId,
@@ -497,14 +588,88 @@ public:
if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: setMvpdRing rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: setMvpdRing rc FAIL 4: exp=0x%x, rc=0x%x",
fapi::FAPI_RC_SUCCESS,
static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
+ // read back data to prove the writes worked
+ l_ringId = l_ringModifiers[TEST_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[TEST_INDEX].chipletIdval;
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size+16;
+ l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
+ l_fapi_cpu_target,
+ l_chipletId,
+ l_ringId,
+ l_pRingBuf,
+ l_ringBufsize );
+
+ if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
+ {
+ TS_FAIL( "testRepairRings: getMvpdRing rc FAIL 2: 0x%x, 0x%x",
+ fapi::FAPI_RC_SUCCESS,
+ static_cast<uint32_t>(l_fapirc) );
+ fapiLogError(l_fapirc);
+ }
+ else
+ {
+ l_pData = l_pRingBuf+sizeof(CompressedScanData);
+ for( l_offset = 0,l_data=0x30;
+ l_offset < l_ringBufsize-sizeof(CompressedScanData);
+ l_offset++)
+ {
+ if( l_pData[l_offset] != l_data++ )
+ {
+ TS_FAIL("Mismatch after write on ring %X",
+ l_ringId);
+ TRACFBIN(g_trac_test,
+ "ringdata=",
+ l_pRingBuf,l_ringBufsize);
+ }
+ }
+ }
+
+ // read back data to prove the writes worked
+ l_ringId = 0x77;
+ l_chipletId = 0x88;
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size;
+ l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
+ l_ringModifiers[TEST_INDEX].keyword,
+ l_fapi_cpu_target,
+ l_chipletId,
+ l_ringId,
+ l_pRingBuf,
+ l_ringBufsize );
+
+ if ( l_fapirc != fapi::FAPI_RC_SUCCESS )
+ {
+ TS_FAIL( "testRepairRings: getMvpdRing rc FAIL 3: 0x%x, 0x%x",
+ fapi::FAPI_RC_SUCCESS,
+ static_cast<uint32_t>(l_fapirc) );
+ fapiLogError(l_fapirc);
+ }
+ else
+ {
+ l_pData = l_pRingBuf+sizeof(CompressedScanData);
+ for (l_offset = 0,l_data=0x50;
+ l_offset < l_ringBufsize-sizeof(CompressedScanData);
+ l_offset++)
+ {
+ if( l_pData[l_offset] != l_data++ )
+ {
+ TS_FAIL("Mismatch after write on ring %X",
+ l_ringId);
+ TRACFBIN(g_trac_test,
+ "ringdata=",
+ l_pRingBuf,l_ringBufsize);
+ }
+ }
+ }
+
+
// ----------------------------------------------------------------
// Pass in a buffer size that does not match the exact size
// of the ringId/chipletId, should return with correct length
@@ -515,8 +680,8 @@ public:
l_chipletId,
l_ringBufsize );
l_ringBufsize = l_bufsize;
- l_ringId = l_ringModifiers[i].ringIdval;
- l_chipletId = l_ringModifiers[i].chipletIdval;
+ l_ringId = l_ringModifiers[TEST_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[TEST_INDEX].chipletIdval;
l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
MVPD_KEYWORD_PDR,
l_fapi_cpu_target,
@@ -528,19 +693,19 @@ public:
if ( l_fapirc != fapi::RC_MVPD_RING_FUNC_INVALID_PARAMETER )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL("testRepairRings:invalid ring size rc FAIL: 0x%x, 0x%x",
+ TS_FAIL("testRepairRings:invalid ring size rc FAIL: exp=0x%x, act=0x%x",
fapi::RC_REPAIR_RING_INVALID_SIZE,
static_cast<uint32_t>(l_fapirc));
fapiLogError(l_fapirc);
- return;
}
+
// ----------------------------------------------------------------
// Pass in 0 for the ring modifier, should return with "not found"
// error
// ----------------------------------------------------------------
TS_TRACE( "testRepairRings: pass in invalid ringId" );
- l_ringBufsize = l_ringModifiers[i].size;
+ l_ringBufsize = l_ringModifiers[TEST_INDEX].size;
l_ringId = 0; // ringId
l_chipletId = 0; // chipletId
l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
@@ -558,20 +723,19 @@ public:
if ( l_fapirc != fapi::RC_MVPD_RING_FUNC_INVALID_PARAMETER )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: rc FAIL: exp=0x%x, act=0x%x",
fapi::RC_REPAIR_RING_NOT_FOUND,
static_cast<uint32_t>(l_fapirc) );
fapiLogError(l_fapirc);
- return;
}
// ----------------------------------------------------------------
// Pass in a NULL pointer with a valid ringId/chipletId, should
// return with correct length and successful return code.
// ----------------------------------------------------------------
- TS_TRACE( "testRepairRings: get size of ring(from set) %d ", i );
+ TS_TRACE( "testRepairRings: get size of ring(from set) %d ", TEST_INDEX );
l_ringBufsize = 0x0;
- l_ringId = l_ringModifiers[i].ringIdval;
- l_chipletId = l_ringModifiers[i].chipletIdval;
+ l_ringId = l_ringModifiers[TEST_INDEX].ringIdval;
+ l_chipletId = l_ringModifiers[TEST_INDEX].chipletIdval;
l_fapirc = setMvpdRing( MVPD_RECORD_CP00,
MVPD_KEYWORD_PDR,
l_fapi_cpu_target,
@@ -587,17 +751,110 @@ public:
if ( l_fapirc != fapi::RC_MVPD_RING_FUNC_INVALID_PARAMETER )
{
// note: "uint32_t" below is an _operator_ of fapi::ReturnCode
- TS_FAIL( "testRepairRings: setMvpdRing rc FAIL: 0x%x, 0x%x",
+ TS_FAIL( "testRepairRings: setMvpdRing rc FAIL 5: exp=0x%x, act=0x%x",
fapi::RC_MVPD_RING_FUNC_INVALID_PARAMETER,
static_cast<uint32_t>(l_fapirc));
fapiLogError(l_fapirc);
- return;
}
-#endif // RTC 39177
- // delete allocated space
+
+ // ----------------------------------------------------------------
+ // Pass in an invalid chiplet id with a valid ring, should fail
+ // ----------------------------------------------------------------
+ l_ringBufsize = l_bufsize;
+ l_ringId = l_ringModifiers[TEST_INDEX].ringIdval;
+ l_chipletId = 0x22;
+ TS_TRACE("testRepairRing:invalid chiplet ring=0x%X chiplet=0x%X size=0x%x",
+ l_ringId,
+ l_chipletId,
+ l_ringBufsize );
+ l_fapirc = getMvpdRing( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDR,
+ l_fapi_cpu_target,
+ l_chipletId,
+ l_ringId,
+ l_pRingBuf,
+ l_ringBufsize );
+
+ if ( l_fapirc != fapi::RC_REPAIR_RING_NOT_FOUND )
+ {
+ // note: "uint32_t" below is an _operator_ of fapi::ReturnCode
+ TS_FAIL("testRepairRings:invalid chipletid rc FAIL: exp=0x%x, act=0x%x",
+ fapi::RC_REPAIR_RING_NOT_FOUND,
+ static_cast<uint32_t>(l_fapirc));
+
+ fapiLogError(l_fapirc);
+ }
+
+ }
+
+ //-- Put the original data back into the vpd
+ for( std::list<saveRestoreData_t>::iterator sv = l_srData.begin();
+ sv != l_srData.end();
+ ++sv )
+ {
+ if( sv->target == NULL )
+ {
+ continue;
+ }
+
+ if( sv->CP00_pdG != NULL )
+ {
+ l_errhdl = deviceWrite( sv->target,
+ sv->CP00_pdG,
+ sv->CP00_pdG_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDG ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error restoring CP00/#G to %.8X",
+ TARGETING::get_huid(sv->target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ }
+ delete[] sv->CP00_pdG;
+ sv->CP00_pdG = NULL;
+ }
+
+ if( sv->CP00_pdR != NULL )
+ {
+ l_errhdl = deviceWrite( sv->target,
+ sv->CP00_pdR,
+ sv->CP00_pdR_size,
+ DEVICE_MVPD_ADDRESS( MVPD_RECORD_CP00,
+ MVPD_KEYWORD_PDR ) );
+ if( l_errhdl )
+ {
+ TS_FAIL("Error restoring CP00/#R to %.8X",
+ TARGETING::get_huid(sv->target));
+ errlCommit( l_errhdl, VPD_COMP_ID );
+ }
+ delete[] sv->CP00_pdR;
+ sv->CP00_pdR = NULL;
+ }
+ }
+ //--
+
+ // delete allocated space
+ if( l_pRingBuf )
+ {
delete[] l_pRingBuf;
}
+ for( std::list<saveRestoreData_t>::iterator sv = l_srData.begin();
+ sv != l_srData.end();
+ ++sv )
+ {
+ if( sv->CP00_pdG != NULL )
+ {
+ delete[] sv->CP00_pdG;
+ sv->CP00_pdG = NULL;
+ }
+ if( sv->CP00_pdR != NULL )
+ {
+ delete[] sv->CP00_pdR;
+ sv->CP00_pdR = NULL;
+ }
+ }
+
TS_TRACE( "testRepairRings exit" );
}
diff --git a/src/usr/vpd/makefile b/src/usr/vpd/makefile
index 5834a325c..36d41d0db 100644
--- a/src/usr/vpd/makefile
+++ b/src/usr/vpd/makefile
@@ -27,7 +27,8 @@ OBJS = vpd.o spd.o mvpd.o dimmPres.o
SUBDIRS = test.d
-BINARY_FILES = $(IMGDIR)/procmvpd.dat:fd9fac85d9132c287f81468045c79f1c98409811
-BINARY_FILES += $(IMGDIR)/dimmspd.dat:9a6e6b6a7f6d3fc77a12d38537279d402124d699
+BINARY_FILES = $(IMGDIR)/dimmspd.dat:9a6e6b6a7f6d3fc77a12d38537279d402124d699
+#BINARY_FILES += $(IMGDIR)/procmvpd.dat:fb03d27717e1f0d36bb4582a07b5aaaf90de41d6
+BINARY_FILES += $(IMGDIR)/procmvpd.dat:dc85f0e2f7b26f3928c817be3f0c37a9cc0e0bed
include ${ROOTPATH}/config.mk
diff --git a/src/usr/vpd/mvpd.C b/src/usr/vpd/mvpd.C
index cf935758e..30d1f3c62 100755
--- a/src/usr/vpd/mvpd.C
+++ b/src/usr/vpd/mvpd.C
@@ -75,7 +75,7 @@ uint64_t g_mvpdPnorAddr = 0x0;
// By setting to false, allows debug at a later time by allowing to
// substitute a binary file (procmvpd.dat) into PNOR.
-const bool g_readPNOR = true;
+const bool g_usePNOR = true;
/**
@@ -219,6 +219,9 @@ errlHndl_t mvpdWrite ( DeviceFW::OperationType i_opType,
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 ));
@@ -228,26 +231,51 @@ errlHndl_t mvpdWrite ( DeviceFW::OperationType i_opType,
do
{
- // TODO - This will be implemented with story 39177
- TRACFCOMP( g_trac_mvpd,
- ERR_MRK"MVPD Writes are not supported yet!" );
+ // Get the Record/keyword names
+ err = mvpdTranslateRecord( args.record,
+ recordName );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_OPERATION_NOT_SUPPORTED
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_MVPD_WRITE
- * @userdata1 Requested Record
- * @userdata2 Requested Keyword
- * @devdesc MVPD Writes are not supported currently.
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_MVPD_WRITE,
- VPD::VPD_OPERATION_NOT_SUPPORTED,
- args.record,
- args.keyword );
+ if( err )
+ {
+ break;
+ }
+
+ err = mvpdTranslateKeyword( args.keyword,
+ keywordName );
+
+ if( err )
+ {
+ break;
+ }
+
+ TRACSCOMP( g_trac_mvpd,
+ INFO_MRK"Write record (%s) and Keyword (%s)",
+ recordName, keywordName );
+
+ // Get the offset of the record requested
+ err = mvpdFindRecordOffset( recordName,
+ recordOffset,
+ i_target,
+ args );
- break;
+ if( err )
+ {
+ break;
+ }
+
+ // use record offset to find/read the keyword
+ err = mvpdWriteKeyword( keywordName,
+ recordName,
+ recordOffset,
+ i_target,
+ io_buffer,
+ io_buflen,
+ args );
+
+ if( err )
+ {
+ break;
+ }
} while( 0 );
TRACSSCOMP( g_trac_mvpd,
@@ -497,220 +525,56 @@ errlHndl_t mvpdRetrieveKeyword ( const char * i_keywordName,
input_args_t i_args )
{
errlHndl_t err = NULL;
- uint16_t offset = i_offset;
- uint16_t recordSize = 0x0;
- uint16_t keywordSize = 0x0;
- 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;
-
+ // First go find the keyword in memory
+ size_t keywordSize = 0x0;
+ uint64_t byteAddr = 0x0;
+ err = mvpdFindKeywordAddr( i_keywordName,
+ i_recordName,
+ i_offset,
+ i_target,
+ keywordSize,
+ byteAddr,
+ i_args );
if( err )
{
break;
}
- // Byte Swap
- recordSize = le16toh( 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 )
+ // If the buffer is NULL, return the keyword size in io_buflen
+ if( NULL == io_buffer )
{
+ io_buflen = keywordSize;
break;
}
- if( memcmp( record, i_recordName, RECORD_BYTE_SIZE ) )
+ // check size of usr buffer with io_buflen
+ err = checkBufferSize( io_buflen,
+ (size_t)keywordSize );
+ if( err )
{
- 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 VPD::VPD_RECORD_MISMATCH
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_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,
- VPD::VPD_MVPD_RETRIEVE_KEYWORD,
- VPD::VPD_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 = le16toh( 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;
-
- // If the buffer is NULL, return the keyword size in io_buflen
- if( NULL == io_buffer )
- {
- io_buflen = keywordSize;
- break;
- }
-
- // 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 ||
- matchFound )
+ // Read keyword data into io_buffer
+ err = mvpdFetchData( i_offset+byteAddr,
+ keywordSize,
+ io_buffer,
+ i_target );
+ 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 VPD::VPD_KEYWORD_NOT_FOUND
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_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,
- VPD::VPD_MVPD_RETRIEVE_KEYWORD,
- VPD::VPD_KEYWORD_NOT_FOUND,
- i_offset,
- TWO_UINT32_TO_UINT64( i_args.record,
- i_args.keyword ) );
+ // Everything worked
+ io_buflen = keywordSize;
- // Add trace so we know what Record/Keyword was missing
- err->collectTrace( "MVPD" );
- }
+ } while(0);
TRACSSCOMP( g_trac_mvpd,
EXIT_MRK"mvpdRetrieveKeyword()" );
@@ -734,7 +598,7 @@ errlHndl_t mvpdFetchData ( uint64_t i_byteAddr,
do
{
- if( g_readPNOR )
+ if( likely( g_usePNOR ) )
{
// Call a function in the common VPD code
VPD::pnorInformation info;
@@ -945,5 +809,335 @@ bool compareKeywords ( const mvpdKeywordInfo e1,
return false;
}
+// ------------------------------------------------------------------
+// mvpdFindKeywordAddr
+// ------------------------------------------------------------------
+errlHndl_t mvpdFindKeywordAddr ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ size_t& o_keywordSize,
+ uint64_t& o_byteAddr,
+ input_args_t i_args )
+{
+ errlHndl_t err = NULL;
+ uint16_t offset = i_offset;
+ uint16_t recordSize = 0x0;
+ uint16_t keywordSize = 0x0;
+ char record[RECORD_BYTE_SIZE] = { '\0' };
+ char keyword[KEYWORD_BYTE_SIZE] = { '\0' };
+ bool matchFound = false;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdFindKeywordAddr()" );
+
+ 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 = le16toh( 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 VPD::VPD_RECORD_MISMATCH
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_MVPD_FIND_KEYWORD_ADDR
+ * @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,
+ VPD::VPD_MVPD_FIND_KEYWORD_ADDR,
+ VPD::VPD_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 = le16toh( 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 ) ) )
+ {
+ // send back the relevant data
+ o_keywordSize = keywordSize;
+ o_byteAddr = offset - i_offset; //make address relative
+
+ // found our match, break out
+ matchFound = true;
+ break;
+ }
+ else
+ {
+ // set offset to next keyword (based on current keyword size)
+ offset += keywordSize;
+ }
+ }
+
+ if( err ||
+ matchFound )
+ {
+ 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 VPD::VPD_KEYWORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_MVPD_FIND_KEYWORD_ADDR
+ * @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,
+ VPD::VPD_MVPD_FIND_KEYWORD_ADDR,
+ VPD::VPD_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"mvpdFindKeywordAddr()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// mvpdWriteKeyword
+// ------------------------------------------------------------------
+errlHndl_t mvpdWriteKeyword ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ void * i_buffer,
+ size_t & i_buflen,
+ input_args_t i_args )
+{
+ errlHndl_t err = NULL;
+
+ TRACSSCOMP( g_trac_mvpd,
+ ENTER_MRK"mvpdWriteKeyword()" );
+
+ do
+ {
+ // Note, there is no way to tell if a keyword is writable without
+ // hardcoding it so we will just assume that the callers know
+ // what they are doing
+
+ // First go find the keyword in memory
+ size_t keywordSize = 0x0;
+ uint64_t byteAddr = 0x0;
+ err = mvpdFindKeywordAddr( i_keywordName,
+ i_recordName,
+ i_offset,
+ i_target,
+ keywordSize,
+ byteAddr,
+ i_args );
+ if( err )
+ {
+ break;
+ }
+
+ // check size of usr buffer with io_buflen
+ err = checkBufferSize( i_buflen,
+ keywordSize );
+ if( err )
+ {
+ break;
+ }
+
+ // Now write it out to PNOR
+ if( likely( g_usePNOR ) )
+ {
+ // Setup info needed to write from PNOR
+ VPD::pnorInformation info;
+ info.segmentSize = MVPD_SECTION_SIZE;
+ info.maxSegments = MVPD_MAX_SECTIONS;
+ info.pnorSection = PNOR::MODULE_VPD;
+ info.pnorSide = PNOR::CURRENT_SIDE;
+ err = VPD::writePNOR( i_offset+byteAddr,
+ keywordSize,
+ i_buffer,
+ i_target,
+ info,
+ g_mvpdPnorAddr,
+ &g_mvpdMutex );
+
+ if( err )
+ {
+ break;
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"There is no way to write mvpd when not using PNOR!" );
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_INVALID_WRITE_METHOD
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_MVPD_WRITE_KEYWORD
+ * @userdata1 Write Offset
+ * @userdata2 Number of Bytes to Write
+ * @devdesc g_usePNOR is false, but there isn't an
+ * alternate way to write PNOR.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_MVPD_WRITE_KEYWORD,
+ VPD::VPD_INVALID_WRITE_METHOD,
+ byteAddr,
+ keywordSize );
+
+ break;
+ }
+
+ VPD::VpdWriteMsg_t msgdata;
+
+ // Quick double-check that our constants agree with the values in the
+ // VPD message structure
+ assert( sizeof(msgdata.record) == RECORD_BYTE_SIZE );
+ assert( sizeof(msgdata.keyword) == KEYWORD_BYTE_SIZE );
+
+ // Finally, send it down to the FSP
+ msgdata.rec_num = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>();
+ memcpy( msgdata.record, i_recordName, RECORD_BYTE_SIZE );
+ memcpy( msgdata.keyword, i_keywordName, KEYWORD_BYTE_SIZE );
+ err = VPD::sendMboxWriteMsg( keywordSize,
+ i_buffer,
+ i_target,
+ VPD::VPD_WRITE_PROC,
+ msgdata );
+
+ if( err )
+ {
+ break;
+ }
+
+
+ } while(0);
+
+ TRACSSCOMP( g_trac_mvpd,
+ EXIT_MRK"mvpdWriteKeyword()" );
+
+ return err;
+}
} // end namespace MVPD
diff --git a/src/usr/vpd/mvpd.H b/src/usr/vpd/mvpd.H
index 680119fcd..26aba4c49 100755
--- a/src/usr/vpd/mvpd.H
+++ b/src/usr/vpd/mvpd.H
@@ -70,7 +70,7 @@ typedef struct
typedef struct
{
mvpdRecord record;
- char recordName[MVPD_LAST_RECORD];
+ char recordName[RECORD_BYTE_SIZE+1];
} mvpdRecordInfo;
/**
@@ -78,7 +78,7 @@ typedef struct
typedef struct
{
mvpdKeyword keyword;
- char keywordName[MVPD_LAST_KEYWORD];
+ char keywordName[KEYWORD_BYTE_SIZE+1];
} mvpdKeywordInfo;
@@ -127,6 +127,7 @@ const mvpdRecordInfo mvpdRecords[] =
{ LWPD, "LWPD" },
{ LWPE, "LWPE" },
{ VWML, "VWML" },
+ { MER0, "MER0" },
// -------------------------------------------------------------------
// DO NOT USE!! This is for test purposes ONLY!
{ MVPD_TEST_RECORD, "TEST" },
@@ -181,7 +182,7 @@ const mvpdKeywordInfo mvpdKeywords[] =
{ CH, "CH" },
// -------------------------------------------------------------------
// DO NOT USE!! This is for test purposes ONLY!
- { MVPD_TEST_KEYWORD, "TEST" },
+ { MVPD_TEST_KEYWORD, "XX" },
// -------------------------------------------------------------------
};
@@ -374,6 +375,66 @@ errlHndl_t mvpdRetrieveKeyword ( const char * i_keywordName,
size_t & io_buflen,
input_args_t i_args );
+/**
+ * @brief This function will write the required keyword into 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 writing.
+ *
+ * @param[in] i_target - The target to write data for.
+ *
+ * @param[in] i_buffer - The buffer to pull the data from.
+ *
+ * @param[in] i_buflen - Length of the buffer to be written
+ * to the target's VPD area. This value should indicate the size of the
+ * io_buffer parameter that has been allocated.
+ *
+ * @param[in] i_args - The input arguments.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdWriteKeyword ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ void * i_buffer,
+ size_t & i_buflen,
+ input_args_t i_args );
+
+/**
+ * @brief This function will locate the byte address of a keyword
+ * within its VPD section.
+ *
+ * @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 writing.
+ *
+ * @param[in] i_target - The target to write data for.
+ *
+ * @param[out] o_keywordSize - Size of keyword in bytes.
+ *
+ * @param[out] o_byteAddr - Address of keyword, relative to this target's
+ * section.
+ *
+ * @param[in] i_args - The original input arguments.
+ *
+ * @return errHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t mvpdFindKeywordAddr ( const char * i_keywordName,
+ const char * i_recordName,
+ uint16_t i_offset,
+ TARGETING::Target * i_target,
+ size_t& o_keywordSize,
+ uint64_t& o_byteAddr,
+ input_args_t i_args );
+
}; // end MVPD namespace
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index 27df54b2a..c62bd91f4 100755
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -603,51 +603,7 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
}
// Check write flag
- if( entry->writable )
- {
- // Check the Size to be equal to entry written
- err = spdCheckSize( io_buflen,
- entry->length,
- i_keyword );
-
- if( err )
- {
- break;
- }
-
- //@todo: RTC:39177 - Need to handle writes that are not on a
- // byte boundary by reading the rest of the byte first
- assert( (entry->length)%8 == 0 );
-
- // Write value
- err = spdWriteData( entry->offset,
- io_buflen,
- io_buffer,
- i_target );
-
- if( err )
- {
- break;
- }
-
- // Send mbox message with new data to Fsp
- VPD::VpdWriteMsg_t msgdata;
- msgdata.rec_num = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>();
- //XXXX=offset relative to whole section
- memcpy( msgdata.record, "XXXX", 4 );
- msgdata.offset = entry->offset;
- err = VPD::sendMboxWriteMsg( io_buflen,
- io_buffer,
- i_target,
- VPD::VPD_WRITE_DIMM,
- msgdata );
-
- if( err )
- {
- break;
- }
- }
- else
+ if( !(entry->writable) )
{
// Error if not writable
TRACFCOMP( g_trac_spd,
@@ -674,6 +630,77 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
break;
}
+
+ // Check the Size to be equal to entry written
+ err = spdCheckSize( io_buflen,
+ entry->length,
+ i_keyword );
+
+ if( err )
+ {
+ break;
+ }
+
+ // We are not handling writes that are not on a byte
+ // boundary until we absolutely need to. There are
+ // no writable keywords that are not on byte boundaries
+ if( entry->useBitMask )
+ {
+ // Error if not writable
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Trying to write keyword (0x%04x) that is not a full byte size",
+ i_keyword );
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_UNSUPPORTED_WRITE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_SPD_WRITE_VALUE
+ * @userdata1 SPD Keyword
+ * @userdata2[0:15] Keyword Length (in bytes)
+ * @userdata2[16:31] Keyword Bitmask
+ * @userdata2[32:63] Memory Type
+ * @devdesc Writes to non-byte SPD keywords are unsupported.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_WRITE_VALUE,
+ VPD::VPD_UNSUPPORTED_WRITE,
+ i_keyword,
+ TWO_UINT16_ONE_UINT32_TO_UINT64(
+ entry->length,
+ entry->bitMask,
+ i_DDRRev ) );
+
+ break;
+ }
+
+ // Write value
+ err = spdWriteData( entry->offset,
+ io_buflen,
+ io_buffer,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+
+ // Send mbox message with new data to Fsp
+ VPD::VpdWriteMsg_t msgdata;
+ msgdata.rec_num = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>();
+ //XXXX=offset relative to whole section
+ memcpy( msgdata.record, "XXXX", sizeof(msgdata.record) );
+ msgdata.offset = entry->offset;
+ err = VPD::sendMboxWriteMsg( io_buflen,
+ io_buffer,
+ i_target,
+ VPD::VPD_WRITE_DIMM,
+ msgdata );
+
+ if( err )
+ {
+ break;
+ }
} while( 0 );
TRACSSCOMP( g_trac_spd,
diff --git a/src/usr/vpd/spd.H b/src/usr/vpd/spd.H
index b21d34bf9..267c5aa48 100755
--- a/src/usr/vpd/spd.H
+++ b/src/usr/vpd/spd.H
@@ -52,7 +52,7 @@ enum
// Basic Memory Type Enumerations
SPD_DDR3 = 0xB,
- SPD_DDR4 = 0xC, // TODO - Proposed value from draft Spec.
+ SPD_DDR4 = 0xC, // @todo - Proposed value from draft Spec. (RTC:61138)
};
/**
diff --git a/src/usr/vpd/test/mvpdtest.H b/src/usr/vpd/test/mvpdtest.H
index 9480f2881..a7685550e 100755
--- a/src/usr/vpd/test/mvpdtest.H
+++ b/src/usr/vpd/test/mvpdtest.H
@@ -66,43 +66,19 @@ mvpdTestData mvpdData[] =
{ CRP0, ED },
{ CRP0, TE },
{ CRP0, DD },
-// { CRP0, pdP }, // TODO - no #P in test data, pull for now RTC 51716
+// { CRP0, pdP }, // TODO - no #P in test data
{ CRP0, ST },
-// { CRP0, DN, 0x03 }, // TODO - This doesn't match documentation,
-// pulling out for now
{ CP00, VD },
{ CP00, PG },
-// { CP00, PK }, // TODO - no PK in test data. pull for now RTC 51716
+// { CP00, PK }, // TODO - no PK in test data
{ CP00, pdR },
{ CP00, pdG },
{ CP00, pdV },
{ CP00, pdH },
-// { CP00, pdP }, // TODO - no #P in test data, pull for now RTC 51716
+// { CP00, pdP }, // TODO - no #P in test data
{ CP00, SB },
{ CP00, MK },
{ CP00, PB },
-/* // TODO no LRP0,LRP1,LRP2,LRP3 in test data, pull for now RTC 51716
- { LRP0, VD },
- { LRP0, pdV },
- { LRP0, pdP },
- { LRP0, pdM },
- { LRP0, CH },
- { LRP1, VD },
- { LRP1, pdV },
- { LRP1, pdP },
- { LRP1, pdM },
- { LRP1, CH },
- { LRP2, VD },
- { LRP2, pdV },
- { LRP2, pdP },
- { LRP2, pdM },
- { LRP2, CH },
- { LRP3, VD },
- { LRP3, pdV },
- { LRP3, pdP },
- { LRP3, pdM },
- { LRP3, CH },
-*/
{ LRP4, VD },
{ LRP4, pdV },
{ LRP4, pdP },
@@ -118,7 +94,7 @@ mvpdTestData mvpdData[] =
{ LRP6, pdP },
{ LRP6, pdM },
{ LRP6, CH },
-/* // TODO no LRP7,LRP8,LRP9,LRPA,LRPB,LWPO,LWP1,LWP2,LWP3 in test data, pull for now RTC 51716
+/* // TODO no LRP7,LRP8,LRP9,LRPA,LRPB,LWPO,LWP1,LWP2,LWP3 in test data
{ LRP7, VD },
{ LRP7, pdV },
{ LRP7, pdP },
@@ -188,7 +164,7 @@ mvpdTestData mvpdData[] =
{ LWP6, pd2 },
{ LWP6, pd3 },
{ LWP6, IN },
-/* // TODO no LWP7,LWP8,LWP9,LWPA,LWPB in test data, pull for now RTC 51716
+/* // TODO no LWP7,LWP8,LWP9,LWPA,LWPB in test data
{ LWP7, VD },
{ LWP7, pd2 },
{ LWP7, pd3 },
@@ -233,7 +209,10 @@ mvpdTestData mvpdData[] =
{ VINI, HE },
{ VINI, CT },
{ VINI, HW },
- // TODO - Add VWML when available.
+
+ { VWML, pdI },
+
+ { MER0, pdI },
};
void getProcTargets( TargetHandleList & o_procList )
@@ -400,13 +379,16 @@ class MVPDTest: public CxxTest::TestSuite
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
+ uint8_t* testData = NULL;
+ uint8_t* origData = NULL;
+ uint8_t* verifyData = NULL;
TRACFCOMP( g_trac_mvpd,
ENTER_MRK"testMvpdWrite()" );
do
{
- TARGETING::Target * theTarget = NULL;
+ TARGETING::Target * theTgt = NULL;
// Get the processor targets
TargetHandleList procList;
@@ -422,11 +404,10 @@ class MVPDTest: public CxxTest::TestSuite
}
// Use the first Proc in the list
- theTarget = procList[0];
+ theTgt = procList[0];
// check to see if the target is functional
- if
- (!theTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
+ if(!theTgt->getAttr<TARGETING::ATTR_HWAS_STATE>().functional)
{
TRACFCOMP( g_trac_mvpd,
@@ -435,35 +416,142 @@ class MVPDTest: public CxxTest::TestSuite
continue; // add continue because target is non functional
}
- size_t theSize = 1;
- uint8_t * theData = new uint8_t[theSize];
+ // first figure out how big the keyword is
+ cmds++;
+ size_t theSize = 0;
+ err = deviceRead( theTgt,
+ testData,
+ theSize,
+ DEVICE_MVPD_ADDRESS(VWML,pdI) );
+ if( err )
+ {
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdWrite() - failure getting size of VWML/#I, RC=%.4X",
+ err->reasonCode() );
+ TS_FAIL( "testMvpdWrite() - Failure calling deviceRead!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+ // save off the original data
+ origData = new uint8_t[theSize];
cmds++;
- err = deviceWrite( theTarget,
- theData,
+ err = deviceRead( theTgt,
+ origData,
+ theSize,
+ DEVICE_MVPD_ADDRESS(VWML,pdI) );
+ if( err )
+ {
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdWrite() - failure reading VWML/#I, RC=%.4X",
+ err->reasonCode() );
+ TS_FAIL( "testMvpdWrite() - Failure calling deviceRead!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
+ TRACFBIN( g_trac_mvpd, "orig=", origData, theSize );
+
+ // fill it up with some dummy data
+ testData = new uint8_t[theSize];
+ for( size_t x=0; x<theSize; x++ )
+ {
+ testData[x] = x;
+ }
+
+ // write the new data in
+ cmds++;
+ err = deviceWrite( theTgt,
+ testData,
theSize,
- DEVICE_MVPD_ADDRESS( CRP0,
- pdP ) );
+ DEVICE_MVPD_ADDRESS(VWML,pdI) );
+ if( err )
+ {
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdWrite() - failure writing VWML/#I, RC=%.4X",
+ err->reasonCode() );
+ TS_FAIL( "testMvpdWrite() - Failure calling deviceWrite!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
+ }
- if( NULL == err )
+ // verify the data got written
+ cmds++;
+ verifyData = new uint8_t[theSize];
+ err = deviceRead( theTgt,
+ verifyData,
+ theSize,
+ DEVICE_MVPD_ADDRESS(VWML,pdI) );
+ if( err )
{
fails++;
- TS_FAIL( "testMvpdWrite - Expected error from write "
- "attempt since its not supported!" );
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdWrite() - failure reading VWML/#I to verify, RC=%.4X",
+ err->reasonCode() );
+ TS_FAIL( "testMvpdWrite() - Failure calling deviceRead!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
}
- else
+ TRACFBIN( g_trac_mvpd, "verif=", verifyData, theSize );
+
+ // compare what we read to what we wrote
+ if( memcmp( testData, verifyData, theSize ) )
{
- delete err;
- err = NULL;
+ fails++;
+ TRACFBIN( g_trac_mvpd, "wrote=", testData, theSize );
+ TRACFBIN( g_trac_mvpd, "read=", verifyData, theSize );
+ TS_FAIL( "testMvpdWrite - Data mismatch!" );
}
- if( NULL != theData )
+ // put the original data back to be a good citizen
+ cmds++;
+ err = deviceWrite( theTgt,
+ origData,
+ theSize,
+ DEVICE_MVPD_ADDRESS(VWML,pdI) );
+ if( err )
{
- delete theData;
- theData = NULL;
+ fails++;
+ TRACFCOMP( g_trac_mvpd,
+ ERR_MRK"testMvpdWrite() - failure writing original data back into VWML/#I, RC=%.4X",
+ err->reasonCode() );
+ TS_FAIL( "testMvpdWrite() - Failure calling deviceRead!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ continue;
}
+
} while( 0 );
+ if( NULL != testData )
+ {
+ delete[] testData;
+ testData = NULL;
+ }
+
+ if( NULL != origData )
+ {
+ delete[] origData;
+ origData = NULL;
+ }
+
+ if( NULL != verifyData )
+ {
+ delete[] verifyData;
+ verifyData = NULL;
+ }
+
+ if( cmds == 0 )
+ {
+ TS_FAIL( "testMvpdWrite - No tests ran, something is wrong..." );
+ }
+
TRACFCOMP( g_trac_mvpd,
"testMvpdWrite - %d/%d fails",
fails, cmds );
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
index 38b53bf23..5ef8a6107 100755
--- a/src/usr/vpd/test/spdtest.H
+++ b/src/usr/vpd/test/spdtest.H
@@ -207,6 +207,11 @@ class SPDTest: public CxxTest::TestSuite
theData = NULL;
}
+ if( cmds == 0 )
+ {
+ TS_FAIL( "testSpdRead - No tests ran, something is wrong..." );
+ }
+
TRACFCOMP( g_trac_spd,
"testSpdRead - %d/%d fails",
fails, cmds );
@@ -215,16 +220,17 @@ class SPDTest: public CxxTest::TestSuite
/**
* @brief Test a SPD Write
*/
- void testSpdWrite ( void )
+ void testSpdWriteDQ ( void )
{
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
- uint8_t * theData = NULL;
+ uint8_t * testData = NULL;
uint8_t * origData = NULL;
+ uint8_t * verifyData = NULL;
TRACFCOMP( g_trac_spd,
- ENTER_MRK"testSpdWrite()" );
+ ENTER_MRK"testSpdWriteDQ()" );
do
{
@@ -238,7 +244,7 @@ class SPDTest: public CxxTest::TestSuite
( NULL == dimmList[0] ) )
{
TRACFCOMP( g_trac_spd,
- "testSpdWrite - No DIMMs found!" );
+ "testSpdWriteDQ - No DIMMs found!" );
break;
}
@@ -255,7 +261,7 @@ class SPDTest: public CxxTest::TestSuite
if( err )
{
fails++;
- TS_FAIL( "testSpdWrite - failed to read memtype!" );
+ TS_FAIL( "testSpdWriteDQ - failed to read memtype!" );
errlCommit( err,
VPD_COMP_ID );
break;
@@ -279,98 +285,301 @@ class SPDTest: public CxxTest::TestSuite
{
fails++;
TRACFCOMP( g_trac_spd,
- "testSpdWrite - memory type: 0x%04x",
+ "testSpdWriteDQ - memory type: 0x%04x",
memType );
- TS_FAIL( "testSpdWrite - Unsupported Memory Type!" );
+ TS_FAIL( "testSpdWriteDQ - Unsupported Memory Type!" );
errlCommit( err,
VPD_COMP_ID );
break;
}
// Allocate data buffer
- theData = static_cast<uint8_t*>(malloc( theSize ));
+ origData = static_cast<uint8_t*>(malloc( theSize ));
// Read the data out first
err = deviceRead( theTarget,
- theData,
+ origData,
theSize,
DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
if( err )
{
fails++;
- TS_FAIL( "testSpdWrite - failed to read DIMM Bad DQ data!" );
+ TS_FAIL( "testSpdWriteDQ - failed to read DIMM Bad DQ data!" );
errlCommit( err,
VPD_COMP_ID );
break;
}
- origData = static_cast<uint8_t*>(malloc( theSize ));
- memcpy( origData, theData, theSize );
+ // fill it up with some dummy data
+ testData = static_cast<uint8_t*>(malloc( theSize ));
+ for( size_t x=0; x<theSize; x++ )
+ {
+ testData[x] = x;
+ }
- // Write the data back
+ // Write the test data in
err = deviceWrite( theTarget,
- theData,
+ testData,
theSize,
DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
if( err )
{
- // No error returned, failure
fails++;
- TS_FAIL( "testSpdWrite - Error writing data to DIMM Bad DQ "
+ TS_FAIL( "testSpdWriteDQ - Error writing data to DIMM Bad DQ "
"data" );
break;
}
- else
- {
- delete err;
- err = NULL;
- }
// Read the data out again to check it
+ verifyData = static_cast<uint8_t*>(malloc( theSize ));
err = deviceRead( theTarget,
- theData,
+ verifyData,
theSize,
DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
if( err )
{
fails++;
- TS_FAIL( "testSpdWrite - failed to read DIMM Bad DQ data! [2]" );
+ TS_FAIL( "testSpdWriteDQ - failed to read DIMM Bad DQ data! [2]" );
errlCommit( err,
VPD_COMP_ID );
break;
}
- if( memcmp( theData, origData, theSize ) )
+ if( memcmp( testData, verifyData, theSize ) )
{
fails++;
- TS_FAIL( "testSpdWrite - DIMM Bad DQ data does not match what we wrote!" );
- TRACFBIN( g_trac_spd, "orig=", origData, theSize );
- TRACFBIN( g_trac_spd, "read=", theData, theSize );
+ TS_FAIL( "testSpdWriteDQ - DIMM Bad DQ data does not match what we wrote!" );
+ TRACFBIN( g_trac_spd, "wrote=", testData, theSize );
+ TRACFBIN( g_trac_spd, "read=", verifyData, theSize );
}
+ // put the original data back to be a good citizen
+ err = deviceWrite( theTarget,
+ origData,
+ theSize,
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteDQ - Error writing original data back to DIMM Bad DQ "
+ "data" );
+ break;
+ }
+
+
} while( 0 );
- if( NULL != theData )
+ if( NULL != testData )
{
- free( theData );
- theData = NULL;
+ delete testData;
+ testData = NULL;
}
if( NULL != origData )
{
- free( origData );
- theData = NULL;
+ delete origData;
+ origData = NULL;
+ }
+
+ if( NULL != verifyData )
+ {
+ delete verifyData;
+ verifyData = NULL;
+ }
+
+ if( cmds == 0 )
+ {
+ TS_FAIL( "testSpdWriteDQ - No tests ran, something is wrong..." );
}
TRACFCOMP( g_trac_spd,
- "testSpdWrite - %d/%d fails",
+ "testSpdWriteDQ - %d/%d fails",
fails, cmds );
}
/**
+ * @brief Test a SPD Write to a value that is less than 1 byte
+ *
+ * Note - There are no writable keywords that fit this criteria
+ * so this test is disabled by default. To enable, modify the
+ * table in spdDDR3.H to make something writable.
+ */
+ void _testSpdWriteSmall ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint8_t* testData = NULL;
+ uint8_t* origData = NULL;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdWriteSmall()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - No DIMMs found!" );
+ break;
+ }
+
+ // Operate on first DIMM
+ cmds++;
+ theTarget = dimmList[0];
+
+ // Get Memory Type
+ uint8_t memType = 0x0;
+ err = getMemType( theTarget,
+ memType );
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteSmall - failed to read memtype!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // Get the size
+ size_t theSize = 0;
+ uint16_t theKeyword = INVALID_SPD_KEYWORD;
+ if( SPD_DDR3 == memType )
+ {
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( ddr3Data[entry].writable
+ && ddr3Data[entry].useBitMask )
+ {
+ theSize = ddr3Data[entry].length;
+ theKeyword = ddr3Data[entry].keyword;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - Using keyword 0x%04x",
+ theKeyword );
+ break;
+ }
+ }
+ }
+ else
+ {
+ fails++;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - memory type: 0x%04x",
+ memType );
+ TS_FAIL( "testSpdWriteSmall - Unsupported Memory Type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ cmds++;
+ if( theKeyword == INVALID_SPD_KEYWORD )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteSmall - Could not find a keyword to work with!" );
+ break;
+ }
+
+ // Read the data out
+ cmds++;
+ origData = new uint8_t[theSize];
+ err = deviceRead( theTarget,
+ origData,
+ theSize,
+ DEVICE_SPD_ADDRESS( theKeyword ) );
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteSmall - failed to read keyword!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
+ // fill test array up with some dummy data
+ testData = new uint8_t[theSize];
+ for( size_t x=0; x<theSize; x++ )
+ {
+ testData[x] = 0x55;
+ }
+
+ // Write the test data
+ cmds++;
+ err = deviceWrite( theTarget,
+ testData,
+ theSize,
+ DEVICE_SPD_ADDRESS( theKeyword ) );
+ if( !err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteSmall - Did not get expected error writing data" );
+
+ // Put the original data back to be a good citizen
+ cmds++;
+ err = deviceWrite( theTarget,
+ origData,
+ theSize,
+ DEVICE_SPD_ADDRESS( theKeyword ) );
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWriteSmall - Error writing original data back" );
+ }
+
+ break;
+ }
+ else
+ {
+ cmds++;
+ if( err->reasonCode() != VPD::VPD_UNSUPPORTED_WRITE )
+ {
+ fails++;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - RC from write = 0x%04x",
+ err->reasonCode() );
+ TS_FAIL( "testSpdWriteSmall - Did not get VPD_UNSUPPORTED_WRITE error writing data" );
+ }
+
+ delete err;
+ }
+
+ } while( 0 );
+
+ if( NULL != testData )
+ {
+ delete[] testData;
+ testData = NULL;
+ }
+
+ if( NULL != origData )
+ {
+ delete[] origData;
+ origData = NULL;
+ }
+
+ if( cmds == 0 )
+ {
+ TS_FAIL( "testSpdWriteSmall - No tests ran, something is wrong..." );
+ }
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - %d/%d fails",
+ fails, cmds );
+ }
+ /**
* @brief Test an invalid Keyword to a DIMM target.
*/
void testSpdInvalidKeyword ( void )
@@ -542,7 +751,7 @@ class SPDTest: public CxxTest::TestSuite
err = NULL;
}
} while( 0 );
-
+
TRACFCOMP( g_trac_spd,
"testSpdInvalidWrite - %d/%d fails",
fails, cmds );
diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C
index e23279309..54fefa8b9 100644
--- a/src/usr/vpd/vpd.C
+++ b/src/usr/vpd/vpd.C
@@ -24,6 +24,7 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
+#include <vpd/vpdreasoncodes.H>
#include "vpd.H"
// ----------------------------------------------
@@ -261,12 +262,9 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
msg->data[0] = i_record.data0;
msg->data[1] = i_numBytes;
- //should never need more than 4KB @fixme
- assert( i_numBytes < PAGESIZE);
-
+ //Copy the data into the message
msg->extra_data = malloc( i_numBytes );
memcpy( msg->extra_data, i_data, i_numBytes );
- TRACFCOMP( g_trac_vpd, "extra_data=%p", msg->extra_data );
TRACFCOMP( g_trac_vpd,
INFO_MRK"Send msg to FSP to write VPD type %.8X, record %d, offset 0x%X",
OpenPOWER on IntegriCloud