[Gems-users] Stale Data Accesses


Date: Tue, 3 May 2005 12:31:10 -0500 (CDT)
From: Luke Yen <lyen@xxxxxxxxxxx>
Subject: [Gems-users] Stale Data Accesses
  I have been working with Sid on this issue, and here's what I wrote to
him in an earlier email.  This issue should be corrected in a future
release.

1) Our research tree and our GEMS release trees have deviated quite a bit.
Hence the code that I am using to obtain stale data values is totally
different then what you are using.  The CacheMemory.h that I am using
(which is NOT available in GEMS) contains this snipet of code to set the
stale data value array:

template<class ENTRY>
inline
void CacheMemory<ENTRY>::changePermission(const Address& address,
AccessPermission new_perm)
{
  assert(address == line_address(address));
  Index    cacheSet = addressToCacheSet(address);
  CacheTag tag  = addressToCacheTag(address);

  int loc = findTagInSet(cacheSet, tag);
  ASSERT( loc != -1 );
  AccessPermission old_perm = m_cache[cacheSet][loc].m_permission;
  m_cache[cacheSet][loc].m_permission = new_perm;

  // if downgrading to AccessPermission_Invalid, store the stale data
values
  // in m_stale_data. Stale data is read from simics's memory system.
  if (new_perm == AccessPermission_Invalid) {
    Vector<int8> &stale_data = m_cache[cacheSet][loc].m_stale_data;
    if (g_SIMICS) {
      for(int j=0; j < RubyConfig::dataBlockBytes(); j++) {
        stale_data[j] = SIMICS_read_physical_memory( m_chip_ptr->getID(),

address.getAddress()+j,
                                                     1 );
      }
    }
    m_cache[cacheSet][loc].m_stale_valid = true;
  }

  // Treat AccessPermission_NotPresent the same as Invalid
  if (new_perm == AccessPermission_NotPresent) {
    new_perm = AccessPermission_Invalid;
  }
}

  And to read the value, there exists a staleDataAccess function:

template<class ENTRY>
inline
bool CacheMemory<ENTRY>::staleDataAccess(const Address& address, unsigned
int requestSize, int8 *dataBuffer ) const
{
  Address lineaddr = line_address(address);
  Index cacheSet = addressToCacheSet(lineaddr);
  CacheTag tag   = addressToCacheTag(lineaddr);
  int location   = findTagInSet(cacheSet, tag);

  if (location == -1)
    return false;
  if (m_cache[cacheSet][location].m_permission ==
AccessPermission_NotPresent)
    return false;
  if (m_cache[cacheSet][location].m_stale_valid != true)
    return false;

  // copy the requested bytes from the cache line into the buffer
  const Vector<int8>& stale_data =
m_cache[cacheSet][location].m_stale_data;
  // round request size (in bytes) to double-words
  cout << "****StaleDataAccess: data[";
  for (int j=0; j < RubyConfig::dataBlockBytes(); j++) {
    dataBuffer[j] = stale_data[j];
    cout << hex << stale_data[j] << " ";
  }
  cout << "]"<< endl;

  return true;
}


2)  My understanding is that our research tree contains multiple
files implementing the same functionality as CacheMemory.h, and my guess
is that we found this to be too confusing to release to the public, so we
axed the different versions and released only one version.  Hence the GEMS
CacheMemory.h doesn't have these two functions.
  Having said that, I believe we have made a mistake in CacheMemory.h.
The only place where any cache entry's data block is actually set is in
DirectoryMemory.C, in the lookup() function.  However, from the code you
have sent me you are clearly only searching the L1 cache objects and not
the direcotry object.  In essence, your code should be returning zeroed
out values because no built-in code is setting the data block array.  To
correct this, you should copy the code in DirectoryMemory.C to set the
cache entry's value inside CacheMemory.h.


  Luke

[← Prev in Thread] Current Thread [Next in Thread→]
  • [Gems-users] Stale Data Accesses, Luke Yen <=