summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/i2c/eepromddreasoncodes.H6
-rw-r--r--src/include/usr/vmmconst.h4
-rw-r--r--src/usr/i2c/eepromCache.C588
-rw-r--r--src/usr/i2c/eepromCache.H106
-rw-r--r--src/usr/i2c/eepromCache_common.C326
-rwxr-xr-xsrc/usr/i2c/eepromdd.C55
-rw-r--r--src/usr/i2c/i2c.mk4
-rw-r--r--src/usr/i2c/makefile1
-rw-r--r--src/usr/i2c/runtime/makefile6
-rw-r--r--src/usr/i2c/runtime/rt_eepromCache.C285
-rw-r--r--src/usr/vpd/makefile1
-rw-r--r--src/usr/vpd/rtvpd_load.C18
-rw-r--r--src/usr/vpd/spd.C2
-rw-r--r--src/usr/vpd/vpd.mk1
-rw-r--r--src/usr/vpd/vpd_common.C4
15 files changed, 941 insertions, 466 deletions
diff --git a/src/include/usr/i2c/eepromddreasoncodes.H b/src/include/usr/i2c/eepromddreasoncodes.H
index c08935ab4..41de06dfa 100644
--- a/src/include/usr/i2c/eepromddreasoncodes.H
+++ b/src/include/usr/i2c/eepromddreasoncodes.H
@@ -58,6 +58,8 @@ enum eepromModuleId
EEPROM_CLEAR_EECACHE = 0x08,
EEPROM_CACHE_PERFORM_OP = 0x09,
EEPROM_INVALIDATE_CACHE = 0x0A,
+ EEPROM_RESOLVE_SOURCE = 0x0B,
+ EEPROM_CACHE_INIT_RT = 0x0C,
};
/**
@@ -92,6 +94,10 @@ enum eepromReasonCode
// what eeproms have been cached was not found
EEPROM_CACHE_NOT_FOUND_IN_PNOR = EEPROM_COMP_ID | 0x10, // An entry we thought would be in the the EECACHE section of PNOR seems
// to be missing
+ EEPROM_CACHE_NO_VPD_IN_RSV_MEM = EEPROM_COMP_ID | 0x11, // When looking up the VPD section in reserved memory no entry was found.
+ EEPROM_DUPLICATE_CACHE_ENTRY = EEPROM_COMP_ID | 0x12 // While parsing eecache found in reserved memory we found at least two
+ // cache entries that had identical "unique" identifiers
+ // (see structs defined in eeprom_const.H)
};
enum UserDetailsTypes
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index b6841eea4..bd6a889c1 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -208,9 +208,13 @@ enum BlockPriority
#define VMM_MODULE_VPD_SIZE (512*KILOBYTE) /* must be 64KB aligned */
#define VMM_CENTAUR_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */
#define VMM_DIMM_JEDEC_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */
+#ifndef CONFIG_SUPPORT_EEPROM_CACHING
#define VMM_RT_VPD_SIZE ( VMM_MODULE_VPD_SIZE + \
VMM_CENTAUR_VPD_SIZE + \
VMM_DIMM_JEDEC_VPD_SIZE )
+#else
+#define VMM_RT_VPD_SIZE (512*KILOBYTE) /* 64KB aligned (size EECACHE section size - ecc) */
+#endif
/** Internode communication area outside of the HB image.
diff --git a/src/usr/i2c/eepromCache.C b/src/usr/i2c/eepromCache.C
index 6993f35ee..b50f899bf 100644
--- a/src/usr/i2c/eepromCache.C
+++ b/src/usr/i2c/eepromCache.C
@@ -34,7 +34,7 @@
#include "i2c.H"
#include "eepromCache.H"
#include <i2c/i2cif.H>
-#include <i2c/eepromif.H>
+
#include <i2c/eepromddreasoncodes.H>
#include <initservice/initserviceif.H>
#include <initservice/initsvcreasoncodes.H>
@@ -55,6 +55,10 @@ extern trace_desc_t* g_trac_eeprom;
namespace EEPROM
{
+// Any time we access either any of the global variables defined below we want
+// to wrap the call in this mutex to avoid multi-threading issues
+mutex_t g_eecacheMutex = MUTEX_INITIALIZER;
+
// Global variable that will keep track of the virtual address which
// points to the start of the EECACHE section, and the size of this section.
// It is handy to keep these around so we do not need to look them up in the
@@ -70,287 +74,6 @@ uint64_t g_eecachePnorSize = 0;
// if this eeprom's hardware has changed this IPL
std::map<eepromRecordHeader, EeepromEntryMetaData_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 lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader)
-{
- uint64_t l_vaddr = 0;
- std::map<eepromRecordHeader, EeepromEntryMetaData_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);
- mutex_unlock(&g_eecacheMutex);
-
- if(l_it != g_cachedEeproms.end())
- {
- l_vaddr = l_it->second.cache_entry_address;
- }
- return l_vaddr;
-}
-
-uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader)
-{
- uint64_t l_vaddr = 0;
- std::map<eepromRecordHeader, EeepromEntryMetaData_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,
- i_eepromRecordHeader.completeRecord.devAddr,
- i_eepromRecordHeader.completeRecord.mux_select,
- i_eepromRecordHeader.completeRecord.cache_copy_size);
- }
- return l_vaddr;
-}
-
-errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
- eeprom_addr_t & io_eepromInfo,
- eepromRecordHeader & o_eepromRecordHeader)
-{
-
- TARGETING::Target * l_muxTarget = nullptr;
- TARGETING::Target * l_i2cMasterTarget = nullptr;
- TARGETING::TargetService& l_targetService = TARGETING::targetService();
- errlHndl_t l_errl = nullptr;
-
- do{
-
- l_errl = eepromReadAttributes(i_target, io_eepromInfo);
- if(l_errl)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() error occured reading eeprom attributes for eepromType %d, target 0x%.08X, returning!!",
- io_eepromInfo.eepromRole,
- TARGETING::get_huid(i_target));
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // Grab the I2C mux target so we can read the HUID, if the target is NULL we will not be able
- // to lookup attribute to uniquely ID this eeprom so we will not cache it
- l_muxTarget = l_targetService.toTarget( io_eepromInfo.i2cMuxPath);
- if(l_muxTarget == nullptr)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() Mux target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache",
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_EEPROM
- * @reasoncode EEPROM_I2C_MUX_PATH_ERROR
- * @userdata1 HUID of target we want to cache
- * @userdata2 Type of EEPROM we are caching
- * @devdesc buildEepromRecordHeader invalid mux target
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_EEPROM,
- EEPROM_I2C_MUX_PATH_ERROR,
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole,
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // Grab the I2C master target so we can read the HUID, if the target is NULL we will not be able
- // to lookup attribute to uniquely ID this eeprom so we will not cache it
- l_i2cMasterTarget = l_targetService.toTarget( io_eepromInfo.i2cMasterPath );
- if(l_i2cMasterTarget == nullptr)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() I2C Master target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache ",
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_EEPROM
- * @reasoncode EEPROM_I2C_MASTER_PATH_ERROR
- * @userdata1 HUID of target we want to cache
- * @userdata2 Type of EEPROM we are caching
- * @devdesc buildEepromRecordHeader invalid master target
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_EEPROM,
- EEPROM_I2C_MASTER_PATH_ERROR,
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole,
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // This is what we will compare w/ when we are going through the existing
- // caches in the eeprom to see if we have already cached something
- // Or if no matches are found we will copy this into the header
- o_eepromRecordHeader.completeRecord.i2c_master_huid = l_i2cMasterTarget->getAttr<TARGETING::ATTR_HUID>();
- o_eepromRecordHeader.completeRecord.port = static_cast<uint8_t>(io_eepromInfo.port);
- o_eepromRecordHeader.completeRecord.engine = static_cast<uint8_t>(io_eepromInfo.engine);
- o_eepromRecordHeader.completeRecord.devAddr = static_cast<uint8_t>(io_eepromInfo.devAddr);
- o_eepromRecordHeader.completeRecord.mux_select = static_cast<uint8_t>(io_eepromInfo.i2cMuxBusSelector);
- o_eepromRecordHeader.completeRecord.cache_copy_size = static_cast<uint32_t>(io_eepromInfo.devSize_KB);
-
- // Do not set valid bit nor internal offset here as we do not have
- // enough information availible to determine
-
- }while(0);
-
- return l_errl;
-}
-
-// Do NOT allow adding/removing eeproms to cache during RT
-#ifndef __HOSTBOOT_RUNTIME
-
-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);
- }
- }
-
-}
-
-/**
-*
-* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
-* caches and check if the eeprom has changed this IPL or not
-*
-* @param[in] i_eepromRecordHeader we want to look up
-*
-* @return bool Return TRUE if eeprom is found in map AND mark_target_changed
- was set to true for the eeprom entry. Return FALSE otherwise.
-*
-*/
-bool hasEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
-{
- bool l_eepromHasChanged = false;
-
- // 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())
- {
- l_eepromHasChanged = g_cachedEeproms[i_eepromRecordHeader].mark_target_changed;
- }
-
- mutex_unlock(&g_eecacheMutex);
-
- return l_eepromHasChanged;
-}
-
-/**
-*
-* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
-* caches and mark that it has changed this IPL
-*
-* @param[in] i_eepromRecordHeader we want to mark as changed
-*
-* @return void
-*/
-void setEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
-{
-
- // 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].mark_target_changed = true;
- }
-
- mutex_unlock(&g_eecacheMutex);
-
-}
-
-bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
- const uint64_t i_recordHeaderVaddr)
-{
- bool l_matchFound = true;
-
- // 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].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,
- i_eepromRecordHeader.completeRecord.devAddr,
- i_eepromRecordHeader.completeRecord.mux_select,
- i_eepromRecordHeader.completeRecord.cache_copy_size);
-
- l_matchFound = false;
- }
-
- mutex_unlock(&g_eecacheMutex);
-
- return l_matchFound;
-}
-
/**
* @brief Lookup I2C information for given eeprom, check if eeprom exists in cache.
* If it exists already determine if any updates are required. If it is not
@@ -1066,186 +789,163 @@ errlHndl_t setIsValidCacheEntry(const eepromRecordHeader& i_eepromRecordHeader,
return l_errl;
}
-#endif
-
-errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
- TARGETING::Target * i_target,
- void * io_buffer,
- size_t& io_buflen,
- eeprom_addr_t &i_eepromInfo)
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr)
{
- errlHndl_t l_errl = nullptr;
- eepromRecordHeader l_eepromRecordHeader;
+ bool l_matchFound = true;
- do{
+ // 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].cache_entry_address =
+ g_eecachePnorVaddr + i_eepromRecordHeader.completeRecord.internal_offset;
+
+ g_cachedEeproms[i_eepromRecordHeader].header_entry_address =
+ i_recordHeaderVaddr;
- TRACSSCOMP( g_trac_eeprom, ENTER_MRK"eepromPerformOpCache() "
- "Target HUID 0x%.08X Enter", TARGETING::get_huid(i_target));
+ 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,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
- l_errl = buildEepromRecordHeader(i_target,
- i_eepromInfo,
- l_eepromRecordHeader);
+ l_matchFound = false;
+ }
- if(l_errl)
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_matchFound;
+}
+
+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)
{
- // buildEepromRecordHeader should have traced any relavent information if
- // it was needed, just break out and pass the error along
- break;
+ 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);
}
+ }
- uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader);
+}
- // Ensure that a copy of the eeprom exists in our map of cached eeproms
- if(l_eepromCacheVaddr)
- {
- // First check if io_buffer is a nullptr, if so then assume user is
- // requesting size back in io_bufferlen
- if(io_buffer == nullptr)
- {
- io_buflen = l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE;
- TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
- "io_buffer == nullptr , returning io_buflen as 0x%lx",
- io_buflen);
- break;
- }
+bool hasEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
+{
+ bool l_eepromHasChanged = false;
- TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
- "Performing %s on target 0x%.08X offset 0x%lx length 0x%x vaddr 0x%lx",
- (i_opType == DeviceFW::READ) ? "READ" : "WRITE",
- TARGETING::get_huid(i_target),
- i_eepromInfo.offset, io_buflen, l_eepromCacheVaddr);
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
- // 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))
- {
- TRACFCOMP(g_trac_eeprom,
- ERR_MRK"eepromPerformOpCache: i_eepromInfo.offset + i_offset is greater than size of eeprom (0x%x KB)",
- l_eepromRecordHeader.completeRecord.cache_copy_size);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_OVERFLOW_ERROR
- * @userdata1 Length of Operation
- * @userdata2 Offset we are attempting to read/write
- * @custdesc Soft error in Firmware
- * @devdesc cacheEeprom invalid op type
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_OVERFLOW_ERROR,
- TO_UINT64(io_buflen),
- TO_UINT64(i_eepromInfo.offset),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
+ if(g_cachedEeproms.find(i_eepromRecordHeader) != g_cachedEeproms.end())
+ {
+ l_eepromHasChanged = g_cachedEeproms[i_eepromRecordHeader].mark_target_changed;
+ }
- break;
- }
+ mutex_unlock(&g_eecacheMutex);
- if(i_opType == DeviceFW::READ)
- {
- 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);
+ return l_eepromHasChanged;
+}
- #ifndef __HOSTBOOT_RUNTIME
+void setEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
+{
- // Perform flush to ensure pnor is updated
- int rc = mm_remove_pages( FLUSH,
- reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
- 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);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_FAILED_TO_FLUSH_CONTENTS
- * @userdata1 Requested Address
- * @userdata2 rc from mm_remove_pages
- * @devdesc cacheEeprom mm_remove_pages FLUSH failed
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_FAILED_TO_FLUSH_CONTENTS,
- (l_eepromCacheVaddr + i_eepromInfo.offset),
- TO_UINT64(rc),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace( EEPROM_COMP_NAME );
- }
- #endif //__HOSTBOOT_RUNTIME
- }
- else
- {
- TRACFCOMP(g_trac_eeprom,
- ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d",
- i_opType);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_INVALID_OPERATION
- * @userdata1[0:31] Op Type that was invalid
- * @userdata1[32:63] Eeprom Role
- * @userdata2 Offset we are attempting to perfrom op on
- * @custdesc Soft error in Firmware
- * @devdesc cacheEeprom invalid op type
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_INVALID_OPERATION,
- TWO_UINT32_TO_UINT64(i_opType,
- i_eepromInfo.eepromRole),
- TO_UINT64(i_eepromInfo.offset),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
- }
- }
- else
- {
- TRACFCOMP( g_trac_eeprom,"eepromPerformOpCache: Failed to find entry in cache for 0x%.08X, %s failed",
- TARGETING::get_huid(i_target),
- (i_opType == DeviceFW::READ) ? "READ" : "WRITE");
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_NOT_IN_CACHE
- * @userdata1[0:31] Op Type
- * @userdata1[32:63] Eeprom Role
- * @userdata2 Offset we are attempting to read/write
- * @custdesc Soft error in Firmware
- * @devdesc Tried to lookup eeprom not in cache
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_NOT_IN_CACHE,
- TWO_UINT32_TO_UINT64(i_opType,
- i_eepromInfo.eepromRole),
- TO_UINT64(i_eepromInfo.offset),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
- }
+ // 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].mark_target_changed = true;
+ }
- TRACSSCOMP( g_trac_eeprom, EXIT_MRK"eepromPerformOpCache() "
- "Target HUID 0x%.08X Exit", TARGETING::get_huid(i_target));
+ mutex_unlock(&g_eecacheMutex);
- }while(0);
+}
- return l_errl;
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_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.cache_entry_address;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_vaddr;
+}
+
+uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_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,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+ }
+ return l_vaddr;
}
}
diff --git a/src/usr/i2c/eepromCache.H b/src/usr/i2c/eepromCache.H
index 9e0e140d8..253367b07 100644
--- a/src/usr/i2c/eepromCache.H
+++ b/src/usr/i2c/eepromCache.H
@@ -97,10 +97,29 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
eeprom_addr_t & io_eepromInfo,
eepromRecordHeader & o_eepromRecordHeader);
+
+#ifndef __HOSTBOOT_RUNTIME
+
+/**
+*
+* @brief Check if entry already exists in g_cachedEeproms, if a match is
+* found then return true. If there is no match, add it to the list
+* and return false;
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to map
+*
+* @param[in] i_recordHeaderVaddr Virtual address to PNOR copy of header information
+*
+* @return TRUE if entry is already in map FALSE if this is a new entry
+*
+*/
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr);
+
/**
*
* @brief Perform a lookup on the global map g_cachedEeproms to get a
-* virtual address for a given EEPROM cache entry
+* virtual address for a given EEPROM entry in the EECACHE table of contents
*
* @param[in] i_eepromRecordHeader
*
@@ -110,12 +129,12 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
* @return uint64_t virtual address pointing to the cached eeprom data in pnor
*
*/
-uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader);
+uint64_t lookupEepromHeaderAddr(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
+* virtual address for a given EEPROM cache entry
*
* @param[in] i_eepromRecordHeader
*
@@ -125,9 +144,19 @@ uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader);
* @return uint64_t virtual address pointing to the cached eeprom data in pnor
*
*/
-uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader);
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader);
+
+
+/**
+*
+* @brief Print the info found in the Table of Contents of the EECACHE
+* section of pnor to trace buffer
+*
+* @return void
+*
+*/
+void printTableOfContents(void);
-#ifndef __HOSTBOOT_RUNTIME
/**
*
@@ -164,16 +193,77 @@ errlHndl_t setIsValidCacheEntry(const TARGETING::Target * i_target,
*
*/
errlHndl_t setIsValidCacheEntry(const eepromRecordHeader& i_eepromRecordHeader, bool i_isValid);
+
/**
*
-* @brief Print the info found in the Table of Contents of the EECACHE
-* section of pnor to trace buffer
+* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
+* caches and check if the eeprom has changed this IPL or not
+*
+* @param[in] i_eepromRecordHeader we want to look up
+*
+* @return bool Return TRUE if eeprom is found in map AND mark_target_changed
+ was set to true for the eeprom entry. Return FALSE otherwise.
+*
+*/
+bool hasEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader);
+
+/**
+*
+* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
+* caches and mark that it has changed this IPL
+*
+* @param[in] i_eepromRecordHeader we want to mark as changed
*
* @return void
+*/
+void setEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader);
+#else
+/**
+*
+* @brief Check if entry already exists in g_cachedEeproms, if a match is
+* found then return true. If there is no match, add it to the list
+* and return false;
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to map
+*
+* @param[in] i_recordHeaderVaddr Virtual address to PNOR copy of header information
+*
+* @param[in] i_instance Node ID that this eeprom is on
+*
+* @return TRUE if entry is already in map FALSE if this is a new entry
*
*/
-void printTableOfContents(void);
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr,
+ const uint8_t i_instance);
+/**
+*
+* @brief Perform a lookup on the global map g_cachedEeproms to get a
+* virtual address for a given EEPROM cache entry
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to lookup address for
+*
+* @param[in] i_isntance Node ID that this eeprom is on
+*
+* @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 lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader,
+ const uint8_t i_instance);
+
+/**
+*
+* @brief Walk through g_cachedEeproms map and print information about
+* the cached eeproms found
+*
+* @return void
+*
+*/
+void printCurrentCachedEepromMap(void);
#endif // __HOSTBOOT_RUNTIME
}
diff --git a/src/usr/i2c/eepromCache_common.C b/src/usr/i2c/eepromCache_common.C
new file mode 100644
index 000000000..c7a838294
--- /dev/null
+++ b/src/usr/i2c/eepromCache_common.C
@@ -0,0 +1,326 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/eepromCache_common.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 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 */
+#include "eepromCache.H"
+#include <errl/errlmanager.H>
+#include <i2c/eepromif.H>
+#include <i2c/eepromddreasoncodes.H>
+#include <errl/errludtarget.H>
+#include <config.h>
+
+#ifdef __HOSTBOOT_RUNTIME
+#include <targeting/attrrp.H>
+#else
+#include <sys/mm.h>
+#endif
+
+extern trace_desc_t* g_trac_eeprom;
+
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace EEPROM
+{
+
+errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
+ eeprom_addr_t & io_eepromInfo,
+ eepromRecordHeader & o_eepromRecordHeader)
+{
+
+ TARGETING::Target * l_muxTarget = nullptr;
+ TARGETING::Target * l_i2cMasterTarget = nullptr;
+ TARGETING::TargetService& l_targetService = TARGETING::targetService();
+ errlHndl_t l_errl = nullptr;
+
+ do{
+
+ l_errl = eepromReadAttributes(i_target, io_eepromInfo);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() error occurred reading eeprom attributes for eepromType %d, target 0x%.08X, returning!!",
+ io_eepromInfo.eepromRole,
+ TARGETING::get_huid(i_target));
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // Grab the I2C mux target so we can read the HUID, if the target is NULL we will not be able
+ // to lookup attribute to uniquely ID this eeprom so we will not cache it
+ l_muxTarget = l_targetService.toTarget( io_eepromInfo.i2cMuxPath);
+ if(l_muxTarget == nullptr)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() Mux target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache",
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_EEPROM
+ * @reasoncode EEPROM_I2C_MUX_PATH_ERROR
+ * @userdata1 HUID of target we want to cache
+ * @userdata2 Type of EEPROM we are caching
+ * @devdesc buildEepromRecordHeader invalid mux target
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_EEPROM,
+ EEPROM_I2C_MUX_PATH_ERROR,
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // Grab the I2C master target so we can read the HUID, if the target is NULL we will not be able
+ // to lookup attribute to uniquely ID this eeprom so we will not cache it
+ l_i2cMasterTarget = l_targetService.toTarget( io_eepromInfo.i2cMasterPath );
+ if(l_i2cMasterTarget == nullptr)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() I2C Master target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache ",
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_EEPROM
+ * @reasoncode EEPROM_I2C_MASTER_PATH_ERROR
+ * @userdata1 HUID of target we want to cache
+ * @userdata2 Type of EEPROM we are caching
+ * @devdesc buildEepromRecordHeader invalid master target
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_EEPROM,
+ EEPROM_I2C_MASTER_PATH_ERROR,
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // This is what we will compare w/ when we are going through the existing
+ // caches in the eeprom to see if we have already cached something
+ // Or if no matches are found we will copy this into the header
+ o_eepromRecordHeader.completeRecord.i2c_master_huid = l_i2cMasterTarget->getAttr<TARGETING::ATTR_HUID>();
+ o_eepromRecordHeader.completeRecord.port = static_cast<uint8_t>(io_eepromInfo.port);
+ o_eepromRecordHeader.completeRecord.engine = static_cast<uint8_t>(io_eepromInfo.engine);
+ o_eepromRecordHeader.completeRecord.devAddr = static_cast<uint8_t>(io_eepromInfo.devAddr);
+ o_eepromRecordHeader.completeRecord.mux_select = static_cast<uint8_t>(io_eepromInfo.i2cMuxBusSelector);
+ o_eepromRecordHeader.completeRecord.cache_copy_size = static_cast<uint32_t>(io_eepromInfo.devSize_KB);
+
+ // Do not set valid bit nor internal offset here as we do not have
+ // enough information availible to determine
+
+ }while(0);
+
+ return l_errl;
+}
+
+errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t& io_buflen,
+ eeprom_addr_t &i_eepromInfo)
+{
+ errlHndl_t l_errl = nullptr;
+ eepromRecordHeader l_eepromRecordHeader;
+
+ do{
+
+ 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);
+
+ if(l_errl)
+ {
+ // buildEepromRecordHeader should have traced any relavent information if
+ // it was needed, just break out and pass the error along
+ break;
+ }
+
+#ifndef __HOSTBOOT_RUNTIME
+ uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader);
+#else
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(i_target);
+ uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader, l_instance);
+#endif
+
+ // Ensure that a copy of the eeprom exists in our map of cached eeproms
+ if(l_eepromCacheVaddr)
+ {
+ // First check if io_buffer is a nullptr, if so then assume user is
+ // requesting size back in io_bufferlen
+ if(io_buffer == nullptr)
+ {
+ io_buflen = l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE;
+ TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
+ "io_buffer == nullptr , returning io_buflen as 0x%lx",
+ io_buflen);
+ break;
+ }
+
+ TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
+ "Performing %s on target 0x%.08X offset 0x%lx length 0x%x vaddr 0x%lx",
+ (i_opType == DeviceFW::READ) ? "READ" : "WRITE",
+ TARGETING::get_huid(i_target),
+ 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))
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: i_eepromInfo.offset + i_offset is greater than size of eeprom (0x%x KB)",
+ l_eepromRecordHeader.completeRecord.cache_copy_size);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_OVERFLOW_ERROR
+ * @userdata1 Length of Operation
+ * @userdata2 Offset we are attempting to read/write
+ * @custdesc Soft error in Firmware
+ * @devdesc cacheEeprom invalid op type
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_OVERFLOW_ERROR,
+ TO_UINT64(io_buflen),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+
+ break;
+ }
+
+ if(i_opType == DeviceFW::READ)
+ {
+ 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);
+
+#ifndef __HOSTBOOT_RUNTIME
+ // Perform flush to ensure pnor is updated
+ int rc = mm_remove_pages( FLUSH,
+ reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ 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);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_FAILED_TO_FLUSH_CONTENTS
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc cacheEeprom mm_remove_pages FLUSH failed
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_FAILED_TO_FLUSH_CONTENTS,
+ (l_eepromCacheVaddr + i_eepromInfo.offset),
+ TO_UINT64(rc),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+#endif
+ }
+ else
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d",
+ i_opType);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_INVALID_OPERATION
+ * @userdata1[0:31] Op Type that was invalid
+ * @userdata1[32:63] Eeprom Role
+ * @userdata2 Offset we are attempting to perfrom op on
+ * @custdesc Soft error in Firmware
+ * @devdesc cacheEeprom invalid op type
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_INVALID_OPERATION,
+ TWO_UINT32_TO_UINT64(i_opType,
+ i_eepromInfo.eepromRole),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_eeprom,"eepromPerformOpCache: Failed to find entry in cache for 0x%.08X, %s failed",
+ TARGETING::get_huid(i_target),
+ (i_opType == DeviceFW::READ) ? "READ" : "WRITE");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_NOT_IN_CACHE
+ * @userdata1[0:31] Op Type
+ * @userdata1[32:63] Eeprom Role
+ * @userdata2 Offset we are attempting to read/write
+ * @custdesc Soft error in Firmware
+ * @devdesc Tried to lookup eeprom not in cache
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_NOT_IN_CACHE,
+ TWO_UINT32_TO_UINT64(i_opType,
+ i_eepromInfo.eepromRole),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+
+ TRACSSCOMP( g_trac_eeprom, EXIT_MRK"eepromPerformOpCache() "
+ "Target HUID 0x%.08X Exit", TARGETING::get_huid(i_target));
+
+ }while(0);
+
+ return l_errl;
+}
+} \ No newline at end of file
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index ab7e804e1..2243e9b38 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -41,6 +41,11 @@
// va_list
#include "eepromCache.H"
#include "eepromdd_hardware.H"
+#include <i2c/eepromddreasoncodes.H>
+#ifdef __HOSTBOOT_RUNTIME
+// Need to be able to convert HB target id's to runtime target ids
+#include <targeting/attrrp.H>
+#endif
extern trace_desc_t* g_trac_eeprom;
@@ -87,6 +92,7 @@ errlHndl_t resolveSource(TARGETING::Target * i_target,
err = buildEepromRecordHeader(i_target,
io_i2cInfo,
l_eepromRecordHeader);
+#ifndef __HOSTBOOT_RUNTIME
// if lookupEepromAddr returns non-zero address
// then we know it exists in cache somewhere
if(lookupEepromCacheAddr(l_eepromRecordHeader))
@@ -99,7 +105,46 @@ errlHndl_t resolveSource(TARGETING::Target * i_target,
TRACDCOMP(g_trac_eeprom,"Eeprom not found in cache, looking at hardware");
o_source = EEPROM::HARDWARE;
}
-
+#else
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(i_target);
+ // if lookupEepromAddr returns non-zero address
+ // then we know it exists in cache somewhere
+ if(lookupEepromCacheAddr(l_eepromRecordHeader, l_instance))
+ {
+ TRACDCOMP(g_trac_eeprom,"Eeprom found in cache, looking at eecache");
+ o_source = EEPROM::CACHE;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @moduleid EEPROM_RESOLVE_SOURCE
+ * @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 resolveSource failed to find cache in map during runtime
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_RESOLVE_SOURCE,
+ 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);
+ }
+#endif
return err;
}
@@ -185,14 +230,16 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType,
{
break;
}
-
- // If the operation is a write we also need to
- // "write through" to HW after we write cache
+ // TODO RTC:212469 Complete Work needed for Axone i2c runtime support
+ #ifndef __HOSTBOOT_RUNTIME
if(i_opType == DeviceFW::WRITE)
{
+ // If the operation is a write we also need to
+ // "write through" to HW after we write cache
err = eepromPerformOpHW(i_opType, i_target,
io_buffer, io_buflen, i2cInfo);
}
+ #endif
}
else if(l_source == EEPROM::HARDWARE)
{
diff --git a/src/usr/i2c/i2c.mk b/src/usr/i2c/i2c.mk
index 6d4ef8935..0300d2c46 100644
--- a/src/usr/i2c/i2c.mk
+++ b/src/usr/i2c/i2c.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -27,4 +27,4 @@ OBJS += eepromdd.o
OBJS += eepromdd_hardware.o
OBJS += eeprom_utils.o
OBJS += errlud_i2c.o
-OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache.o)
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache_common.o)
diff --git a/src/usr/i2c/makefile b/src/usr/i2c/makefile
index 535484752..10e55c9de 100644
--- a/src/usr/i2c/makefile
+++ b/src/usr/i2c/makefile
@@ -33,6 +33,7 @@ OBJS += i2c.o
OBJS += $(if $(CONFIG_TPMDD),tpmdd.o,)
OBJS += fapi_i2c_dd.o
OBJS += i2cTargetPres.o
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache.o)
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/i2c/runtime/makefile b/src/usr/i2c/runtime/makefile
index e6bf9330b..73d3d464b 100644
--- a/src/usr/i2c/runtime/makefile
+++ b/src/usr/i2c/runtime/makefile
@@ -1,11 +1,11 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/usr/vpd/runtime/makefile $
+# $Source: src/usr/i2c/runtime/makefile $
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2015
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -32,7 +32,7 @@ include ../i2c.mk
#add unique object modules
OBJS += rt_i2c.o
-
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),rt_eepromCache.o)
VPATH += ..
include $(ROOTPATH)/config.mk
diff --git a/src/usr/i2c/runtime/rt_eepromCache.C b/src/usr/i2c/runtime/rt_eepromCache.C
new file mode 100644
index 000000000..e3b757b03
--- /dev/null
+++ b/src/usr/i2c/runtime/rt_eepromCache.C
@@ -0,0 +1,285 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/runtime/rt_eepromCache.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,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 */
+/**
+ * @file rt_eepromCache.C
+ *
+ * @brief Runtime functionality of the eeprom cache driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <i2c/eepromddreasoncodes.H>
+#include <runtime/interface.h>
+#include <runtime/rt_targeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/attrrp.H>
+#include <trace/interface.H>
+#include <util/runtime/util_rt.H>
+#include <sys/internode.h>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+
+#include "../eepromCache.H"
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_eeprom;
+
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace EEPROM
+{
+
+// 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 g_eecachePnorVaddr[MAX_NODES_PER_SYS] = {0,0,0,0,0,0,0,0};
+std::map<eepromRecordHeader, EeepromEntryMetaData_t> g_cachedEeproms[MAX_NODES_PER_SYS];
+
+// ------------------------------------------------------------------
+// rtEecacheInit
+// ------------------------------------------------------------------
+struct rtEecacheInit
+{
+ rtEecacheInit()
+ {
+ errlHndl_t l_errl = nullptr;
+
+ // Add cache status for the node
+ TARGETING::TargetHandleList l_nodeList;
+ getEncResources(l_nodeList,
+ TARGETING::TYPE_NODE,
+ TARGETING::UTIL_FILTER_ALL);
+ // Find all the targets with VPD switches
+ for (auto & l_node : l_nodeList)
+ {
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(l_node);
+ uint64_t vpd_size = 0;
+ eecacheSectionHeader* l_sectionHeader =
+ reinterpret_cast<eecacheSectionHeader*>(
+ hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_VPD,
+ l_instance, vpd_size));
+
+ g_eecachePnorVaddr[l_instance] = reinterpret_cast<uint64_t>(l_sectionHeader);
+
+ // Check if reserved memory does not exist for this instance
+ if ((NULL == l_sectionHeader) || (0 == vpd_size))
+ {
+ TRACFCOMP(g_trac_eeprom,
+ "rtEecacheInit(): ERROR Could not find VPD section of reserved memory for Node %d, ",
+ l_instance);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_CACHE_INIT_RT
+ * @reasoncode EEPROM_CACHE_NO_VPD_IN_RSV_MEM
+ * @userdata1 Node Id
+ * @userdata2 Unused
+ *
+ * @devdesc Attempted to lookup VPD in reserved memory
+ * and failed
+ * @custdesc A problem occurred during the IPL of the
+ * system.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM::EEPROM_CACHE_INIT_RT,
+ EEPROM::EEPROM_CACHE_NO_VPD_IN_RSV_MEM,
+ l_instance,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ errlCommit (l_errl, EEPROM_COMP_ID);
+ break;
+
+ }
+
+ eepromRecordHeader * l_recordHeaderToCopy = nullptr;
+ uint8_t l_eepromCount = 0;
+ for(int8_t i = 0; i < MAX_EEPROMS_VERSION_1; i++)
+ {
+ // Keep track of current record so we can use outside for loop
+ l_recordHeaderToCopy = &l_sectionHeader->recordHeaders[i];
+
+ // If internal_offset is UNSET_INTERNAL_OFFSET_VALUE then we will assume this address not been filled
+ if(l_recordHeaderToCopy->completeRecord.internal_offset != UNSET_INTERNAL_OFFSET_VALUE)
+ {
+ l_eepromCount++;
+ // Will return true if already found an entry in the list
+ if(addEepromToCachedList(*l_recordHeaderToCopy,
+ reinterpret_cast<uint64_t>(l_recordHeaderToCopy),
+ l_instance))
+ {
+
+ TRACFCOMP(g_trac_eeprom,
+ "rtEecacheInit(): ERROR Duplicate cache entries found in VPD reserved memory section");
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_CACHE_INIT_RT
+ * @reasoncode EEPROM_DUPLICATE_CACHE_ENTRY
+ * @userdata1[0:31] i2c_master_huid
+ * @userdata1[32:39] port on i2c master eeprom slave is on
+ * @userdata1[40:47] engine on i2c master eeprom slave is on
+ * @userdata1[48:55] devAddr of eeprom slave
+ * @userdata1[56:63] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:31] size of eeprom
+ * @userdata2[32:63] Node Id
+ * @devdesc Attempted to lookup VPD in reserved memory
+ * and failed
+ * @custdesc A problem occurred during the IPL of the
+ * system.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM::EEPROM_CACHE_INIT_RT,
+ EEPROM::EEPROM_DUPLICATE_CACHE_ENTRY,
+ TWO_UINT32_TO_UINT64(
+ l_recordHeaderToCopy->completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ l_recordHeaderToCopy->completeRecord.port,
+ l_recordHeaderToCopy->completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ l_recordHeaderToCopy->completeRecord.devAddr,
+ l_recordHeaderToCopy->completeRecord.mux_select))),
+ TWO_UINT32_TO_UINT64(l_recordHeaderToCopy->completeRecord.cache_copy_size,
+ TO_UINT32(l_instance)),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ errlCommit (l_errl, EEPROM_COMP_ID);
+ // Something is wrong so we have committed the unrecoverable
+ // but keep processing the eeproms because we want a full picture
+ // of what we understand the eeprom cache contents to be
+ continue;
+ }
+ }
+ }
+
+ TRACFCOMP(g_trac_eeprom, "Found %d cached eeproms in reserved memory for node %d",
+ l_eepromCount, l_instance);
+
+ printCurrentCachedEepromMap();
+
+ }
+ }
+
+};
+rtEecacheInit g_rtEecacheInit;
+
+void printCurrentCachedEepromMap(void)
+{
+ TRACFCOMP( g_trac_eeprom,
+ "printCurrentCachedEepromMap():");
+
+ mutex_lock(&g_eecacheMutex);
+ for(int8_t i = 0; i < MAX_NODES_PER_SYS; i++)
+ {
+ for(std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator iter = g_cachedEeproms[i].begin();
+ iter != g_cachedEeproms[i].end();
+ ++iter)
+ {
+ TRACSSCOMP( 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",
+ iter->first.completeRecord.i2c_master_huid,
+ iter->first.completeRecord.port,
+ iter->first.completeRecord.engine,
+ iter->first.completeRecord.devAddr,
+ iter->first.completeRecord.mux_select,
+ iter->first.completeRecord.cache_copy_size);
+
+ TRACSSCOMP( g_trac_eeprom,
+ " "
+ "Internal Offset: 0x%.08X, Cache Valid: 0x%.02X",
+ iter->first.completeRecord.internal_offset,
+ iter->first.completeRecord.cached_copy_valid);
+ }
+ }
+ mutex_unlock(&g_eecacheMutex);
+
+}
+
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader,
+ const uint8_t i_instance)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator l_it;
+
+ // Wrap lookup in mutex because reads are not thread safe
+ mutex_lock(&g_eecacheMutex);
+ l_it = g_cachedEeproms[i_instance].find(i_eepromRecordHeader);
+
+ if(l_it != g_cachedEeproms[i_instance].end())
+ {
+ l_vaddr = l_it->second.cache_entry_address;
+ }
+ mutex_unlock(&g_eecacheMutex);
+ return l_vaddr;
+}
+
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr,
+ const uint8_t i_instance)
+{
+ bool l_matchFound = true;
+
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
+
+ if(g_cachedEeproms[i_instance].find(i_eepromRecordHeader) ==
+ g_cachedEeproms[i_instance].end())
+ {
+ g_cachedEeproms[i_instance][i_eepromRecordHeader].cache_entry_address =
+ g_eecachePnorVaddr[i_instance] + i_eepromRecordHeader.completeRecord.internal_offset;
+
+ g_cachedEeproms[i_instance][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,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+
+ l_matchFound = false;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_matchFound;
+}
+
+} // end namespace EEPROM
diff --git a/src/usr/vpd/makefile b/src/usr/vpd/makefile
index 728750fca..9ef60d788 100644
--- a/src/usr/vpd/makefile
+++ b/src/usr/vpd/makefile
@@ -31,7 +31,6 @@ include vpd.mk
#include unique objects
OBJS += vpd.o
OBJS += dimmPres.o
-OBJS += ocmb_spd.o
OBJS += rtvpd_load.o
SUBDIRS += test.d
diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C
index 26ad6f031..f12d23d01 100644
--- a/src/usr/vpd/rtvpd_load.C
+++ b/src/usr/vpd/rtvpd_load.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -108,6 +108,7 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & i_vpd_addr)
do
{
+#ifndef CONFIG_SUPPORT_EEPROM_CACHING
void* vptr = reinterpret_cast<void*>(i_vpd_addr);
uint8_t* vpd_ptr = reinterpret_cast<uint8_t*>(vptr);
@@ -136,6 +137,21 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & i_vpd_addr)
{
break;
}
+#else
+ // In Axone we store all contents of EEPROMs in EECACHE
+ // so copy the EECACHE pnor section to the space in reserved
+ // memory allocated for VPD.
+ void* vptr = reinterpret_cast<void*>(i_vpd_addr);
+ uint8_t* vpd_ptr = reinterpret_cast<uint8_t*>(vptr);
+
+ err = bld_vpd_image(PNOR::EECACHE,
+ vpd_ptr,
+ VMM_RT_VPD_SIZE);
+ if(err)
+ {
+ break;
+ }
+#endif
} while( 0 );
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index afa7417a6..dbae8feae 100644
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -1314,13 +1314,11 @@ errlHndl_t fetchDataFromEepromType(uint64_t i_byteAddr,
}
else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
{
-#ifndef __HOSTBOOT_RUNTIME
errl = ocmbFetchData(i_target,
i_byteAddr,
i_numBytes,
o_data,
EEPROM::AUTOSELECT);
-#endif
}
return errl;
diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk
index d5717e653..aa3333291 100644
--- a/src/usr/vpd/vpd.mk
+++ b/src/usr/vpd/vpd.mk
@@ -34,4 +34,5 @@ OBJS += cvpd.o
OBJS += pvpd.o
OBJS += dvpd.o
OBJS += spd.o
+OBJS += ocmb_spd.o
OBJS += errlud_vpd.o
diff --git a/src/usr/vpd/vpd_common.C b/src/usr/vpd/vpd_common.C
index 0196b8be8..92c4e9294 100644
--- a/src/usr/vpd/vpd_common.C
+++ b/src/usr/vpd/vpd_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -156,6 +156,8 @@ bool resolveVpdSource( TARGETING::Target * i_target,
}
}
+ TRACDCOMP(g_trac_vpd,"resolveVpdSource: o_vpdSource = %s" ,o_vpdSource == VPD::PNOR ? "PNOR" : "SEEPROM" );
+
return badConfig;
}
OpenPOWER on IntegriCloud