Add register cache support in HardwareRegister class
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: Ic671a099fdcd98d1f0158289ef321b968f1908ca
diff --git a/src/register/hei_hardware_register.cpp b/src/register/hei_hardware_register.cpp
index 5663f3b..58106bf 100755
--- a/src/register/hei_hardware_register.cpp
+++ b/src/register/hei_hardware_register.cpp
@@ -18,7 +18,6 @@
#include <iipchip.h>
#include <prdfMain.H>
#include <prdfRasServices.H>
-#include <prdfRegisterCache.H>
#include <prdfPlatServices.H>
#include <prdfExtensibleChip.H>
@@ -69,14 +68,16 @@
// Calling Read() will ensure that an entry exists in the cache and the
// entry has at been synched with hardware at least once. Note that we
// cannot read hardware for write-only registers. In this case, an entry
- // will be created in the cache, if it does not exist, when readCache() is
- // called below.
+ // will be created in the cache, if it does not exist, when the cache is
+ // read below.
+
if ( ( ACCESS_NONE != iv_operationType ) &&
- ( ACCESS_WO != iv_operationType ) )
+ ( ACCESS_WO != iv_operationType ) )
{
Read();
}
- return &(readCache());
+
+ return &( accessCache() );
}
//------------------------------------------------------------------------------
@@ -86,15 +87,16 @@
// Calling Read() will ensure that an entry exists in the cache and the
// entry has at been synched with hardware at least once. Note that we
// cannot read hardware for write-only registers. In this case, an entry
- // will be created in the cache, if it does not exist, when readCache() is
- // called below.
+ // will be created in the cache, if it does not exist, when the cache is
+ // read below.
+
if ( ( ACCESS_NONE != iv_operationType ) &&
- ( ACCESS_WO != iv_operationType ) )
+ ( ACCESS_WO != iv_operationType ) )
{
Read();
}
- return readCache();
+ return accessCache();
}
#endif
@@ -104,17 +106,17 @@
{
ReturnCode rc;
-#if 0
// Read from hardware only if the read is forced or the entry for this
// instance does not exist in the cache.
if ( i_force || !queryCache() )
{
+#if 0
// This register must be readable.
HEI_ASSERT( ( ACCESS_NONE != iv_operationType ) &&
( ACCESS_WO != iv_operationType ) );
// Get the buffer from the register cache.
- BitString & bs = readCache();
+ BitString & bs = accessCache();
// Get the byte size of the buffer.
size_t sz_buffer = BitString::getMinBytes( bs.getBitLen() );
@@ -122,20 +124,22 @@
// Read this register from hardware.
rc = registerRead( getAccessorChip().getChip(), bs.getBufAddr(),
sz_buffer, getRegisterType(), getAddress() );
+#endif
if ( RC_SUCCESS != rc )
{
// The read failed and we can't trust what was put in the register
// cache. So remove this instance's entry from the cache.
- flushCache( getAccessorChip() );
+ cv_cache.flush( getAccessorChip(), this );
}
+#if 0
else
{
// Sanity check. The returned size of the data written to the buffer
// should match the register size.
HEI_ASSERT( getSize() == sz_buffer );
}
- }
#endif
+ }
return rc;
}
@@ -157,7 +161,7 @@
HEI_ASSERT( queryCache() );
// Get the buffer from the register cache.
- BitString & bs = readCache();
+ BitString & bs = accessCache();
// Get the byte size of the buffer.
size_t sz_buffer = BitString::getMinBytes( bs.getBitLen() );
@@ -182,38 +186,6 @@
#if 0
//------------------------------------------------------------------------------
-bool HardwareRegister::queryCache() const
-{
- RegDataCache & cache = RegDataCache::getCachedRegisters();
- BitString * bs = cache.queryCache( getAccessorChip(), this );
- return ( nullptr != bs );
-}
-
-//------------------------------------------------------------------------------
-
-BitString & HardwareRegister::readCache() const
-{
- RegDataCache & cache = RegDataCache::getCachedRegisters();
- return cache.read( getAccessorChip(), this );
-}
-
-//------------------------------------------------------------------------------
-
-void HardwareRegister::flushCache( ExtensibleChip *i_pChip ) const
-{
- RegDataCache & regDump = RegDataCache::getCachedRegisters();
- if( nullptr == i_pChip )
- {
- regDump.flush();
- }
- else
- {
- regDump.flush( i_pChip ,this );
- }
-}
-
-//-----------------------------------------------------------------------------
-
bool HardwareRegister::operator == ( const HardwareRegister & i_rightRegister ) const
{
if( iv_scomAddress == i_rightRegister.GetAddress() )
@@ -254,5 +226,95 @@
//------------------------------------------------------------------------------
+HardwareRegister::Cache HardwareRegister::cv_cache {};
+
+//------------------------------------------------------------------------------
+
+bool HardwareRegister::Cache::query( const Chip & i_chip,
+ const HardwareRegister * i_hwReg ) const
+{
+ // Does i_chip exist in the cache?
+ auto chipPairItr = iv_cache.find( i_chip );
+ if ( iv_cache.end() != chipPairItr )
+ {
+ auto & hwRegMap = chipPairItr->second; // for ease of use
+
+ // Does i_hwReg exist in the cache?
+ auto hwRegPairItr = hwRegMap.find( i_hwReg );
+ if ( hwRegMap.end() != hwRegPairItr )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------------------
+
+BitString & HardwareRegister::Cache::access( const Chip & i_chip,
+ const HardwareRegister * i_hwReg )
+{
+ // If the entry does not exist, create a new entry.
+ if ( !query(i_chip, i_hwReg) )
+ {
+ BitString * bs = new BitStringBuffer { i_hwReg->getByteSize() * 8 };
+ iv_cache[i_chip][i_hwReg] = bs;
+ }
+
+ // Return a reference to the target entry.
+ return *(iv_cache[i_chip][i_hwReg]);
+}
+
+//------------------------------------------------------------------------------
+
+void HardwareRegister::Cache::flush()
+{
+ // Delete all of the BitStrings.
+ for ( auto & chipPair : iv_cache )
+ {
+ for ( auto & hwRegPair : chipPair.second )
+ {
+ delete hwRegPair.second;
+ }
+ }
+
+ // !!! Do not delete the HardwareRegisters !!!
+ // Those are deleted when the main uninitialize() API is called.
+
+ // Flush the rest of the cache.
+ iv_cache.clear();
+}
+
+//------------------------------------------------------------------------------
+
+void HardwareRegister::Cache::flush( const Chip & i_chip,
+ const HardwareRegister * i_hwReg )
+{
+ // Does i_chip exist in the cache?
+ auto chipPairItr = iv_cache.find( i_chip );
+ if ( iv_cache.end() != chipPairItr )
+ {
+ auto & hwRegMap = chipPairItr->second; // for ease of use
+
+ // Does i_hwReg exist in the cache?
+ auto hwRegPairItr = hwRegMap.find( i_hwReg );
+ if ( hwRegMap.end() != hwRegPairItr )
+ {
+ delete hwRegPairItr->second; // delete the BitString
+ hwRegMap.erase(i_hwReg); // remove the entry for this register
+ }
+
+ // If i_hwReg was the only entry for i_chip, we can remove i_chip from
+ // the cache.
+ if ( hwRegMap.empty() )
+ {
+ iv_cache.erase(i_chip);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
} // end namespace libhei