summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTerry J. Opie <opiet@us.ibm.com>2012-04-30 11:08:27 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-06-19 10:33:05 -0500
commit733ba77cc3d60ac69143a9fb5be21202495d02a7 (patch)
tree9be74e03ade55b898f67e4f82e825a36ca74df9c /src
parente9de3b17d17a3c230ae9db3ed7d4139950cd4963 (diff)
downloadblackbird-hostboot-733ba77cc3d60ac69143a9fb5be21202495d02a7.tar.gz
blackbird-hostboot-733ba77cc3d60ac69143a9fb5be21202495d02a7.zip
SPD Write Support
RTC: 35776 Depends-on: I2348a2da90ea85a966f3724f8b3694a0b8f03916 Depends-on: Ia0f22c87f8bc3959324fa8347e191f2b47b4325c Change-Id: I66bdc8baf491abb0df5427d16bc586e293c6f506 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1048 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/spd/spdif.H4
-rw-r--r--src/include/usr/spd/spdreasoncodes.H51
-rwxr-xr-xsrc/usr/mvpd/mvpd.C4
-rwxr-xr-xsrc/usr/spd/dimmPres.C8
-rwxr-xr-xsrc/usr/spd/spd.C633
-rwxr-xr-xsrc/usr/spd/spd.H209
-rwxr-xr-xsrc/usr/spd/spdDDR3.H400
-rwxr-xr-xsrc/usr/spd/test/spdtest.H154
8 files changed, 1060 insertions, 403 deletions
diff --git a/src/include/usr/spd/spdif.H b/src/include/usr/spd/spdif.H
index f536babd8..c56a8dabf 100644
--- a/src/include/usr/spd/spdif.H
+++ b/src/include/usr/spd/spdif.H
@@ -43,8 +43,8 @@ namespace SPD
*/
struct pnorInformation
{
- uint64_t sectionSize;
- uint64_t maxSections;
+ uint64_t segmentSize;
+ uint64_t maxSegments;
PNOR::SectionId pnorSection;
PNOR::SideSelect pnorSide;
};
diff --git a/src/include/usr/spd/spdreasoncodes.H b/src/include/usr/spd/spdreasoncodes.H
index 68adffca5..96b207494 100644
--- a/src/include/usr/spd/spdreasoncodes.H
+++ b/src/include/usr/spd/spdreasoncodes.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/usr/spd/spdreasoncodes.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
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/include/usr/spd/spdreasoncodes.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_TAG
+ */
/**
* @file spdreasoncodes.H
*
@@ -55,6 +56,9 @@ enum spdModuleId
SPD_PRESENCE_DETECT = 0x07,
SPD_CHECK_MODULE_SPECIFIC_KEYWORD = 0x08,
SPD_GET_PNOR_ADDR = 0x09,
+ SPD_WRITE_VALUE = 0x0a,
+ SPD_GET_KEYWORD_ENTRY = 0x0b,
+ SPD_WRITE_DATA = 0x0c,
};
/**
@@ -80,6 +84,9 @@ enum spdReasonCode
SPD_MOD_SPECIFIC_MISMATCH_LRMM = SPD_COMP_ID | 0x0c,
SPD_MOD_SPECIFIC_UNSUPPORTED = SPD_COMP_ID | 0x0d,
SPD_SIZE_MISMATCH = SPD_COMP_ID | 0x0e,
+ SPD_INVALID_WRITE_METHOD = SPD_COMP_ID | 0x0f,
+ SPD_NULL_ENTRY = SPD_COMP_ID | 0x10,
+ SPD_KEYWORD_NOT_WRITABLE = SPD_COMP_ID | 0x11,
};
}; // end SPD
diff --git a/src/usr/mvpd/mvpd.C b/src/usr/mvpd/mvpd.C
index 9aab6f40a..07c98560e 100755
--- a/src/usr/mvpd/mvpd.C
+++ b/src/usr/mvpd/mvpd.C
@@ -741,8 +741,8 @@ errlHndl_t mvpdFetchData ( uint64_t i_byteAddr,
// but with different address offsets. Saves us having to
// duplicate the code between the 2 modules.
SPD::pnorInformation info;
- info.sectionSize = MVPD_SECTION_SIZE;
- info.maxSections = MVPD_MAX_SECTIONS;
+ info.segmentSize = MVPD_SECTION_SIZE;
+ info.maxSegments = MVPD_MAX_SECTIONS;
info.pnorSection = PNOR::MODULE_VPD;
info.pnorSide = PNOR::SIDELESS;
err = SPD::readPNOR( i_byteAddr,
diff --git a/src/usr/spd/dimmPres.C b/src/usr/spd/dimmPres.C
index e1b349c93..3cc573414 100755
--- a/src/usr/spd/dimmPres.C
+++ b/src/usr/spd/dimmPres.C
@@ -117,10 +117,10 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
// Read Byte 2 (BASIC_MEMORY_TYPE) for the target passed in.
uint16_t data = 0x0;
size_t dataSz = sizeof(data);
- err = spdGetKeywordValue( BASIC_MEMORY_TYPE,
- &data,
- dataSz,
- i_target );
+ err = deviceRead( i_target,
+ &data,
+ dataSz,
+ DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
if( err )
{
diff --git a/src/usr/spd/spd.C b/src/usr/spd/spd.C
index e472d7885..6786ad689 100755
--- a/src/usr/spd/spd.C
+++ b/src/usr/spd/spd.C
@@ -56,7 +56,7 @@ uint64_t g_spdPnorAddr = 0x0;
// By setting to false, allows debug at a later time by allowing to
// substitute a binary file (dimmspd.dat) into PNOR.
-const bool g_readPNOR = true;
+const bool g_usePNOR = true;
// ----------------------------------------------
// Trace definitions
@@ -97,68 +97,70 @@ namespace SPD
bool compareEntries ( const KeywordData e1,
const KeywordData e2 );
-// Register the perform Op with the routing code for DIMMs.
-DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
- DeviceFW::SPD,
- TARGETING::TYPE_DIMM,
- spdAccess );
-
-// ------------------------------------------------------------------
-// spdRead
-// ------------------------------------------------------------------
-errlHndl_t spdAccess( 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;
- uint64_t keyword = va_arg( i_args, uint64_t );
+/**
+ * @brief This function will read the DIMM memory type.
+ *
+ * @param[out] o_memType - The memory type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getMemType ( uint8_t & o_memType,
+ TARGETING::Target * i_target );
- if( DeviceFW::READ == i_opType )
- {
- // Read the SPD keyword
- err = spdGetKeywordValue( keyword,
- io_buffer,
- io_buflen,
- i_target );
- }
- else
- {
- // Write the SPD keyword
- err = spdWriteKeywordValue( keyword,
- io_buffer,
- io_buflen,
- i_target );
- }
+/**
+ * @brief This function will scan the table and return the entry
+ * corresponding to the keyword being requested.
+ *
+ * @param[in] i_keyword - The keyword being requested.
+ *
+ * @param[in] i_memType - The memory type of the target.
+ *
+ * @param[out] o_entry - The table entry corresponding to the keyword.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t getKeywordEntry ( uint64_t i_keyword,
+ uint64_t i_memType,
+ KeywordData *& o_entry );
- return err;
-} // end spdRead
+// Register the perform Op with the routing code for DIMMs.
+DEVICE_REGISTER_ROUTE( DeviceFW::READ,
+ DeviceFW::SPD,
+ TARGETING::TYPE_DIMM,
+ spdGetKeywordValue );
+DEVICE_REGISTER_ROUTE( DeviceFW::WRITE,
+ DeviceFW::SPD,
+ TARGETING::TYPE_DIMM,
+ spdWriteKeywordValue );
// ------------------------------------------------------------------
// spdGetKeywordValue
// ------------------------------------------------------------------
-errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
+errlHndl_t spdGetKeywordValue ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
void * io_buffer,
size_t & io_buflen,
- TARGETING::Target * i_target )
+ int64_t i_accessType,
+ va_list i_args )
{
errlHndl_t err = NULL;
+ uint64_t keyword = va_arg( i_args, uint64_t );
TRACSSCOMP( g_trac_spd,
ENTER_MRK"spdGetKeywordValue(), io_buflen: %d, keyword: 0x%04x",
- io_buflen, i_keyword );
+ io_buflen, keyword );
do
{
// Read the Basic Memory Type
uint8_t memType = 0x0;
- err = spdFetchData( MEM_TYPE_ADDR,
- MEM_TYPE_ADDR_SZ,
- &memType,
- i_target );
+ err = getMemType( memType,
+ i_target );
if( err )
{
@@ -174,7 +176,7 @@ errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
if( SPD_DDR3 == memType )
{
// If the user wanted the Basic memory type, return this now.
- if( BASIC_MEMORY_TYPE == i_keyword )
+ if( BASIC_MEMORY_TYPE == keyword )
{
io_buflen = MEM_TYPE_ADDR_SZ;
memcpy( io_buffer, &memType, io_buflen );
@@ -182,11 +184,11 @@ errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
}
// Read the keyword value
- err = spdGetValue( i_keyword,
- io_buffer,
- io_buflen,
- i_target,
- memType );
+ err = spdGetValue( keyword,
+ io_buffer,
+ io_buflen,
+ i_target,
+ memType );
if( err )
{
@@ -212,7 +214,9 @@ errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
SPD_GET_KEYWORD_VALUE,
SPD_INVALID_BASIC_MEMORY_TYPE,
memType,
- i_keyword );
+ keyword );
+
+ break;
}
} while( 0 );
@@ -226,37 +230,68 @@ errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
// ------------------------------------------------------------------
// spdWriteKeywordValue
// ------------------------------------------------------------------
-errlHndl_t spdWriteKeywordValue ( uint64_t i_keyword,
+errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
void * io_buffer,
size_t & io_buflen,
- TARGETING::Target * i_target )
+ int64_t i_accessType,
+ va_list i_args )
{
errlHndl_t err = NULL;
+ uint64_t keyword = va_arg( i_args, uint64_t );
TRACSSCOMP( g_trac_spd,
ENTER_MRK"spdWriteKeywordValue()" );
do
{
- // TODO - This will be implemented with story 39177
- TRACFCOMP( g_trac_spd,
- ERR_MRK"SPD writes are not supported yet!" );
+ // Get memory type
+ uint8_t memType = 0x0;
+ err = getMemType( memType,
+ i_target );
- /*@
- * @errortype
- * @reasoncode SPD_NOT_SUPPORTED
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid SPD_WRITE_KEYWORD_VALUE
- * @userdata1 i_keyword
- * @userdata2 <UNUSED>
- * @devdesc SPD Writes are not supported yet.
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- SPD_WRITE_KEYWORD_VALUE,
- SPD_NOT_SUPPORTED,
- i_keyword,
- 0x0 );
- break;
+ if( err )
+ {
+ break;
+ }
+
+ // Check DDR3
+ if( SPD_DDR3 == memType )
+ {
+ err = spdWriteValue( keyword,
+ io_buffer,
+ io_buflen,
+ i_target,
+ memType );
+
+ if( err )
+ {
+ break;
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Invalid Basic Memory Type (0x%04x)",
+ memType );
+
+ /*@
+ * @errortype
+ * @reasoncode SPD_INVALID_BASIC_MEMORY_TYPE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SPD_WRITE_KEYWORD_VALUE
+ * @userdata1 Basic Memory Type (Byte 2)
+ * @userdata2 Keyword Requested
+ * @devdesc Invalid Basic Memory Type
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SPD_WRITE_KEYWORD_VALUE,
+ SPD_INVALID_BASIC_MEMORY_TYPE,
+ memType,
+ keyword );
+
+ break;
+ }
} while( 0 );
TRACSSCOMP( g_trac_spd,
@@ -281,12 +316,12 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
do
{
- if( g_readPNOR )
+ if( likely( g_usePNOR ) )
{
// Setup info needed to read from PNOR
pnorInformation info;
- info.sectionSize = DIMM_SPD_SECTION_SIZE;
- info.maxSections = DIMM_SPD_MAX_SECTIONS;
+ info.segmentSize = DIMM_SPD_SECTION_SIZE;
+ info.maxSegments = DIMM_SPD_MAX_SECTIONS;
info.pnorSection = PNOR::DIMM_JEDEC_VPD;
info.pnorSide = PNOR::SIDELESS;
err = readPNOR( i_byteAddr,
@@ -323,82 +358,123 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
// ------------------------------------------------------------------
-// spdGetValue
+// spdWriteData
// ------------------------------------------------------------------
-errlHndl_t spdGetValue ( uint64_t i_keyword,
- void * io_buffer,
- size_t & io_buflen,
- TARGETING::Target * i_target,
- uint64_t i_DDRRev )
+errlHndl_t spdWriteData ( uint64_t i_offset,
+ size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target )
{
errlHndl_t err = NULL;
- uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
- KeywordData * kwdData;
- uint32_t arraySize = 0x0;
TRACSSCOMP( g_trac_spd,
- ENTER_MRK"spdGetValue()" );
+ ENTER_MRK"spdWriteData()" );
do
{
- if( SPD_DDR3 == i_DDRRev )
+ if( likely( g_usePNOR ) )
{
- // Put the table into an array
- arraySize = (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
- kwdData = ddr3Data;
+ // Setup info needed to write from PNOR
+ pnorInformation info;
+ info.segmentSize = DIMM_SPD_SECTION_SIZE;
+ info.maxSegments = DIMM_SPD_MAX_SECTIONS;
+ info.pnorSection = PNOR::DIMM_JEDEC_VPD;
+ info.pnorSide = PNOR::SIDELESS;
+ err = writePNOR( i_offset,
+ i_numBytes,
+ i_data,
+ i_target,
+ info,
+ g_spdPnorAddr,
+ &g_spdMutex );
+
+ if( err )
+ {
+ break;
+ }
}
else
{
TRACFCOMP( g_trac_spd,
- ERR_MRK"Unsupported DDRx Revision (0x%04x)",
- i_DDRRev );
+ ERR_MRK"There is no way to write SPD when not using PNOR!" );
/*@
* @errortype
- * @reasoncode SPD_INVALID_BASIC_MEMORY_TYPE
+ * @reasoncode SPD_INVALID_WRITE_METHOD
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid SPD_GET_VALUE
- * @userdata1 SPD Keyword
- * @userdata2 The DDR Revision
- * @devdesc Invalid DDR Revision
+ * @moduleid SPD_WRITE_DATA
+ * @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,
- SPD_GET_VALUE,
- SPD_INVALID_BASIC_MEMORY_TYPE,
- i_keyword,
- i_DDRRev );
+ SPD_WRITE_DATA,
+ SPD_INVALID_WRITE_METHOD,
+ i_offset,
+ i_numBytes );
break;
}
+ } while( 0 );
- // Set the searching structure equal to the keyword we're looking for.
- KeywordData tmpKwdData;
- tmpKwdData.keyword = i_keyword;
- KeywordData * entry = std::lower_bound( kwdData,
- &kwdData[arraySize],
- tmpKwdData,
- compareEntries );
+ TRACSSCOMP( g_trac_spd,
+ EXIT_MRK"spdWriteData()" );
- if( ( entry == &kwdData[arraySize] ) ||
- ( i_keyword != entry->keyword ) )
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// spdGetValue
+// ------------------------------------------------------------------
+errlHndl_t spdGetValue ( uint64_t i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev )
+{
+ errlHndl_t err = NULL;
+ uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
+
+ TRACSSCOMP( g_trac_spd,
+ ENTER_MRK"spdGetValue()" );
+
+ do
+ {
+ KeywordData * entry = NULL;
+ err = getKeywordEntry( i_keyword,
+ i_DDRRev,
+ entry );
+
+ if( err )
+ {
+ break;
+ }
+
+ // Check to be sure entry is not NULL.
+ if( NULL == entry )
{
TRACFCOMP( g_trac_spd,
- ERR_MRK"No matching keyword entry found!" );
+ ERR_MRK"Entry Pointer is NULL!" );
/*@
* @errortype
- * @reasoncode SPD_KEYWORD_NOT_FOUND
+ * @reasoncode SPD_NULL_ENTRY
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid SPD_GET_VALUE
* @userdata1 SPD Keyword
- * @userdata2 <UNUSED>
- * @devdesc Invalid SPD Keyword
+ * @userdata2[0:31] Buffer Size
+ * @userdata2[32:63] Memory Type
+ * @devdesc The table entry associated with keyword was
+ * NULL.
*/
err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
SPD_GET_VALUE,
- SPD_KEYWORD_NOT_FOUND,
+ SPD_NULL_ENTRY,
i_keyword,
- 0x0 );
+ TWO_UINT32_TO_UINT64( io_buflen,
+ i_DDRRev ) );
break;
}
@@ -476,6 +552,126 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
// ------------------------------------------------------------------
+// spdWriteValue
+// ------------------------------------------------------------------
+errlHndl_t spdWriteValue ( uint64_t i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev )
+{
+ errlHndl_t err = NULL;
+
+ TRACSSCOMP( g_trac_spd,
+ ENTER_MRK"spdWriteValue()" );
+
+ do
+ {
+ KeywordData * entry = NULL;
+ err = getKeywordEntry( i_keyword,
+ i_DDRRev,
+ entry );
+
+ if( err )
+ {
+ break;
+ }
+
+ if( NULL == entry )
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Entry pointer is NULL!" );
+
+ /*@
+ * @errortype
+ * @reasoncode SPD_NULL_ENTRY
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SPD_WRITE_VALUE
+ * @userdata1 SPD Keyword
+ * @userdata2[0:31] Buffer Length
+ * @userdata2[32:63] Memory Type
+ * @devdesc The table entry associated with keyword was
+ * NULL.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SPD_WRITE_VALUE,
+ SPD_NULL_ENTRY,
+ i_keyword,
+ TWO_UINT32_TO_UINT64( io_buflen,
+ i_DDRRev ) );
+
+ break;
+ }
+
+ // 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;
+ }
+
+ // Write value
+ err = spdWriteData( entry->offset,
+ io_buflen,
+ io_buffer,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+
+ // Send mbox message with new data to Fsp
+ err = spdSendMboxWriteMsg();
+
+ if( err )
+ {
+ break;
+ }
+ }
+ else
+ {
+ // Error if not writable
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Trying to write keyword (0x%04x) that is non-"
+ "writable",
+ i_keyword );
+
+ /*@
+ * @errortype
+ * @reasoncode SPD_KEYWORD_NOT_WRITABLE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SPD_WRITE_VALUE
+ * @userdata1 SPD Keyword
+ * @userdata2[0:31] Buffer Length
+ * @userdata2[32:63] Memory Type
+ * @devdesc The SPD Keyword is not writable.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SPD_WRITE_VALUE,
+ SPD_KEYWORD_NOT_WRITABLE,
+ i_keyword,
+ TWO_UINT32_TO_UINT64( io_buflen,
+ i_DDRRev ) );
+
+ break;
+ }
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_spd,
+ EXIT_MRK"spdWriteValue()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
// spdSpecialCases
// ------------------------------------------------------------------
errlHndl_t spdSpecialCases ( KeywordData i_kwdData,
@@ -820,6 +1016,33 @@ errlHndl_t spdReadBinaryFile ( uint64_t i_byteAddr,
// ------------------------------------------------------------------
+// spdSendMboxWriteMsg
+// ------------------------------------------------------------------
+errlHndl_t spdSendMboxWriteMsg ( void )
+{
+ errlHndl_t err = NULL;
+
+ TRACSSCOMP( g_trac_spd,
+ ENTER_MRK"spdSendMboxWriteMsg()" );
+
+ do
+ {
+ // TODO - Since all writes to SPD will be greather than 16 bytes,
+ // there is a need for the "extra_data" option from mbox. This is not
+ // available as of yet.
+ //
+ // This will be implemented with Story 41365, which cannot be done
+ // until story 34032 has been completed.
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_spd,
+ EXIT_MRK"spdSendMboxWriteMsg()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
// readPNOR
// ------------------------------------------------------------------
errlHndl_t readPNOR ( uint64_t i_byteAddr,
@@ -864,7 +1087,7 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr,
}
// Offset cached address by vpd location multiplier
- addr += (vpdLocation * i_pnorInfo.sectionSize);
+ addr += (vpdLocation * i_pnorInfo.segmentSize);
// Now offset into that chunk of data by i_byteAddr
addr += i_byteAddr;
@@ -888,6 +1111,74 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr,
// ------------------------------------------------------------------
+// writePNOR
+// ------------------------------------------------------------------
+errlHndl_t writePNOR ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target,
+ pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t * i_mutex )
+{
+ errlHndl_t err = NULL;
+ int64_t vpdLocation = 0;
+ uint64_t addr = 0x0;
+ const char * writeAddr = NULL;
+
+ TRACSSCOMP( g_trac_spd,
+ ENTER_MRK"writePNOR()" );
+
+ do
+ {
+ // Check if we have the PNOR addr cached.
+ if( 0x0 == io_cachedAddr )
+ {
+ err = getPnorAddr( i_pnorInfo,
+ io_cachedAddr,
+ i_mutex );
+
+ if( err )
+ {
+ break;
+ }
+ }
+ addr = io_cachedAddr;
+
+ // Find vpd location of the target
+ err = getVpdLocation( vpdLocation,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+
+ // Offset cached address by vpd location multiplier
+ addr += (vpdLocation * i_pnorInfo.segmentSize);
+
+ // Now offset into that chunk of data by i_byteAddr
+ addr += i_byteAddr;
+
+ TRACUCOMP( g_trac_spd,
+ INFO_MRK"Address to write: 0x%08x",
+ addr );
+
+ // Write the data
+ writeAddr = reinterpret_cast<const char*>( addr );
+ memcpy( (void*)(writeAddr),
+ i_data,
+ i_numBytes );
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_spd,
+ EXIT_MRK"writePNOR()" );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
// getPnorAddr
// ------------------------------------------------------------------
errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo,
@@ -913,7 +1204,7 @@ errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo,
}
// Check the Size
- uint32_t expectedSize = i_pnorInfo.sectionSize * i_pnorInfo.maxSections;
+ uint32_t expectedSize = i_pnorInfo.segmentSize * i_pnorInfo.maxSegments;
if( expectedSize != info.size )
{
TRACFCOMP( g_trac_spd,
@@ -1209,4 +1500,114 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
}
+// ------------------------------------------------------------------
+// getMemType
+// ------------------------------------------------------------------
+errlHndl_t getMemType ( uint8_t & o_memType,
+ TARGETING::Target * i_target )
+{
+ errlHndl_t err = NULL;
+
+ err = spdFetchData( MEM_TYPE_ADDR,
+ MEM_TYPE_ADDR_SZ,
+ &o_memType,
+ i_target );
+
+ TRACUCOMP( g_trac_spd,
+ "SPD::getMemType() - MemType: 0x%02x, Error: %s",
+ o_memType,
+ ((NULL == err) ? "No" : "Yes") );
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// getKeywordEntry
+// ------------------------------------------------------------------
+errlHndl_t getKeywordEntry ( uint64_t i_keyword,
+ uint64_t i_memType,
+ KeywordData *& o_entry )
+{
+ errlHndl_t err = NULL;
+ KeywordData * kwdData;
+ uint32_t arraySize = 0x0;
+
+ TRACSSCOMP( g_trac_spd,
+ ENTER_MRK"getKeywordEntry()" );
+
+ do
+ {
+ if( SPD_DDR3 == i_memType )
+ {
+ // Put the table into an array
+ arraySize = (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ kwdData = ddr3Data;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Unsupported DDRx Revision (0x%04x)",
+ i_memType );
+
+ /*@
+ * @errortype
+ * @reasoncode SPD_INVALID_BASIC_MEMORY_TYPE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SPD_GET_KEYWORD_ENTRY
+ * @userdata1 SPD Keyword
+ * @userdata2 The DDR Revision
+ * @devdesc Invalid DDR Revision
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SPD_GET_KEYWORD_ENTRY,
+ SPD_INVALID_BASIC_MEMORY_TYPE,
+ i_keyword,
+ i_memType );
+
+ break;
+ }
+
+ // Set the searching structure equal to the keyword we're looking for.
+ KeywordData tmpKwdData;
+ tmpKwdData.keyword = i_keyword;
+ KeywordData * entry = std::lower_bound( kwdData,
+ &kwdData[arraySize],
+ tmpKwdData,
+ compareEntries );
+
+ if( ( entry == &kwdData[arraySize] ) ||
+ ( i_keyword != entry->keyword ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"No matching keyword entry found!" );
+
+ /*@
+ * @errortype
+ * @reasoncode SPD_KEYWORD_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SPD_GET_KEYWORD_ENTRY
+ * @userdata1 SPD Keyword
+ * @userdata2 <UNUSED>
+ * @devdesc Invalid SPD Keyword
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SPD_GET_KEYWORD_ENTRY,
+ SPD_KEYWORD_NOT_FOUND,
+ i_keyword,
+ 0x0 );
+
+ break;
+ }
+
+ o_entry = entry;
+ } while( 0 );
+
+ TRACSSCOMP( g_trac_spd,
+ EXIT_MRK"getKeywordEntry()" );
+
+ return err;
+}
+
+
} // end namespace SPD
diff --git a/src/usr/spd/spd.H b/src/usr/spd/spd.H
index f8ad6da5a..a5bf27c5c 100755
--- a/src/usr/spd/spd.H
+++ b/src/usr/spd/spd.H
@@ -84,15 +84,14 @@ struct KeywordData
uint8_t bitMask; // Bit mask
uint8_t shift; // Used for fields < 1 byte to right justify all values.
bool isSpecialCase; // Whether or not this entry is a special case.
+ bool writable; // Whether this keyword can be written to.
modSpecTypes_t modSpec; // Module Specific type keyword is valid for.
};
/**
-*
-* @brief Perform an SPD operation. It follows a pre-defined
-* prototype function in order to be registered with the device
-* driver framework.
+ * @brief This function is used to read SPD keywords from collected
+ * SPD data for the given target
*
* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
* driververif.H
@@ -100,11 +99,10 @@ struct KeywordData
* @param[in] i_target - DIMM 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.
+* the target 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
+* @param [in/out] io_buflen - Length of the buffer to be read
+* 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.
*
@@ -113,60 +111,48 @@ struct KeywordData
*
* @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 spdAccess ( 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 is used to read SPD keywords from collected
- * SPD data for the given target
- *
- * @param[in] i_keyword - The SPD keyword to access.
- *
- * @param[in/out] io_buffer - The buffer that will contain the data
- * read from the SPD data.
- *
- * @param[in/out] io_buflen - The requested number of bytes to read.
- * The actual number of bytes read will be returned.
- *
- * @param[in] i_target - The target DIMM to access the data for.
*
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
-errlHndl_t spdGetKeywordValue ( uint64_t i_keyword,
+errlHndl_t spdGetKeywordValue ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
void * io_buffer,
size_t & io_buflen,
- TARGETING::Target * i_target );
+ int64_t i_accessType,
+ va_list i_args );
/**
* @brief This function is used to write SPD keyword values.
- *
- * @param[in] i_keyword - The SPD keyword to access.
- *
- * @param[in/out] io_buffer - The buffer that will contain the data
- * read from the SPD data.
- *
- * @param[in/out] io_buflen - The requested number of bytes to read.
- * The actual number of bytes read will be returned.
- *
- * @param[in] i_target - The target DIMM to access the data for.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driververif.H
+*
+* @param[in] i_target - DIMM Target device
+*
+* @param [in/out] io_buffer - Pointer to the data that will contain data
+* to be written to the device.
+*
+* @param [in/out] io_buflen - Length of the buffer to be written
+* to 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 written to the target.
+*
+* @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 spdWriteKeywordValue ( uint64_t i_keyword,
+errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
void * io_buffer,
size_t & io_buflen,
- TARGETING::Target * i_target );
+ int64_t i_accessType,
+ va_list i_args );
/**
* @param This function is a wrapper for reading the correct keyword.
@@ -190,6 +176,28 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
TARGETING::Target * i_target );
/**
+ * @brief This function is a wrapper for writing the correct keyword.
+ * It will route the write to whatever function has the latest
+ * supported access code.
+ *
+ * @param[in] i_offset - The offset into the JEDEC SPD layout.
+ *
+ * @param[in] i_numbytes - Number of bytes to read.
+ *
+ * @param[in] i_data - The data buffer that will return the data read.
+ *
+ * @param[in] i_target - The target DIMM to access.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t spdWriteData ( uint64_t i_offset,
+ size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target );
+
+
+/**
* @param This function will read the SPD keyword from the appropriate
* table.
*
@@ -214,6 +222,33 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
TARGETING::Target * i_target,
uint64_t i_DDRRev );
+
+/**
+ * @brief This function will write the SPD keyword from the appropriate
+ * table.
+ *
+ * @param[in] i_keyword - The SPD keyword to access.
+ *
+ * @param[in/out] io_buffer - The buffer that will contain the data
+ * written from the SPD data.
+ *
+ * @param[in/out] io_buflen - The requested number of bytes to write.
+ * The actual number of bytes written will be returned.
+ *
+ * @param[in] i_target - The target DIMM to access the data for.
+ *
+ * @param[in] i_DDRRev - The DIMM DDR Revision.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t spdWriteValue ( uint64_t i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev );
+
+
/**
* @param This function handles the special case keywords where
* the data isn't sequential, or is broken up between two different
@@ -357,6 +392,86 @@ errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo,
errlHndl_t getVpdLocation ( int64_t & o_vpdLocation,
TARGETING::Target * i_target );
+
+/**
+ * @brief This function will read the PNOR at the correct offset and number of
+ * bytes for the keyword requested.
+ *
+ * @param[in] i_byteAddr - The offset to access in the PNOR.
+ *
+ * @param[in] i_numBytes - Number of bytes to read.
+ *
+ * @param[out] o_data - The data buffer that the read data will be placed
+ * into.
+ *
+ * @param[in] i_target - The chip target to access the data for.
+ *
+ * @param[in] i_pnorInfo - Information about the PNOR section and side that we
+ * need to know to make the request.
+ *
+ * @param[in/out] io_cachedAddr - The address offset to the data chunk in
+ * PNOR.
+ *
+ * @param[in] i_mutex - The mutex to lock/unlock while setting io_isAddrCached
+ * and io_cachedAddr. It is assumed that those parameters are global
+ * variables in the code where they reside.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the error
+ * log.
+ */
+errlHndl_t readPNOR ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t i_mutex );
+
+/**
+ * @brief This function will write the PNOR at the correct offset and number
+ * of bytes for the keyword requested.
+ *
+ * @param[in] i_byteAddr - The offset to access in the PNOR.
+ *
+ * @param[in] i_numBytes - The number of bytes to write.
+ *
+ * @param[in] i_data - The data buffer of the data to be written.
+ *
+ * @param[in] i_target - The chip target to access the data for.
+ *
+ * @param[in] i_pnorInfo - Information about the PNOR section and side that we
+ * need to know to make the request.
+ *
+ * @param[in/out] io_cachedAddr - The address offset to the data chunk in
+ * PNOR.
+ *
+ * @param[in] i_mutex - The mutex to lock/unlock while setting io_isAddrCached
+ * and io_cachedAddr. It is assumed that those parameters are global
+ * variables in the code where they reside.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the error
+ * log.
+ */
+errlHndl_t writePNOR ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * i_data,
+ TARGETING::Target * i_target,
+ pnorInformation & i_pnorInfo,
+ uint64_t &io_cachedAddr,
+ mutex_t * i_mutex );
+
+/**
+ * @brief This function handles sending the mailbox message to the Fsp to
+ * notify of updates to the data.
+ *
+ * TODO with Story 41365
+ * @param NONE, yet.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the error
+ * log.
+ */
+errlHndl_t spdSendMboxWriteMsg ( void );
+
}; // end SPD namespace
#endif // __SPD_H
diff --git a/src/usr/spd/spdDDR3.H b/src/usr/spd/spdDDR3.H
index b60ce34a8..35f17846e 100755
--- a/src/usr/spd/spdDDR3.H
+++ b/src/usr/spd/spdDDR3.H
@@ -53,206 +53,206 @@ KeywordData ddr3Data[] =
//
// Special cases listed below will be handled out of the normal table lookup
// handler code.
- // ----------------------------------------------------------------------------------
- // Keyword offset size Use Bitmsk Shift
- // Bitmsk Number
- // ----------------------------------------------------------------------------------
- { CRC_EXCLUDE, 0x00, 0x01, true, 0x80, 0x07, false, NA },
- { SPD_BYTES_TOTAL, 0x00, 0x01, true, 0x70, 0x04, false, NA },
- { SPD_BYTES_USED, 0x00, 0x01, true, 0x0F, 0x00, false, NA },
- { SPD_MAJOR_REVISION, 0x01, 0x01, true, 0xF0, 0x04, false, NA },
- { SPD_MINOR_REVISION, 0x01, 0x01, true, 0x0F, 0x00, false, NA },
- { BASIC_MEMORY_TYPE, 0x02, 0x01, false, 0x00, 0x00, false, NA },
- { MODULE_TYPE, 0x03, 0x01, true, 0x0F, 0x00, false, NA },
- { BANK_ADDRESS_BITS, 0x04, 0x01, true, 0x70, 0x04, false, NA },
- { DENSITY, 0x04, 0x01, true, 0x0F, 0x00, false, NA },
- { ROW_ADDRESS, 0x05, 0x01, true, 0x38, 0x03, false, NA },
- { COL_ADDRESS, 0x05, 0x01, true, 0x07, 0x00, false, NA },
- { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, true, 0x07, 0x00, false, NA },
- { MODULE_RANKS, 0x07, 0x01, true, 0x38, 0x03, false, NA },
- { MODULE_DRAM_WIDTH, 0x07, 0x01, true, 0x07, 0x00, false, NA },
- { ECC_BITS, 0x08, 0x01, true, 0x18, 0x03, false, NA },
- { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, true, 0x07, 0x00, false, NA },
- { FTB_DIVIDEND, 0x09, 0x01, true, 0xF0, 0x04, false, NA },
- { FTB_DIVISOR, 0x09, 0x01, true, 0x0F, 0x00, false, NA },
- { MTB_DIVIDEND, 0x0a, 0x01, false, 0x00, 0x00, false, NA },
- { MTB_DIVISOR, 0x0b, 0x01, false, 0x00, 0x00, false, NA },
- { TCK_MIN, 0x0c, 0x01, false, 0x00, 0x00, false, NA },
- { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, true, 0x7F, 0x00, true, NA },
- { MIN_CAS_LATENCY, 0x10, 0x01, false, 0x00, 0x00, false, NA },
- { TWR_MIN, 0x11, 0x01, false, 0x00, 0x00, false, NA },
- { TRCD_MIN, 0x12, 0x01, false, 0x00, 0x00, false, NA },
- { TRRD_MIN, 0x13, 0x01, false, 0x00, 0x00, false, NA },
- { TRP_MIN, 0x14, 0x01, false, 0x00, 0x00, false, NA },
- { TRC_MIN, 0x15, 0x02, true, 0xF0, 0x04, true, NA },
- { TRAS_MIN, 0x15, 0x02, true, 0x0F, 0x00, true, NA },
- { TRFC_MIN, 0x19, 0x02, false, 0x00, 0x00, true, NA },
- { TWTR_MIN, 0x1a, 0x01, false, 0x00, 0x00, false, NA },
- { TRTP_MIN, 0x1b, 0x01, false, 0x00, 0x00, false, NA },
- { TFAW_MIN, 0x1c, 0x02, true, 0x0F, 0x00, true, NA },
- { DLL_OFF, 0x1e, 0x01, true, 0x80, 0x07, false, NA },
- { RZQ_7, 0x1e, 0x01, true, 0x02, 0x01, false, NA },
- { RZQ_6, 0x1e, 0x01, true, 0x01, 0x00, false, NA },
- { PASR, 0x1f, 0x01, true, 0x80, 0x07, false, NA },
- { ODTS, 0x1f, 0x01, true, 0x08, 0x03, false, NA },
- { ASR, 0x1f, 0x01, true, 0x04, 0x02, false, NA },
- { ETR_1X, 0x1f, 0x01, true, 0x02, 0x01, false, NA },
- { ETR, 0x1f, 0x01, true, 0x01, 0x00, false, NA },
- { THERMAL_SENSOR_PRESENT, 0x20, 0x01, true, 0x80, 0x07, false, NA },
- { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, true, 0x7F, 0x00, false, NA },
- { SDRAM_DEVICE_TYPE_NONSTD, 0x21, 0x01, true, 0x80, 0x07, false, NA },
- { SDRAM_DEVICE_TYPE, 0x21, 0x01, true, 0x7F, 0x00, false, NA },
- { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, false, 0x00, 0x00, false, NA },
- { MODULE_MANUFACTURER_ID, 0x76, 0x02, false, 0x00, 0x00, true, NA },
- { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, false, 0x00, 0x00, false, NA },
- { MODULE_MANUFACTURING_DATE, 0x78, 0x02, false, 0x00, 0x00, false, NA },
- { MODULE_SERIAL_NUMBER, 0x7a, 0x04, false, 0x00, 0x00, false, NA },
- { MODULE_CRC, 0x7e, 0x02, false, 0x00, 0x00, false, NA },
- { MODULE_PART_NUMBER, 0x80, 0x12, false, 0x00, 0x00, false, NA },
- { MODULE_REVISION_CODE, 0x92, 0x02, false, 0x00, 0x00, false, NA },
- { DRAM_MANUFACTURER_ID, 0x95, 0x02, false, 0x00, 0x00, true, NA },
- { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, false, 0x00, 0x00, false, NA },
- { TCKMIN_FINE_OFFSET, 0x22, 0x01, false, 0x00, 0x00, false, NA },
- { TAAMIN_FINE_OFFSET, 0x23, 0x01, false, 0x00, 0x00, false, NA },
- { TRCDMIN_FINE_OFFSET, 0x24, 0x01, false, 0x00, 0x00, false, NA },
- { TRPMIN_FINE_OFFSET, 0x25, 0x01, false, 0x00, 0x00, false, NA },
- { TRCMIN_FINE_OFFSET, 0x26, 0x01, false, 0x00, 0x00, false, NA },
- { MODULE_THERMAL_SENSOR, 0x20, 0x01, false, 0x00, 0x00, false, NA },
- { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, false, 0x00, 0x00, false, NA },
- { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, false, 0x00, 0x00, false, NA },
- { DIMM_BAD_DQ_DATA, 0xb0, 0x50, false, 0x00, 0x00, false, NA },
- { MODSPEC_COM_NOM_HEIGHT_MAX, 0x3c, 0x01, true, 0x0f, 0x00, false, ALL },
- { MODSPEC_COM_MAX_THICK_BACK, 0x3d, 0x01, true, 0xf0, 0x04, false, ALL },
- { MODSPEC_COM_MAX_THICK_FRONT, 0x3d, 0x01, true, 0x0f, 0x00, false, ALL },
- { MODSPEC_COM_RAW_CARD_EXT, 0x3e, 0x01, true, 0x80, 0x07, false, ALL },
- { MODSPEC_COM_RAW_CARD_REV, 0x3e, 0x01, true, 0x60, 0x05, false, ALL },
- { MODSPEC_COM_RAW_CARD, 0x3e, 0x01, true, 0x0f, 0x00, false, ALL },
- { MODSPEC_COM_ADDR_MAPPING, 0x3f, 0x01, true, 0x01, 0x00, false, ALL },
- { RMM_ROWS_RDIMM, 0x3f, 0x01, true, 0x0c, 0x02, false, RMM },
- { RMM_REGS_RDIMM, 0x3f, 0x01, true, 0x03, 0x00, false, RMM },
- { RMM_HEAT_SP, 0x40, 0x01, true, 0x80, 0x07, false, RMM },
- { RMM_HEAT_SP_CHARS, 0x40, 0x01, true, 0x7F, 0x00, false, RMM },
- { RMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, RMM },
- { RMM_REG_REV_NUM, 0x43, 0x01, false, 0x00, 0x00, false, RMM },
- { RMM_REG_TYPE, 0x44, 0x01, true, 0x07, 0x00, false, RMM },
- { RMM_RC1, 0x45, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC0, 0x45, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC3, 0x46, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC2, 0x46, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC5, 0x47, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC4, 0x47, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC7, 0x48, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC6, 0x48, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC9, 0x49, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC8, 0x49, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC11, 0x4a, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC10, 0x4a, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC13, 0x4b, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC12, 0x4b, 0x01, true, 0x0f, 0x00, false, RMM },
- { RMM_RC15, 0x4c, 0x01, true, 0xf0, 0x04, false, RMM },
- { RMM_RC14, 0x4c, 0x01, true, 0x0f, 0x00, false, RMM },
- { LRMM_HEAT_SP, 0x3f, 0x01, true, 0x80, 0x07, false, LRMM },
- { LRMM_RANK_NUMBERING, 0x3f, 0x01, true, 0x20, 0x05, false, LRMM },
- { LRMM_MEMBUF_ORIEN, 0x3f, 0x01, true, 0x10, 0x04, false, LRMM },
- { LRMM_NUM_ROWS, 0x3f, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_MIRRORING, 0x3f, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_REVISION_NUM, 0x40, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, LRMM },
- { LRMM_F0RC3, 0x43, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F0RC2, 0x43, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F0RC5, 0x44, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F0RC4, 0x44, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F1RC11, 0x45, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F1RC8, 0x45, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F1RC13, 0x46, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F1RC12, 0x46, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F1RC15, 0x47, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F1RC14, 0x47, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F3RC9_800_1600, 0x48, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F3RC8_800_1600, 0x48, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F4RC11_800_1600, 0x49, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F3RC11_800_1600, 0x49, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F4RC10_800_1600, 0x49, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F3RC10_800_1600, 0x49, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F6RC11_800_1600, 0x4a, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F5RC11_800_1600, 0x4a, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F6RC10_800_1600, 0x4a, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F5RC10_800_1600, 0x4a, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F8RC11_800_1600, 0x4b, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F7RC11_800_1600, 0x4b, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F8RC10_800_1600, 0x4b, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F7RC10_800_1600, 0x4b, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F10RC11_800_1600, 0x4c, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F9RC11_800_1600, 0x4c, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F10RC10_800_1600, 0x4c, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F9RC10_800_1600, 0x4c, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_RTT_WR_800_1600, 0x4d, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_RTT_NOM_800_1600, 0x4d, 0x01, true, 0x1c, 0x02, false, LRMM },
- { LRMM_IMPEDANCE_800_1600, 0x4d, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F3RC9_1333_1600, 0x4e, 0x01, true, 0xF0, 0x04, false, LRMM },
- { LRMM_F3RC8_1333_1600, 0x4e, 0x01, true, 0x0F, 0x00, false, LRMM },
- { LRMM_F4RC11_1333_1600, 0x4f, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F3RC11_1333_1600, 0x4f, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F4RC10_1333_1600, 0x4f, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F3RC10_1333_1600, 0x4f, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F6RC11_1333_1600, 0x50, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F5RC11_1333_1600, 0x50, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F6RC10_1333_1600, 0x50, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F5RC10_1333_1600, 0x50, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F8RC11_1333_1600, 0x51, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F7RC11_1333_1600, 0x51, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F8RC10_1333_1600, 0x51, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F7RC10_1333_1600, 0x51, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F10RC11_1333_1600, 0x52, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F9RC11_1333_1600, 0x52, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F10RC10_1333_1600, 0x52, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F9RC10_1333_1600, 0x52, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_RTT_WR_1333_1600, 0x53, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_RTT_NOM_1333_1600, 0x53, 0x01, true, 0x1c, 0x02, false, LRMM },
- { LRMM_IMPEDANCE_1333_1600, 0x53, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F3RC9_1866_2133, 0x54, 0x01, true, 0xf0, 0x04, false, LRMM },
- { LRMM_F3RC8_1866_2133, 0x54, 0x01, true, 0x0f, 0x00, false, LRMM },
- { LRMM_F4RC11_1866_2133, 0x55, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F3RC11_1866_2133, 0x55, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F4RC10_1866_2133, 0x55, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F3RC10_1866_2133, 0x55, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F6RC11_1866_2133, 0x56, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F5RC11_1866_2133, 0x56, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F6RC10_1866_2133, 0x56, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F5RC10_1866_2133, 0x56, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F8RC11_1866_2133, 0x57, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F7RC11_1866_2133, 0x57, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F8RC10_1866_2133, 0x57, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F7RC10_1866_2133, 0x57, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_F10RC11_1866_2133, 0x58, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_F9RC11_1866_2133, 0x58, 0x01, true, 0x30, 0x04, false, LRMM },
- { LRMM_F10RC10_1866_2133, 0x58, 0x01, true, 0x0c, 0x02, false, LRMM },
- { LRMM_F9RC10_1866_2133, 0x58, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_RTT_WR_1866_2133, 0x59, 0x01, true, 0xc0, 0x06, false, LRMM },
- { LRMM_RTT_NOM_1866_2133, 0x59, 0x01, true, 0x1c, 0x02, false, LRMM },
- { LRMM_IMPEDANCE_1866_2133, 0x59, 0x01, true, 0x03, 0x00, false, LRMM },
- { LRMM_MIN_DELAY_150V, 0x5a, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_MAX_DELAY_150V, 0x5b, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_MIN_DELAY_135V, 0x5c, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_MAX_DELAY_135V, 0x5d, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_MIN_DELAY_125V, 0x5e, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_MAX_DELAY_125V, 0x5f, 0x01, true, 0x7f, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE0, 0x66, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE1, 0x67, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE2, 0x68, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE3, 0x69, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE4, 0x6a, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE5, 0x6b, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE6, 0x6c, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE7, 0x6d, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE8, 0x6e, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE9, 0x6f, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE10, 0x70, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE11, 0x71, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE12, 0x72, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE13, 0x73, 0x01, false, 0x00, 0x00, false, LRMM },
- { LRMM_PERSONALITY_BYTE14, 0x74, 0x01, false, 0x00, 0x00, false, LRMM },
- // ----------------------------------------------------------------------------------
+ // ---------------------------------------------------------------------------------------
+ // Keyword offset size Use Bitmsk Shift Spec Writ- Mod
+ // Bitmsk Number Case able Spec
+ // ---------------------------------------------------------------------------------------
+ { CRC_EXCLUDE, 0x00, 0x01, true, 0x80, 0x07, false, false, NA },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, true, 0x70, 0x04, false, false, NA },
+ { SPD_BYTES_USED, 0x00, 0x01, true, 0x0F, 0x00, false, false, NA },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, true, 0xF0, 0x04, false, false, NA },
+ { SPD_MINOR_REVISION, 0x01, 0x01, true, 0x0F, 0x00, false, false, NA },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, false, 0x00, 0x00, false, false, NA },
+ { MODULE_TYPE, 0x03, 0x01, true, 0x0F, 0x00, false, false, NA },
+ { BANK_ADDRESS_BITS, 0x04, 0x01, true, 0x70, 0x04, false, false, NA },
+ { DENSITY, 0x04, 0x01, true, 0x0F, 0x00, false, false, NA },
+ { ROW_ADDRESS, 0x05, 0x01, true, 0x38, 0x03, false, false, NA },
+ { COL_ADDRESS, 0x05, 0x01, true, 0x07, 0x00, false, false, NA },
+ { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, true, 0x07, 0x00, false, false, NA },
+ { MODULE_RANKS, 0x07, 0x01, true, 0x38, 0x03, false, false, NA },
+ { MODULE_DRAM_WIDTH, 0x07, 0x01, true, 0x07, 0x00, false, false, NA },
+ { ECC_BITS, 0x08, 0x01, true, 0x18, 0x03, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, true, 0x07, 0x00, false, false, NA },
+ { FTB_DIVIDEND, 0x09, 0x01, true, 0xF0, 0x04, false, false, NA },
+ { FTB_DIVISOR, 0x09, 0x01, true, 0x0F, 0x00, false, false, NA },
+ { MTB_DIVIDEND, 0x0a, 0x01, false, 0x00, 0x00, false, false, NA },
+ { MTB_DIVISOR, 0x0b, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TCK_MIN, 0x0c, 0x01, false, 0x00, 0x00, false, false, NA },
+ { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, true, 0x7F, 0x00, true, false, NA },
+ { MIN_CAS_LATENCY, 0x10, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TWR_MIN, 0x11, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRCD_MIN, 0x12, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRRD_MIN, 0x13, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRP_MIN, 0x14, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRC_MIN, 0x15, 0x02, true, 0xF0, 0x04, true, false, NA },
+ { TRAS_MIN, 0x15, 0x02, true, 0x0F, 0x00, true, false, NA },
+ { TRFC_MIN, 0x19, 0x02, false, 0x00, 0x00, true, false, NA },
+ { TWTR_MIN, 0x1a, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRTP_MIN, 0x1b, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TFAW_MIN, 0x1c, 0x02, true, 0x0F, 0x00, true, false, NA },
+ { DLL_OFF, 0x1e, 0x01, true, 0x80, 0x07, false, false, NA },
+ { RZQ_7, 0x1e, 0x01, true, 0x02, 0x01, false, false, NA },
+ { RZQ_6, 0x1e, 0x01, true, 0x01, 0x00, false, false, NA },
+ { PASR, 0x1f, 0x01, true, 0x80, 0x07, false, false, NA },
+ { ODTS, 0x1f, 0x01, true, 0x08, 0x03, false, false, NA },
+ { ASR, 0x1f, 0x01, true, 0x04, 0x02, false, false, NA },
+ { ETR_1X, 0x1f, 0x01, true, 0x02, 0x01, false, false, NA },
+ { ETR, 0x1f, 0x01, true, 0x01, 0x00, false, false, NA },
+ { THERMAL_SENSOR_PRESENT, 0x20, 0x01, true, 0x80, 0x07, false, false, NA },
+ { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, true, 0x7F, 0x00, false, false, NA },
+ { SDRAM_DEVICE_TYPE_NONSTD, 0x21, 0x01, true, 0x80, 0x07, false, false, NA },
+ { SDRAM_DEVICE_TYPE, 0x21, 0x01, true, 0x7F, 0x00, false, false, NA },
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, false, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURER_ID, 0x76, 0x02, false, 0x00, 0x00, true, false, NA },
+ { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, false, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURING_DATE, 0x78, 0x02, false, 0x00, 0x00, false, false, NA },
+ { MODULE_SERIAL_NUMBER, 0x7a, 0x04, false, 0x00, 0x00, false, false, NA },
+ { MODULE_CRC, 0x7e, 0x02, false, 0x00, 0x00, false, false, NA },
+ { MODULE_PART_NUMBER, 0x80, 0x12, false, 0x00, 0x00, false, false, NA },
+ { MODULE_REVISION_CODE, 0x92, 0x02, false, 0x00, 0x00, false, false, NA },
+ { DRAM_MANUFACTURER_ID, 0x95, 0x02, false, 0x00, 0x00, true, false, NA },
+ { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, false, 0x00, 0x00, false, false, NA },
+ { TCKMIN_FINE_OFFSET, 0x22, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TAAMIN_FINE_OFFSET, 0x23, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRCDMIN_FINE_OFFSET, 0x24, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRPMIN_FINE_OFFSET, 0x25, 0x01, false, 0x00, 0x00, false, false, NA },
+ { TRCMIN_FINE_OFFSET, 0x26, 0x01, false, 0x00, 0x00, false, false, NA },
+ { MODULE_THERMAL_SENSOR, 0x20, 0x01, false, 0x00, 0x00, false, false, NA },
+ { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, false, 0x00, 0x00, false, false, NA },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, false, 0x00, 0x00, false, false, NA },
+ { DIMM_BAD_DQ_DATA, 0xb0, 0x50, false, 0x00, 0x00, false, true, NA },
+ { MODSPEC_COM_NOM_HEIGHT_MAX, 0x3c, 0x01, true, 0x0f, 0x00, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_BACK, 0x3d, 0x01, true, 0xf0, 0x04, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_FRONT, 0x3d, 0x01, true, 0x0f, 0x00, false, false, ALL },
+ { MODSPEC_COM_RAW_CARD_EXT, 0x3e, 0x01, true, 0x80, 0x07, false, false, ALL },
+ { MODSPEC_COM_RAW_CARD_REV, 0x3e, 0x01, true, 0x60, 0x05, false, false, ALL },
+ { MODSPEC_COM_RAW_CARD, 0x3e, 0x01, true, 0x0f, 0x00, false, false, ALL },
+ { MODSPEC_COM_ADDR_MAPPING, 0x3f, 0x01, true, 0x01, 0x00, false, false, ALL },
+ { RMM_ROWS_RDIMM, 0x3f, 0x01, true, 0x0c, 0x02, false, false, RMM },
+ { RMM_REGS_RDIMM, 0x3f, 0x01, true, 0x03, 0x00, false, false, RMM },
+ { RMM_HEAT_SP, 0x40, 0x01, true, 0x80, 0x07, false, false, RMM },
+ { RMM_HEAT_SP_CHARS, 0x40, 0x01, true, 0x7F, 0x00, false, false, RMM },
+ { RMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, false, RMM },
+ { RMM_REG_REV_NUM, 0x43, 0x01, false, 0x00, 0x00, false, false, RMM },
+ { RMM_REG_TYPE, 0x44, 0x01, true, 0x07, 0x00, false, false, RMM },
+ { RMM_RC1, 0x45, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC0, 0x45, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC3, 0x46, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC2, 0x46, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC5, 0x47, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC4, 0x47, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC7, 0x48, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC6, 0x48, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC9, 0x49, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC8, 0x49, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC11, 0x4a, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC10, 0x4a, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC13, 0x4b, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC12, 0x4b, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC15, 0x4c, 0x01, true, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC14, 0x4c, 0x01, true, 0x0f, 0x00, false, false, RMM },
+ { LRMM_HEAT_SP, 0x3f, 0x01, true, 0x80, 0x07, false, false, LRMM },
+ { LRMM_RANK_NUMBERING, 0x3f, 0x01, true, 0x20, 0x05, false, false, LRMM },
+ { LRMM_MEMBUF_ORIEN, 0x3f, 0x01, true, 0x10, 0x04, false, false, LRMM },
+ { LRMM_NUM_ROWS, 0x3f, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_MIRRORING, 0x3f, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_REVISION_NUM, 0x40, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, false, LRMM },
+ { LRMM_F0RC3, 0x43, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F0RC2, 0x43, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F0RC5, 0x44, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F0RC4, 0x44, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC11, 0x45, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC8, 0x45, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC13, 0x46, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC12, 0x46, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC15, 0x47, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC14, 0x47, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_800_1600, 0x48, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_800_1600, 0x48, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_800_1600, 0x49, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_800_1600, 0x49, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_800_1600, 0x49, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_800_1600, 0x49, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_800_1600, 0x4a, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_800_1600, 0x4a, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_800_1600, 0x4a, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_800_1600, 0x4a, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_800_1600, 0x4b, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_800_1600, 0x4b, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_800_1600, 0x4b, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_800_1600, 0x4b, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_800_1600, 0x4c, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_800_1600, 0x4c, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_800_1600, 0x4c, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_800_1600, 0x4c, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_800_1600, 0x4d, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_800_1600, 0x4d, 0x01, true, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_800_1600, 0x4d, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_1333_1600, 0x4e, 0x01, true, 0xF0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_1333_1600, 0x4e, 0x01, true, 0x0F, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_1333_1600, 0x4f, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_1333_1600, 0x4f, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_1333_1600, 0x4f, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_1333_1600, 0x4f, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_1333_1600, 0x50, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_1333_1600, 0x50, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_1333_1600, 0x50, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_1333_1600, 0x50, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_1333_1600, 0x51, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_1333_1600, 0x51, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_1333_1600, 0x51, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_1333_1600, 0x51, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_1333_1600, 0x52, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_1333_1600, 0x52, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_1333_1600, 0x52, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_1333_1600, 0x52, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_1333_1600, 0x53, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_1333_1600, 0x53, 0x01, true, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_1333_1600, 0x53, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_1866_2133, 0x54, 0x01, true, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_1866_2133, 0x54, 0x01, true, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_1866_2133, 0x55, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_1866_2133, 0x55, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_1866_2133, 0x55, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_1866_2133, 0x55, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_1866_2133, 0x56, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_1866_2133, 0x56, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_1866_2133, 0x56, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_1866_2133, 0x56, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_1866_2133, 0x57, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_1866_2133, 0x57, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_1866_2133, 0x57, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_1866_2133, 0x57, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_1866_2133, 0x58, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_1866_2133, 0x58, 0x01, true, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_1866_2133, 0x58, 0x01, true, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_1866_2133, 0x58, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_1866_2133, 0x59, 0x01, true, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_1866_2133, 0x59, 0x01, true, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_1866_2133, 0x59, 0x01, true, 0x03, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_150V, 0x5a, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_150V, 0x5b, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_135V, 0x5c, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_135V, 0x5d, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_125V, 0x5e, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_125V, 0x5f, 0x01, true, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE0, 0x66, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE1, 0x67, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE2, 0x68, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE3, 0x69, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE4, 0x6a, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE5, 0x6b, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE6, 0x6c, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE7, 0x6d, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE8, 0x6e, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE9, 0x6f, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE10, 0x70, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE11, 0x71, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE12, 0x72, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE13, 0x73, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE14, 0x74, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ // ---------------------------------------------------------------------------------------
};
diff --git a/src/usr/spd/test/spdtest.H b/src/usr/spd/test/spdtest.H
index e00abe773..94b6df38b 100755
--- a/src/usr/spd/test/spdtest.H
+++ b/src/usr/spd/test/spdtest.H
@@ -59,6 +59,19 @@ void getDIMMTargets ( TargetHandleList & o_dimmList )
return;
}
+errlHndl_t getMemType( TARGETING::Target * i_target,
+ uint8_t & i_memType )
+{
+ errlHndl_t err = NULL;
+ size_t theSize = 0x1;
+ err = deviceRead( i_target,
+ &i_memType,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+
+ return err;
+}
+
class SPDTest: public CxxTest::TestSuite
{
public:
@@ -100,11 +113,8 @@ class SPDTest: public CxxTest::TestSuite
// Get the DDR revision
uint8_t memType = 0x0;
- size_t memTypeSize = 0x1;
- err = deviceRead( theTarget,
- &memType,
- memTypeSize,
- DEVICE_SPD_ADDRESS( SPD::BASIC_MEMORY_TYPE ) );
+ err = getMemType( theTarget,
+ memType );
if( err )
{
@@ -226,21 +236,81 @@ class SPDTest: public CxxTest::TestSuite
}
// Operate on first DIMM
+ cmds++;
theTarget = dimmList[0];
uint8_t * theData = NULL;
size_t theSize = 0;
- cmds++;
+ // Get Memory Type
+ uint8_t memType = 0x0;
+ err = getMemType( theTarget,
+ memType );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - failed to read memtype!" );
+ errlCommit( err,
+ SPD_COMP_ID );
+ break;
+ }
+
+ // Get the size
+ if( SPD_DDR3 == memType )
+ {
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
+ entry++ )
+ {
+ if( SPD::DIMM_BAD_DQ_DATA == ddr3Data[entry].keyword )
+ {
+ theSize = ddr3Data[entry].length;
+ break;
+ }
+ }
+ }
+ else
+ {
+ fails++;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWrite - memory type: 0x%04x",
+ memType );
+ TS_FAIL( "testSpdWrite - Unsupported Memory Type!" );
+ errlCommit( err,
+ SPD_COMP_ID );
+ break;
+ }
+
+ // Allocate data buffer
+ theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ // Read the data out first
+ err = deviceRead( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
+
+ if( err )
+ {
+ fails++;
+ TS_FAIL( "testSpdWrite - failed to read DIMM Bad DQ data!" );
+ errlCommit( err,
+ SPD_COMP_ID );
+ break;
+ }
+
+ // Write the data back
err = deviceWrite( theTarget,
theData,
theSize,
- DEVICE_SPD_ADDRESS( SPD_FIRST_NORM_KEYWORD ) );
+ DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ) );
- if( NULL == err )
+ if( err )
{
// No error returned, failure
fails++;
- TS_FAIL( "testSpdWrite - No error returned from deviceWrite()" );
+ TS_FAIL( "testSpdWrite - Error writing data to DIMM Bad DQ "
+ "data" );
break;
}
else
@@ -369,6 +439,70 @@ class SPDTest: public CxxTest::TestSuite
fails, cmds );
}
+ /**
+ */
+ void testSpdInvalidWrite ( void )
+ {
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testSpdInvalidWrite()" );
+
+ do
+ {
+ TARGETING::Target * theTarget = NULL;
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidSize - No DIMMs found!" );
+ break;
+ }
+
+ // Test on first DIMM only.
+ theTarget = dimmList[0];
+ size_t theSize = 0x10;
+ uint8_t * theData = static_cast<uint8_t*>(malloc( theSize ));
+
+ cmds++;
+ err = deviceWrite( theTarget,
+ theData,
+ theSize,
+ DEVICE_SPD_ADDRESS( SPD::SPD_FIRST_NORM_KEYWORD ) );
+
+ // clean up the data
+ if( NULL != theData )
+ {
+ delete theData;
+ theData = NULL;
+ }
+
+ if( NULL == err )
+ {
+ fails++;
+ TS_FAIL( "No failure for Invalid Write attempt to "
+ "SPD_FIRST_NORM_KEYWORD" );
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ } while( 0 );
+
+ TRACFCOMP( g_trac_spd,
+ "testSpdInvalidWrite - %d/%d fails",
+ fails, cmds );
+ }
+
/**
* @brief This test will test reading the Module specific keywords.
@@ -546,7 +680,7 @@ class SPDTest: public CxxTest::TestSuite
* order, according to the keyword enumeration, to enable the search
* algorithm to work correctly.
*/
- void testspdDDR3TableOrder( void )
+ void testspdDDR3TableOrder ( void )
{
uint64_t prevKeyword = 0x0;
uint64_t fails = 0x0;
OpenPOWER on IntegriCloud