diff options
author | aalugore <aalugore@us.ibm.com> | 2016-01-22 13:36:14 -0600 |
---|---|---|
committer | Stephen Cprek <smcprek@us.ibm.com> | 2016-04-21 13:51:43 -0500 |
commit | 4f4f097d65e919bcc8bd5706f50ea0f413b8bfef (patch) | |
tree | 90030301032f3a87e952e5c161763bab0ad812be /src/usr/vpd | |
parent | 18e7af4cee8e4a9b88dee257edffb528b969ecd3 (diff) | |
download | talos-hostboot-4f4f097d65e919bcc8bd5706f50ea0f413b8bfef.tar.gz talos-hostboot-4f4f097d65e919bcc8bd5706f50ea0f413b8bfef.zip |
DDR4 - Allow SPD writes
-DDR4 has 512-byte EEPROM with 2 256-byte pages.
This commit contains the necessary page switching
logic to support this.
Change-Id: Iaa8e3e344def98b71d6a9e9387c5e0d9137a0397
RTC:137707
ForwardPort: yes
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/797
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Tested-by: Jenkins OP Build CI
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Reviewed-by: Matthew A. Ploetz <maploetz@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/871
Diffstat (limited to 'src/usr/vpd')
-rw-r--r-- | src/usr/vpd/spd.C | 112 | ||||
-rwxr-xr-x | src/usr/vpd/spdDDR4.H | 4 |
2 files changed, 82 insertions, 34 deletions
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C index 6833e94df..b9b5890b7 100644 --- a/src/usr/vpd/spd.C +++ b/src/usr/vpd/spd.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -258,8 +258,10 @@ errlHndl_t spdGetKeywordValue ( DeviceFW::OperationType i_opType, else { TRACFCOMP( g_trac_spd, - ERR_MRK"Invalid Basic Memory Type (0x%04x)", - memType ); + ERR_MRK"Invalid Basic Memory Type (0x%04x), " + "target huid = 0x%x", + memType, + TARGETING::get_huid(i_target)); /*@ * @errortype @@ -481,11 +483,14 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr, i_byteAddr ) ); if( err ) { + TRACFCOMP(g_trac_spd, + "ERROR: failing out of deviceOp in spd.C"); break; } } else { + TRACFCOMP(g_trac_spd, "spdFetchData: vpd source incorrect!: %x", vpdSource); configError = true; } @@ -2039,18 +2044,29 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) } // Get the keyword sizes - size_t l_partDataSize = 0; - size_t l_serialDataSize = 0; - if( SPD_DDR3 == l_memType ) + const KeywordData* entry = NULL; + l_err = getKeywordEntry( l_partKeyword, + l_memType, + i_target, + entry ); + if( l_err ) { - l_partDataSize = ddr3Data[l_partKeyword].length; - l_serialDataSize = ddr3Data[l_serialKeyword].length; + break; } - else + size_t l_partDataSize = entry->length; + + entry = NULL; + l_err = getKeywordEntry( l_serialKeyword, + l_memType, + i_target, + entry ); + if( l_err ) { - l_partDataSize = ddr4Data[l_partKeyword].length; - l_serialDataSize = ddr4Data[l_serialKeyword].length; + break; } + size_t l_serialDataSize = entry->length; + TRACDCOMP(g_trac_spd,"l_partDataSize=%d,l_serialDataSize=%d\n", + l_partDataSize,l_serialDataSize); //read the keywords from SEEPROM since PNOR may not be loaded yet uint8_t l_partNumberData[l_partDataSize]; @@ -2079,7 +2095,7 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) if( l_err ) { - TRACDCOMP(g_trac_spd, ERR_MRK"spd.C::setPartAndSerialNumberAttributes(): Error after spdGetValue-> SERIAL_NUMBER"); + TRACFCOMP(g_trac_spd, ERR_MRK"spd.C::setPartAndSerialNumberAttributes(): Error after spdGetValue-> SERIAL_NUMBER"); errlCommit(l_err, VPD_COMP_ID); l_err = NULL; break; @@ -2091,8 +2107,9 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) size_t expectedSNSize = sizeof(l_SN); if(expectedPNSize < l_partDataSize) { - TRACFCOMP(g_trac_spd, "Part data size too large for attribute. Expected: %d Actual: %d", - expectedPNSize, l_partDataSize); + TRACFCOMP(g_trac_spd, "Part data size too large for attribute. Expected: %d Actual: %d" + "Keyword: %X", + expectedPNSize, l_partDataSize, l_partKeyword); } else { @@ -2143,16 +2160,18 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target, break; } - // Get the keyword size - size_t dataSize = 0; - if( SPD_DDR3 == memType ) - { - dataSize = ddr3Data[i_keyword].length; - } - else + // Get the keyword size + const KeywordData* entry = NULL; + err = getKeywordEntry( i_keyword, + memType, + i_target, + entry ); + if( err ) { - dataSize = ddr4Data[i_keyword].length; + break; } + size_t dataSize = entry->length; + // Read the keyword from PNOR size_t sizePnor = dataSize; @@ -2211,8 +2230,9 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target, errlHndl_t loadPnor ( TARGETING::Target * i_target ) { errlHndl_t err = NULL; - - TRACSSCOMP( g_trac_spd, ENTER_MRK"loadPnorCache()" ); + size_t writeDataSize = 0; + uint8_t spdEepromData[DIMM_SPD_SECTION_SIZE]; + TRACSSCOMP( g_trac_spd, ENTER_MRK"loadPnor()" ); do { @@ -2225,13 +2245,40 @@ errlHndl_t loadPnor ( TARGETING::Target * i_target ) break; } + // Determine the memory type so we know if we need to read 256 or + // 512 from the eeprom + uint8_t memType = 0x0; + err = getMemType( memType, + i_target, + VPD::SEEPROM ); + + if( err ) + { + TRACFCOMP(g_trac_spd, + "spd.C::loadPnor - Error getting memtype(0x%x) " + "for target = 0x%x", + memType, + TARGETING::get_huid(i_target)); + break; + } + // Load PNOR cache from SEEPROM + // Read entire EEPROM at one time + if( memType == SPD_DDR3 ) + { + // EEPROM is only 256 bytes + writeDataSize = DIMM_SPD_SECTION_SIZE/2; + } + else if( memType == SPD_DDR4 ) + { + // EEPROM is 512 bytes + writeDataSize = DIMM_SPD_SECTION_SIZE; + } - // Read the entire SPD section from SEEPROM - uint8_t writeData[DIMM_SPD_SECTION_SIZE]; + // Fetch the EEPROM daa err = spdFetchData ( 0x0, - DIMM_SPD_SECTION_SIZE, - writeData, + writeDataSize, + spdEepromData, i_target, VPD::SEEPROM ); if( err ) @@ -2240,19 +2287,20 @@ errlHndl_t loadPnor ( TARGETING::Target * i_target ) ERR_MRK"loadPnorCache: Error reading SEEPROM SPD data" ); break; } - // Write the entire SPD section to PNOR + TRACDBIN(g_trac_spd, "ENTIRE EEPROM", spdEepromData, writeDataSize); err = spdWriteData( 0x0, - DIMM_SPD_SECTION_SIZE, - writeData, + writeDataSize, + spdEepromData, i_target, VPD::PNOR ); if( err ) { - TRACFCOMP( g_trac_spd,ERR_MRK"loadPnorCache: Error writing PNOR SPD data" ); + TRACFCOMP( g_trac_spd,ERR_MRK"loadPnorCache: Error writing PNOR SPD data 2" ); break; } + } while(0); TRACSSCOMP( g_trac_spd, EXIT_MRK"loadPnorCache()" ); diff --git a/src/usr/vpd/spdDDR4.H b/src/usr/vpd/spdDDR4.H index a3df6f3f7..d263f9cd4 100755 --- a/src/usr/vpd/spdDDR4.H +++ b/src/usr/vpd/spdDDR4.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -112,6 +112,7 @@ const KeywordData ddr4Data[] = { DRAM_MANUFACTURER_ID, 0x15f, 0x02, 0x00, 0x00, true, false, NA }, { MANUFACTURER_SPECIFIC_DATA, 0x161, 0x1d, 0x00, 0x00, false, false, NA }, { DIMM_BAD_DQ_DATA, 0x180, 0x50, 0x00, 0x00, false, true, NA }, + { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, false, false, NA }, // Normal fields supported on DDR4 only { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, NA }, { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, NA }, @@ -132,7 +133,6 @@ const KeywordData ddr4Data[] = { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, NA }, { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, NA }, { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, NA }, - { MODULE_REVISION_CODE_DDR4, 0x15d, 0x01, 0x00, 0x00, false, false, NA }, { DRAM_STEPPING, 0x160, 0x01, 0x00, 0x00, false, false, NA }, { MANUFACTURING_SECTION_CRC, 0x17f, 0x02, 0x00, 0x00, true, false, NA }, // Module Specific fields supported on both DDR3 and DDR4 |