diff options
author | Matthew Raybuck <matthew.raybuck@ibm.com> | 2019-05-22 08:45:16 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-05-31 08:51:28 -0500 |
commit | 85c03c9b4f645f3be7b7aca00ead86335b5db7a5 (patch) | |
tree | e6ca6eb1548e998ada307fd49cdaaad3c10f9c1f /src/usr/i2c | |
parent | abf11187330d96f03a5b7960e2b5d187be739761 (diff) | |
download | talos-hostboot-85c03c9b4f645f3be7b7aca00ead86335b5db7a5.tar.gz talos-hostboot-85c03c9b4f645f3be7b7aca00ead86335b5db7a5.zip |
Add cache/hardware comparison functions for SPD classes of VPD content
This commit adds necessary support for ensuring the eeprom cache is in
sync with hardware for EEPROM_CONTENT_TYPE DDIMM and ISDIMM. Support for
IBM_MVPD and IBM_FRUVPD will be added in a later commmit.
Change-Id:I0392c3f6b5dae986c03b9a16cef99a1529dade31
RTC:203788
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77119
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/i2c')
-rw-r--r-- | src/usr/i2c/eepromCache.C | 159 |
1 files changed, 119 insertions, 40 deletions
diff --git a/src/usr/i2c/eepromCache.C b/src/usr/i2c/eepromCache.C index 7fb6e3bf8..7fa2b9861 100644 --- a/src/usr/i2c/eepromCache.C +++ b/src/usr/i2c/eepromCache.C @@ -39,6 +39,7 @@ #include <initservice/initsvcreasoncodes.H> #include <pnor/pnorif.H> #include <vpd/vpd_if.H> + #include <errl/errludtarget.H> #include <config.h> #ifdef CONFIG_CONSOLE @@ -216,6 +217,7 @@ bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader) i_eepromRecordHeader.completeRecord.devAddr, i_eepromRecordHeader.completeRecord.mux_select, i_eepromRecordHeader.completeRecord.cache_copy_size); + l_matchFound = false; } @@ -271,7 +273,7 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target, if(l_errl) { // buildEepromRecordHeader should have traced any relavent information if - // is was needed, just break out and pass the error along + // it was needed, just break out and pass the error along break; } @@ -416,61 +418,138 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target, INITSERVICE::doShutdown(INITSERVICE::SHUTDOWN_DO_RECONFIG_LOOP); } - // - // At this point we have found a match in the PNOR but we need - // to decide what all needs an update - // - - // Stash the internal_offset of the section we found in so we can add - // this record to g_cachedEeproms for later use + // Stash the internal_offset of the section we found in so we + // can add this record to g_cachedEeproms for later use l_eepromRecordHeader.completeRecord.internal_offset = - l_recordHeaderToUpdate->completeRecord.internal_offset; + l_recordHeaderToUpdate->completeRecord.internal_offset; + TRACSSCOMP(g_trac_eeprom, + "cacheEeprom() already found copy for eeprom role %d for target w/ HUID 0x.%08X", + i_eepromType , TARGETING::get_huid(i_target)); + break; + } + } - if(l_recordHeaderToUpdate->completeRecord.cached_copy_valid) - { - // If the existing eeprom record is valid, then only update the - // contents if the SN/PN for current HW do not match the eeprom - // record. (target must be present to cache) + if(!addEepromToCachedList(l_eepromRecordHeader)) + { + TRACSSCOMP( g_trac_eeprom, + "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X added to cached list", + i_eepromType , TARGETING::get_huid(i_target)); + } + else + { + TRACSSCOMP( g_trac_eeprom, + "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X already in cached list", + i_eepromType , TARGETING::get_huid(i_target)); + } - // TODO RTC:203788 add lookup for PN and SN matches - //if( !i_present || PNandSNMatch ) - { - l_updateContents = false; - } - // If target is present there is nothing in the - // header to update - if( i_present ) - { - l_updateHeader = false; - } + uint64_t l_eepromCacheVaddr = lookupEepromAddr(l_eepromRecordHeader); + const uint64_t l_invalidAddress = 0xFFFFFFFFFFFFFFFF; + + // If the virtual address of the eeprom record header is an invalid + // address then this is the first time this target's eeprom is being + // cached. + bool l_isNewCacheEntry = false; + if (memcmp( + reinterpret_cast<void *>(l_eepromCacheVaddr), + &l_invalidAddress, sizeof(uint64_t)) == 0) + { + l_isNewCacheEntry = true; + } + + // At this point we have found a match in the PNOR but we need + // to decide what all needs an update. + // + // Only check if the cache is in sync with HARDWARE if there is an + // existing EECACHE section. Otherwise, the code after this logic will + // take care of adding a new eeprom cache section for the target. + if ( l_recordHeaderToUpdate->completeRecord.cached_copy_valid + && !l_isNewCacheEntry) + { + // Create namespace alias for targeting to reduce number of + // new lines required to be within line character limit. + namespace T = TARGETING; + + // If the existing eeprom record is valid, then only update + // the contents if the SN/PN for current HW do not match the + // eeprom record. (target must be present to cache) + T::EEPROM_CONTENT_TYPE l_eepromContentType = + T::EEPROM_CONTENT_TYPE_RAW; + + if (i_eepromType == EEPROM::VPD_PRIMARY) + { + auto l_eepromVpd = + i_target->getAttr<T::ATTR_EEPROM_VPD_PRIMARY_INFO>(); + + l_eepromContentType = + static_cast<T::EEPROM_CONTENT_TYPE>( + l_eepromVpd.eepromContentType); + } + else + { + auto l_eepromVpd = + i_target->getAttr<T::ATTR_EEPROM_VPD_BACKUP_INFO>(); + + l_eepromContentType = + static_cast<T::EEPROM_CONTENT_TYPE>( + l_eepromVpd.eepromContentType); + } + + TRACSSCOMP(g_trac_eeprom, + "cacheEeprom() Target 0x%.8X " + "EEPROM_CONTENT_TYPE 0x%X", + T::get_huid(i_target), + l_eepromContentType); + + bool l_isInSync = false; + + if (i_present) + { + l_errl = VPD::ensureEepromCacheIsInSync(i_target, + l_eepromContentType, + l_isInSync); + + if (l_errl != nullptr) + { + break; } - else if(!i_present) + + if(l_isInSync) { - // If the target is not present, then do not update contents or header l_updateContents = false; - l_updateHeader = false; } - TRACSSCOMP( g_trac_eeprom, "cacheEeprom() already found copy for eeprom role %d for target w/ HUID 0x.%08X", - i_eepromType , TARGETING::get_huid(i_target)); - break; } - } + else + { + // Clear out the contents of the cache for this eeprom if we have detected that it + // was once valid, indicating it was present at one time, and is now showing + // up as not present. We want to clear the contents of cache so we can achieve + // the replug behavior where a tester can remove the part, boot, then plug in the + // same part and boot again fresh. + void * l_internalSectionAddr = + reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) + l_eepromRecordHeader.completeRecord.internal_offset; + memset( l_internalSectionAddr, 0xFF , + (l_recordHeaderToUpdate->completeRecord.cache_copy_size * KILOBYTE)); + l_updateContents = false; + } - if(!addEepromToCachedList(l_eepromRecordHeader)) - { - TRACSSCOMP( g_trac_eeprom, "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X added to cached list", - i_eepromType , TARGETING::get_huid(i_target)); + // If target is present there is nothing in the + // header to update + if( i_present ) + { + l_updateHeader = false; + } } - else + else if(!i_present) { - TRACSSCOMP( g_trac_eeprom, "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X already in cached list", - i_eepromType , TARGETING::get_huid(i_target)); + // If the target is not present, then do not update contents + // or header + l_updateContents = false; + l_updateHeader = false; } - // Above we have determined whether the contents of the eeprom at // hand need to have their contents updated. Only do the following // steps that update the eeprom's cached data if we were told to do so. |