summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/DirectoryMemory.cc
diff options
context:
space:
mode:
authorBrad Beckmann <Brad.Beckmann@amd.com>2010-03-21 21:22:21 -0700
committerBrad Beckmann <Brad.Beckmann@amd.com>2010-03-21 21:22:21 -0700
commit92cfd1cac7f6f2d0abf64808f08f063cd0db1263 (patch)
treea69a2964f7342083cd8aaca5ed32df207a1edea8 /src/mem/ruby/system/DirectoryMemory.cc
parentb5e4c3cbf2de32e18029b44b16b307a773b6ecf7 (diff)
downloadgem5-92cfd1cac7f6f2d0abf64808f08f063cd0db1263.tar.xz
ruby: Ruby support for sparse memory
The patch includes direct support for the MI example protocol.
Diffstat (limited to 'src/mem/ruby/system/DirectoryMemory.cc')
-rw-r--r--src/mem/ruby/system/DirectoryMemory.cc108
1 files changed, 78 insertions, 30 deletions
diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc
index adf63d06f..78ca1e9e4 100644
--- a/src/mem/ruby/system/DirectoryMemory.cc
+++ b/src/mem/ruby/system/DirectoryMemory.cc
@@ -51,14 +51,24 @@ DirectoryMemory::DirectoryMemory(const Params *p)
m_version = p->version;
m_size_bytes = p->size;
m_size_bits = log_int(m_size_bytes);
+ m_num_entries = 0;
+ m_use_map = p->use_map;
+ m_map_levels = p->map_levels;
}
void DirectoryMemory::init()
{
m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
- m_entries = new Directory_Entry*[m_num_entries];
- for (int i=0; i < m_num_entries; i++)
- m_entries[i] = NULL;
+
+ if (m_use_map) {
+ int entry_bits = log_int(m_num_entries);
+ assert(entry_bits >= m_map_levels);
+ m_sparseMemory = new SparseMemory(entry_bits, m_map_levels);
+ } else {
+ m_entries = new Directory_Entry*[m_num_entries];
+ for (int i=0; i < m_num_entries; i++)
+ m_entries[i] = NULL;
+ }
m_ram = g_system_ptr->getMemoryVector();
@@ -70,13 +80,15 @@ void DirectoryMemory::init()
DirectoryMemory::~DirectoryMemory()
{
// free up all the directory entries
- for (uint64 i=0;i<m_num_entries;i++) {
- if (m_entries[i] != NULL) {
- delete m_entries[i];
- }
- }
if (m_entries != NULL) {
- delete [] m_entries;
+ for (uint64 i = 0; i < m_num_entries; i++) {
+ if (m_entries[i] != NULL) {
+ delete m_entries[i];
+ }
+ }
+ delete [] m_entries;
+ } else if (m_use_map) {
+ delete m_sparseMemory;
}
}
@@ -102,14 +114,14 @@ void DirectoryMemory::printGlobalConfig(ostream & out)
<< "-" << RubySystem::getBlockSizeBits() << endl;
}
out << " total memory size bytes: " << m_total_size_bytes << endl;
- out << " total memory size bits: " << log_int(m_total_size_bytes) << endl;
+ out << " total memory bits: " << log_int(m_total_size_bytes) << endl;
}
-int DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
+uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
{
if (m_num_directories_bits == 0) return 0;
- int ret = address.bitSelect(RubySystem::getBlockSizeBits(),
+ uint64 ret = address.bitSelect(RubySystem::getBlockSizeBits(),
RubySystem::getBlockSizeBits()+m_num_directories_bits-1);
return ret;
}
@@ -121,9 +133,10 @@ bool DirectoryMemory::isPresent(PhysAddress address)
return ret;
}
-int DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
+uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
{
- int ret = address.getAddress() >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
+ uint64 ret = address.getAddress()
+ >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
return ret;
}
@@ -131,13 +144,32 @@ Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
{
assert(isPresent(address));
Directory_Entry* entry;
- int idx = mapAddressToLocalIdx(address);
- entry = m_entries[idx];
- if (entry == NULL) {
- entry = new Directory_Entry;
- entry->getDataBlk().assign(m_ram->getBlockPtr(address));
- m_entries[idx] = entry;
+ uint64 idx;
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+
+ if (m_use_map) {
+ if (m_sparseMemory->exist(address)) {
+ entry = m_sparseMemory->lookup(address);
+ assert(entry != NULL);
+ } else {
+ //
+ // Note: SparseMemory internally creates a new Directory Entry
+ //
+ m_sparseMemory->add(address);
+ entry = m_sparseMemory->lookup(address);
+ }
+ } else {
+ idx = mapAddressToLocalIdx(address);
+ assert(idx < m_num_entries);
+ entry = m_entries[idx];
+
+ if (entry == NULL) {
+ entry = new Directory_Entry();
+ entry->getDataBlk().assign(m_ram->getBlockPtr(address));
+ m_entries[idx] = entry;
+ }
}
+
return (*entry);
}
/*
@@ -169,20 +201,29 @@ Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
void DirectoryMemory::invalidateBlock(PhysAddress address)
{
- /*
- assert(isPresent(address));
-
- Index index = address.memoryModuleIndex();
-
- if (index < 0 || index > m_size) {
- ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
+
+ if (m_use_map) {
+ assert(m_sparseMemory->exist(address));
+ m_sparseMemory->remove(address);
}
+ /*
+ else {
+ assert(isPresent(address));
+
+ Index index = address.memoryModuleIndex();
+
+ if (index < 0 || index > m_size) {
+ ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
+ }
- if(m_entries[index] != NULL){
- delete m_entries[index];
- m_entries[index] = NULL;
+ if(m_entries[index] != NULL){
+ delete m_entries[index];
+ m_entries[index] = NULL;
+ }
}
*/
+
+
}
void DirectoryMemory::print(ostream& out) const
@@ -190,6 +231,13 @@ void DirectoryMemory::print(ostream& out) const
}
+void DirectoryMemory::printStats(ostream& out) const
+{
+ if (m_use_map) {
+ m_sparseMemory->printStats(out);
+ }
+}
+
DirectoryMemory *
RubyDirectoryMemoryParams::create()
{