summaryrefslogtreecommitdiffstats
path: root/src/usr/i2c
diff options
context:
space:
mode:
authorChristian Geddes <crgeddes@us.ibm.com>2019-06-06 15:27:16 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-06-24 10:26:01 -0500
commit1ac1e9584462a41e204ffaae13f086b0a22c6cf8 (patch)
treeb98dd53baa9c7db49f006d7bb0e0a0372911aa14 /src/usr/i2c
parent5316f7dc08c6ebdbf96d93a9a17b97060a29d489 (diff)
downloadtalos-hostboot-1ac1e9584462a41e204ffaae13f086b0a22c6cf8.tar.gz
talos-hostboot-1ac1e9584462a41e204ffaae13f086b0a22c6cf8.zip
Add interface to mark eeprom caches valid/invalid
There are certain scenarios where we might want to update the table of contents at the start of the EECACHE section in pnor to indicate we have decided that the cached copy of one of the eeproms is no longer valid. This commit adds the ability to mark a cache entry as either valid or invalid by calling setIsValidCacheEntry in the EEPROM namespace and tests to verify this works. Future commits will add this call to places it is needed. Change-Id: I6b7dc807b7dbcaca3efa298790f862bc2c5f9ec6 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/78494 Reviewed-by: Roland Veloz <rveloz@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@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: Matt Derksen <mderkse1@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.C285
-rw-r--r--src/usr/i2c/eepromCache.H52
-rwxr-xr-xsrc/usr/i2c/eepromdd.C18
-rw-r--r--src/usr/i2c/test/eecachetest.H121
-rw-r--r--src/usr/i2c/test/makefile3
5 files changed, 448 insertions, 31 deletions
diff --git a/src/usr/i2c/eepromCache.C b/src/usr/i2c/eepromCache.C
index 8eb858883..35aced423 100644
--- a/src/usr/i2c/eepromCache.C
+++ b/src/usr/i2c/eepromCache.C
@@ -64,17 +64,18 @@ uint64_t g_eecachePnorSize = 0;
// Global map which is used as a way to quickly look up the virtual address
// of a given eeprom's cached data in EECACHE section
// Key = eepromRecordHeader with unique info filled out
-// Value = virtual address pointing to the cached eeprom data in pnor
-std::map<eepromRecordHeader, uint64_t> g_cachedEeproms;
+// Value = A struct of 2 virtual addresses , one points to header address
+// and other points to the location of the cache
+std::map<eepromRecordHeader, RecordAddresses_t> g_cachedEeproms;
// Any time we access either any of the global variables defined above we want
// to wrap the call in this mutex to avoid multi-threading issues
mutex_t g_eecacheMutex = MUTEX_INITIALIZER;
-uint64_t lookupEepromAddr(const eepromRecordHeader& i_eepromRecordHeader)
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader)
{
uint64_t l_vaddr = 0;
- std::map<eepromRecordHeader, uint64_t>::iterator l_it;
+ std::map<eepromRecordHeader, RecordAddresses_t>::iterator l_it;
// Wrap lookup in mutex because reads are not thread safe
mutex_lock(&g_eecacheMutex);
@@ -83,12 +84,50 @@ uint64_t lookupEepromAddr(const eepromRecordHeader& i_eepromRecordHeader)
if(l_it != g_cachedEeproms.end())
{
- l_vaddr = l_it->second;
+ l_vaddr = l_it->second.cache_entry_address;
}
if(l_vaddr == 0)
{
- TRACSSCOMP( g_trac_eeprom, "lookupEepromAddr() failed to find I2CM Huid: 0x%.08X, Port: 0x%.02X, Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X, Size: 0x%.08X in g_cachedEeproms",
+ TRACFCOMP( g_trac_eeprom,
+ "lookupEepromCacheAddr() failed to find"
+ " I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X"
+ " in g_cachedEeproms",
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+ }
+ return l_vaddr;
+}
+
+uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, RecordAddresses_t>::iterator l_it;
+
+ // Wrap lookup in mutex because reads are not thread safe
+ mutex_lock(&g_eecacheMutex);
+ l_it = g_cachedEeproms.find(i_eepromRecordHeader);
+
+ if(l_it != g_cachedEeproms.end())
+ {
+ l_vaddr = l_it->second.header_entry_address;
+ }
+ mutex_unlock(&g_eecacheMutex);
+
+ if(l_vaddr == 0)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "lookupEepromHeaderAddr() failed to find"
+ " I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X"
+ "in g_cachedEeproms",
i_eepromRecordHeader.completeRecord.i2c_master_huid,
i_eepromRecordHeader.completeRecord.port,
i_eepromRecordHeader.completeRecord.engine,
@@ -199,18 +238,66 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
// Do NOT allow adding/removing eeproms to cache during RT
#ifndef __HOSTBOOT_RUNTIME
-bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader)
+void printTableOfContents(void)
+{
+ eecacheSectionHeader * l_eecacheSectionHeaderPtr =
+ reinterpret_cast<eecacheSectionHeader*>(g_eecachePnorVaddr);
+
+ TRACFCOMP( g_trac_eeprom,
+ "printTableOfContents(): Version = 0x%.02X"
+ " End of Cache = 0x.08X",
+ l_eecacheSectionHeaderPtr->version,
+ l_eecacheSectionHeaderPtr->end_of_cache);
+
+ for(uint8_t i = 0; i < MAX_EEPROMS_VERSION_1; i++)
+ {
+ eepromRecordHeader l_currentRecordHeader =
+ l_eecacheSectionHeaderPtr->recordHeaders[i];
+
+ if( l_currentRecordHeader.completeRecord.internal_offset !=
+ UNSET_INTERNAL_OFFSET_VALUE)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "printTableOfContents(): I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X",
+ l_currentRecordHeader.completeRecord.i2c_master_huid,
+ l_currentRecordHeader.completeRecord.port,
+ l_currentRecordHeader.completeRecord.engine,
+ l_currentRecordHeader.completeRecord.devAddr,
+ l_currentRecordHeader.completeRecord.mux_select,
+ l_currentRecordHeader.completeRecord.cache_copy_size);
+
+ TRACFCOMP( g_trac_eeprom,
+ " "
+ "Internal Offset: 0x%.08X, Cache Valid: 0x%.02X",
+ l_currentRecordHeader.completeRecord.internal_offset,
+ l_currentRecordHeader.completeRecord.cached_copy_valid);
+ }
+ }
+
+}
+
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr)
{
bool l_matchFound = true;
- std::map<eepromRecordHeader, uint64_t>::iterator it;
// Map accesses are not thread safe, make sure this is always wrapped in mutex
mutex_lock(&g_eecacheMutex);
if(g_cachedEeproms.find(i_eepromRecordHeader) == g_cachedEeproms.end())
{
- g_cachedEeproms[i_eepromRecordHeader] = g_eecachePnorVaddr + i_eepromRecordHeader.completeRecord.internal_offset;
- TRACSSCOMP( g_trac_eeprom, "addEepromToCachedList() Adding I2CM Huid: 0x%.08X, Port: 0x%.02X, Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X, Size: 0x%.08X to g_cachedEeproms",
+ g_cachedEeproms[i_eepromRecordHeader].cache_entry_address =
+ g_eecachePnorVaddr + i_eepromRecordHeader.completeRecord.internal_offset;
+
+ g_cachedEeproms[i_eepromRecordHeader].header_entry_address =
+ i_recordHeaderVaddr;
+
+ TRACSSCOMP( g_trac_eeprom,
+ "addEepromToCachedList() Adding I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X,"
+ " Size: 0x%.08X to g_cachedEeproms",
i_eepromRecordHeader.completeRecord.i2c_master_huid,
i_eepromRecordHeader.completeRecord.port,
i_eepromRecordHeader.completeRecord.engine,
@@ -433,7 +520,11 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
}
}
- if(!addEepromToCachedList(l_eepromRecordHeader))
+ // pass the record we have been building up (l_eepromRecordHeader)
+ // and the virtual address of this eeprom's record entry in the
+ // EECACHE table of contents as a uint64.
+ if(!addEepromToCachedList(l_eepromRecordHeader,
+ reinterpret_cast<uint64_t>(l_recordHeaderToUpdate)))
{
TRACSSCOMP( g_trac_eeprom,
"cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X added to cached list",
@@ -446,7 +537,6 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
i_eepromType , TARGETING::get_huid(i_target));
}
-
// 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.
@@ -517,9 +607,12 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
// 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;
+ 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;
}
@@ -551,7 +644,8 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
l_tmpBuffer = malloc(l_eepromLen);
void * l_internalSectionAddr =
- reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) + l_eepromRecordHeader.completeRecord.internal_offset;
+ reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) +
+ l_eepromRecordHeader.completeRecord.internal_offset;
TRACSSCOMP( g_trac_eeprom, "cacheEeprom() passing the following into deviceOp eeprom address : huid 0x%.08X length 0x%.08X vaddr %p" ,
get_huid(i_target), l_eepromLen, l_internalSectionAddr);
@@ -732,6 +826,144 @@ DEVICE_REGISTER_ROUTE( DeviceFW::READ,
TARGETING::TYPE_DIMM,
genericI2CEepromCache );
+errlHndl_t setIsValidCacheEntry(const TARGETING::Target * i_target,
+ const EEPROM_ROLE &i_eepromRole,
+ bool i_isValid)
+{
+ errlHndl_t l_errl = nullptr;
+ eepromRecordHeader l_eepromRecordHeader;
+ eepromRecordHeader * l_eepromRecordHeaderToUpdate;
+ std::map<eepromRecordHeader, RecordAddresses_t>::iterator l_headerMapIterator;
+
+ eeprom_addr_t l_eepromInfo;
+ l_eepromInfo.eepromRole = i_eepromRole;
+
+ do{
+
+ TRACFCOMP( g_trac_eeprom, ENTER_MRK"setIsValidCacheEntry() "
+ "Target HUID 0x%.08X Eeprom Role = %d Enter",
+ TARGETING::get_huid(i_target), l_eepromInfo.eepromRole);
+
+ // Take the input paramters and use them to build a eeprom record header we can search with
+ l_errl = buildEepromRecordHeader(const_cast<TARGETING::Target *>(i_target),
+ l_eepromInfo,
+ l_eepromRecordHeader);
+
+ if(l_errl)
+ {
+ break;
+ }
+
+ // Find the address of the header entry in the table of contents of the EECACHE pnor section
+ l_eepromRecordHeaderToUpdate =
+ reinterpret_cast<eepromRecordHeader *>(lookupEepromHeaderAddr(l_eepromRecordHeader));
+
+ if(l_eepromRecordHeaderToUpdate == 0)
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"setIsValidCacheEntry: Attempting to invalidate cache for an "
+ "eeprom but we could not find in global eecache map");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_CACHE_NOT_FOUND_IN_MAP
+ * @userdata1[0:7] i2c_master_huid
+ * @userdata1[8:9] port on i2c master eeprom slave is on
+ * @userdata1[10:11] engine on i2c master eeprom slave is on
+ * @userdata1[12:13] devAddr of eeprom slave
+ * @userdata1[14:15] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:7] size of eeprom
+ * @devdesc invalidateCache failed to find cache in map
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_CACHE_NOT_FOUND_IN_MAP,
+ TWO_UINT32_TO_UINT64(
+ l_eepromRecordHeader.completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.port,
+ l_eepromRecordHeader.completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.devAddr,
+ l_eepromRecordHeader.completeRecord.mux_select))),
+ l_eepromRecordHeader.completeRecord.cache_copy_size,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Ensure that information at the address we just looked up matches the record we built up
+ if( memcmp(&l_eepromRecordHeaderToUpdate->uniqueRecord.uniqueID,
+ &l_eepromRecordHeader.uniqueRecord.uniqueID,
+ NUM_BYTE_UNIQUE_ID ) != 0 )
+ {
+ TRACFCOMP(g_trac_eeprom,ERR_MRK"setIsValidCacheEntry: Attempting to invalidate cache for an"
+ "eeprom but we could not find the entry in table of contents of EECACHE section of pnor");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_CACHE_NOT_FOUND_IN_PNOR
+ * @userdata1[0:7] i2c_master_huid
+ * @userdata1[8:9] port on i2c master eeprom slave is on
+ * @userdata1[10:11] engine on i2c master eeprom slave is on
+ * @userdata1[12:13] devAddr of eeprom slave
+ * @userdata1[14:15] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:7] size of eeprom
+ * @devdesc invalidateCache failed to find cache in pnor
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_CACHE_NOT_FOUND_IN_PNOR,
+ TWO_UINT32_TO_UINT64(
+ l_eepromRecordHeader.completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.port,
+ l_eepromRecordHeader.completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.devAddr,
+ l_eepromRecordHeader.completeRecord.mux_select))),
+ l_eepromRecordHeader.completeRecord.cache_copy_size,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Update the header so that it state the entry is invalid
+ l_eepromRecordHeaderToUpdate->completeRecord.cached_copy_valid = i_isValid;
+
+ // Flush the page to make sure it gets to the PNOR
+ int rc = mm_remove_pages( FLUSH,
+ l_eepromRecordHeaderToUpdate,
+ sizeof(eepromRecordHeader) );
+ if( rc )
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"setIsValidCacheEntry: Error from mm_remove_pages trying for flush header write to pnor, rc=%d",rc);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_FAILED_TO_FLUSH_HEADER
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc invalidateCache mm_remove_pages FLUSH failed
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_FAILED_TO_FLUSH_HEADER,
+ (uint64_t)l_eepromRecordHeaderToUpdate,
+ TO_UINT64(rc),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ }while(0);
+
+ return l_errl;
+}
+
#endif
errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
@@ -748,7 +980,9 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
TRACSSCOMP( g_trac_eeprom, ENTER_MRK"eepromPerformOpCache() "
"Target HUID 0x%.08X Enter", TARGETING::get_huid(i_target));
- l_errl = buildEepromRecordHeader(i_target, i_eepromInfo, l_eepromRecordHeader);
+ l_errl = buildEepromRecordHeader(i_target,
+ i_eepromInfo,
+ l_eepromRecordHeader);
if(l_errl)
{
@@ -757,7 +991,7 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
break;
}
- uint64_t l_eepromCacheVaddr = lookupEepromAddr(l_eepromRecordHeader);
+ uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader);
// Ensure that a copy of the eeprom exists in our map of cached eeproms
if(l_eepromCacheVaddr)
@@ -780,7 +1014,8 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
i_eepromInfo.offset, io_buflen, l_eepromCacheVaddr);
// Make sure that offset + buflen are less than the total size of the eeprom
- if(i_eepromInfo.offset + io_buflen > (l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE))
+ if(i_eepromInfo.offset + io_buflen >
+ (l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE))
{
TRACFCOMP(g_trac_eeprom,
ERR_MRK"eepromPerformOpCache: i_eepromInfo.offset + i_offset is greater than size of eeprom (0x%x KB)",
@@ -809,11 +1044,15 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
if(i_opType == DeviceFW::READ)
{
- memcpy(io_buffer, reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset), io_buflen);
+ memcpy(io_buffer,
+ reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ io_buflen);
}
else if(i_opType == DeviceFW::WRITE)
{
- memcpy(reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset), io_buffer, io_buflen);
+ memcpy(reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ io_buffer,
+ io_buflen);
#ifndef __HOSTBOOT_RUNTIME
@@ -823,7 +1062,9 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
io_buflen );
if( rc )
{
- TRACFCOMP(g_trac_eeprom,ERR_MRK"eepromPerformOpCache: Error from mm_remove_pages trying for flush contents write to pnor! rc=%d",rc);
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: Error from mm_remove_pages trying for flush contents write to pnor! rc=%d",
+ rc);
/*@
* @errortype
* @moduleid EEPROM_CACHE_PERFORM_OP
@@ -845,7 +1086,9 @@ errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
}
else
{
- TRACFCOMP(g_trac_eeprom,ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d", i_opType);
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d",
+ i_opType);
/*@
* @errortype
* @moduleid EEPROM_CACHE_PERFORM_OP
diff --git a/src/usr/i2c/eepromCache.H b/src/usr/i2c/eepromCache.H
index 5cad475ba..fa0c340bd 100644
--- a/src/usr/i2c/eepromCache.H
+++ b/src/usr/i2c/eepromCache.H
@@ -100,7 +100,7 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
/**
*
* @brief Perform a lookup on the global map g_cachedEeproms to get a
-* virtual address for a given EEPROM
+* virtual address for a given EEPROM cache entry
*
* @param[in] i_eepromRecordHeader
*
@@ -110,8 +110,56 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
* @return uint64_t virtual address pointing to the cached eeprom data in pnor
*
*/
-uint64_t lookupEepromAddr(const eepromRecordHeader & i_eepromRecordHeader);
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader);
+/**
+*
+* @brief Perform a lookup on the global map g_cachedEeproms to get a
+* virtual address for a given EEPROM entry in the EECACHE table of contents
+*
+* @param[in] i_eepromRecordHeader
+*
+* @pre It is expected that i_eepromRecordHeader has valid information for
+* the uniqueID (i2cm_huid, port, engine, devAddr, mux_select)
+*
+* @return uint64_t virtual address pointing to the cached eeprom data in pnor
+*
+*/
+uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader);
+
+#ifndef __HOSTBOOT_RUNTIME
+
+/**
+*
+* @brief Update the record entry in the Table of Contents of the EECACHE
+* section of pnor to either mark the contents of the cache to be
+* valid or invalid
+*
+* @param[in] i_target Target associated with EEPROM
+*
+* @param[in] i_eepromRole Role of EEPROM associated with target (VPD_PRIMARY etc)
+*
+* @param[in] i_isValid Mark eeprom cache valid or invalid ?
+*
+* @return errlHndl_t - nullptr if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t setIsValidCacheEntry(const TARGETING::Target * i_target,
+ const EEPROM_ROLE &i_eepromRole,
+ bool i_isValid);
+
+/**
+*
+* @brief Print the info found in the Table of Contents of the EECACHE
+* section of pnor to trace buffer
+*
+* @return void
+*
+*/
+void printTableOfContents(void);
+
+#endif // __HOSTBOOT_RUNTIME
}
#endif \ No newline at end of file
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index dd5f5aa11..ab7e804e1 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -89,7 +89,7 @@ errlHndl_t resolveSource(TARGETING::Target * i_target,
l_eepromRecordHeader);
// if lookupEepromAddr returns non-zero address
// then we know it exists in cache somewhere
- if(lookupEepromAddr(l_eepromRecordHeader))
+ if(lookupEepromCacheAddr(l_eepromRecordHeader))
{
TRACDCOMP(g_trac_eeprom,"Eeprom found in cache, looking at eecache");
o_source = EEPROM::CACHE;
@@ -178,29 +178,33 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType,
if(l_source == EEPROM::CACHE )
{
// Read the copy of the EEPROM data we have cached in PNOR
- err = eepromPerformOpCache(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpCache(i_opType, i_target,
+ io_buffer, io_buflen, i2cInfo);
if(err)
{
break;
}
- // If the operation is a write we also need to "write through" to HW after
- // we write cache
+ // If the operation is a write we also need to
+ // "write through" to HW after we write cache
if(i_opType == DeviceFW::WRITE)
{
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpHW(i_opType, i_target,
+ io_buffer, io_buflen, i2cInfo);
}
}
else if(l_source == EEPROM::HARDWARE)
{
// Read from the actual physical EEPROM device
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpHW(i_opType, i_target, io_buffer,
+ io_buflen, i2cInfo);
}
#else
// Read from the actual physical EEPROM device
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpHW(i_opType, i_target, io_buffer,
+ io_buflen, i2cInfo);
#endif // CONFIG_SUPPORT_EEPROM_CACHING
diff --git a/src/usr/i2c/test/eecachetest.H b/src/usr/i2c/test/eecachetest.H
new file mode 100644
index 000000000..cc5233bf6
--- /dev/null
+++ b/src/usr/i2c/test/eecachetest.H
@@ -0,0 +1,121 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/test/eecachetest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __EECACHETEST_H
+#define __EECACHETEST_H
+
+/**
+ * @file eepromtest.H
+ *
+ * @brief Test cases for the eeprom cache code
+ */
+
+#include <cxxtest/TestSuite.H>
+#include "../eepromCache.H"
+
+extern trace_desc_t* g_trac_eeprom;
+
+using namespace TARGETING;
+using namespace EEPROM;
+
+class EECACHETest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief Verify we can mark a cache as invalid then mark it valid again
+ */
+ void test_invalidateCache( void )
+ {
+ uint8_t l_numTests = 0;
+ uint8_t l_numFails = 0;
+
+ TRACFCOMP( g_trac_eeprom, ENTER_MRK"test_invalidateCache" );
+
+ do{
+ // Uncomment to verify manually
+ //printTableOfContents();
+
+ // Get a processor Target
+ TARGETING::TargetService& tS = TARGETING::targetService();
+ TARGETING::Target* testTarget = NULL;
+ tS.masterProcChipTargetHandle( testTarget );
+ assert(testTarget != NULL);
+
+ // Create dummy eeprom info w/ VPD_PRIMARY set
+ const EEPROM_ROLE l_eepromRole = EEPROM::VPD_PRIMARY;
+
+ eeprom_addr_t l_primaryVpdEeprom;
+ l_primaryVpdEeprom.eepromRole = l_eepromRole;
+
+ eepromRecordHeader l_eepromRecordHeader_forLookup;
+ eepromRecordHeader * l_eepromRecordHeader_realPnor;
+
+ buildEepromRecordHeader( testTarget,
+ l_primaryVpdEeprom,
+ l_eepromRecordHeader_forLookup);
+
+ l_eepromRecordHeader_realPnor = reinterpret_cast<eepromRecordHeader *>(lookupEepromHeaderAddr(l_eepromRecordHeader_forLookup));
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 1)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be valid at start of test!");
+ l_numFails++;
+ break;
+ }
+
+ // Invalidate the cache entry
+ setIsValidCacheEntry(testTarget, l_eepromRole, 0);
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 0)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be invalid after setIsValidCacheEntry(invalid) is called!");
+ l_numFails++;
+ break;
+ }
+
+ // Re-validate the cache entry
+ setIsValidCacheEntry(testTarget, l_eepromRole, 1);
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 1)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be invalid after setIsValidCacheEntry(valid) is called!");
+ l_numFails++;
+ break;
+ }
+
+ // Uncomment to verify manually
+ // printTableOfContents();
+
+ }while(0);
+
+ TRACFCOMP( g_trac_eeprom, EXIT_MRK"test_getEEPROMs numTests = %d / num fails = %d", l_numTests, l_numFails );
+ }
+
+};
+
+#endif \ No newline at end of file
diff --git a/src/usr/i2c/test/makefile b/src/usr/i2c/test/makefile
index ef774e6e0..056391308 100644
--- a/src/usr/i2c/test/makefile
+++ b/src/usr/i2c/test/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2015
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -26,6 +26,7 @@ ROOTPATH = ../../../..
MODULE = testi2c
TESTS = eepromddtest.H
+TESTS = $(if $(CONFIG_SUPPORT_EEPROM_CACHING), eecachetest.H, )
TESTS += i2ctest.H
TESTS += $(if $(CONFIG_TPMDD),tpmddtest.H,)
OpenPOWER on IntegriCloud