diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2014-11-06 13:08:24 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-01-30 09:40:11 -0600 |
commit | 7452530902bcc31b361748d832c0f44fe277b686 (patch) | |
tree | d56db7ac0183c03ea288c4517016dcc04c0c28ab | |
parent | e7dd491766237e728331d51064ddf7382c23c404 (diff) | |
download | talos-hostboot-7452530902bcc31b361748d832c0f44fe277b686.tar.gz talos-hostboot-7452530902bcc31b361748d832c0f44fe277b686.zip |
Fix issue with overwriting PNOR VPD cache
Planar VPD needs more space for each CVPD record than
CDIMMs need. Also added a check to catch overruns.
Change-Id: I6aa2291658388cc72b6ba1e04c3eeed51235c3e3
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14382
Tested-by: Jenkins Server
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r-- | src/include/usr/vpd/vpdreasoncodes.H | 4 | ||||
-rw-r--r-- | src/usr/vpd/HBconfig | 7 | ||||
-rw-r--r-- | src/usr/vpd/cvpd.H | 10 | ||||
-rw-r--r-- | src/usr/vpd/ipvpd.C | 31 |
4 files changed, 47 insertions, 5 deletions
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H index 68dc00c2b..fedddbe88 100644 --- a/src/include/usr/vpd/vpdreasoncodes.H +++ b/src/include/usr/vpd/vpdreasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -58,6 +58,7 @@ enum vpdModuleId VPD_IPVPD_FIND_RECORD_OFFSET_SEEPROM = 0x30, VPD_IPVPD_FETCH_DATA = 0x31, VPD_IPVPD_WRITE_KEYWORD = 0x32, + VPD_IPVPD_LOAD_PNOR = 0x33, // DIMM SPD @@ -129,6 +130,7 @@ enum vpdReasonCode VPD_REMOVE_PAGES_FAIL = VPD_COMP_ID | 0x32, VPD_UNEXPECTED_TARGET_TYPE = VPD_COMP_ID | 0x33, VPD_WRITE_DEST_UNRESOLVED = VPD_COMP_ID | 0x34, + VPD_CACHE_SIZE_EXCEEDED = VPD_COMP_ID | 0x35, }; diff --git a/src/usr/vpd/HBconfig b/src/usr/vpd/HBconfig index f65913121..15254caac 100644 --- a/src/usr/vpd/HBconfig +++ b/src/usr/vpd/HBconfig @@ -102,7 +102,7 @@ config DJVPD_WRITE config HAVE_MBVPD default y if CVPD_READ_FROM_PNOR || CVPD_READ_FROM_HW - depends on CVPD_READ_FROM_PNOR || CVPD_READ_FROM_HW + depends on (CVPD_READ_FROM_PNOR || CVPD_READ_FROM_HW) && !PALMETTO_PASS1 help Have MemBuff/Centaur VPD, PNOR or HW @@ -110,3 +110,8 @@ config PALMETTO_PASS1 default n help Palmetto pass1 specific changes + +config CDIMM_FORMAT_FOR_CVPD + default y + help + Assume Custom DIMM VPD layout for CVPD diff --git a/src/usr/vpd/cvpd.H b/src/usr/vpd/cvpd.H index b71b98008..7aefa430e 100644 --- a/src/usr/vpd/cvpd.H +++ b/src/usr/vpd/cvpd.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -40,14 +40,22 @@ #include <vpd/cvpdenums.H> #include "ipvpd.H" +#include <config.h> namespace CVPD { enum { +#ifdef CONFIG_CDIMM_FORMAT_FOR_CVPD + // 4KB x 64 SECTION_SIZE = 0x1000, MAX_SECTIONS = 64, +#else + // 8KB x 32 + SECTION_SIZE = 0x2000, + MAX_SECTIONS = 32, +#endif }; diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C index 2eec10f4f..229a50d27 100644 --- a/src/usr/vpd/ipvpd.C +++ b/src/usr/vpd/ipvpd.C @@ -65,7 +65,6 @@ extern trace_desc_t* g_trac_vpd; static const uint64_t IPVPD_TOC_SIZE = 0x100; //256 static const uint64_t IPVPD_TOC_ENTRY_SIZE = 8; static const uint64_t IPVPD_TOC_INVALID_DATA = 0xFFFFFFFFFFFFFFFF; -static const uint32_t IPVPD_MAX_ENTRY_SIZE = (64 * 1024); /** @@ -433,7 +432,7 @@ errlHndl_t IpVpdFacade::loadPnor ( TARGETING::Target * i_target ) } // Temp data for entire VPD entry - uint8_t* tmpVpdPtr = new uint8_t[IPVPD_MAX_ENTRY_SIZE]; + uint8_t* tmpVpdPtr = new uint8_t[iv_vpdSectionSize]; // Load the temp data with invalid TOC uint64_t tocdata = IPVPD_TOC_INVALID_DATA; @@ -500,6 +499,34 @@ errlHndl_t IpVpdFacade::loadPnor ( TARGETING::Target * i_target ) &pTocEntry, IPVPD_TOC_ENTRY_SIZE ); + // Make sure we don't exceed our allocated space in PNOR + if( (pRecOffset + sRecLength) > iv_vpdSectionSize ) + { + TRACFCOMP(g_trac_vpd,"IpVpdFacade::loadPnor()> The amount of space required (0x%X) for the VPD cache exceeds the available space (0x%X)", pRecOffset + sRecLength, iv_vpdSectionSize ); + /*@ + * @errortype + * @reasoncode VPD::VPD_CACHE_SIZE_EXCEEDED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid VPD::VPD_IPVPD_LOAD_PNOR + * @userdata1 HUID of target chip + * @userdata2[00:31] Available size + * @userdata2[32:63] Requested size + * @devdesc The amount of space required for the VPD + * cache exceeds the available space + * @custdesc Fatal firmware boot error + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + VPD::VPD_IPVPD_LOAD_PNOR, + VPD::VPD_CACHE_SIZE_EXCEEDED, + TARGETING::get_huid(i_target), + TWO_UINT32_TO_UINT64( + iv_vpdSectionSize, + pRecOffset + sRecLength ), + true /*Add HB SW Callout*/ ); + err->collectTrace( "VPD", 256 ); + break; + } + // Read record data from SEEPROM, put it into temp data uint8_t* pRecPtr = tmpVpdPtr + pRecOffset; err = fetchData( sRecOffset, |