From 92cfd1cac7f6f2d0abf64808f08f063cd0db1263 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Sun, 21 Mar 2010 21:22:21 -0700 Subject: ruby: Ruby support for sparse memory The patch includes direct support for the MI example protocol. --- src/mem/ruby/system/DirectoryMemory.cc | 108 ++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 30 deletions(-) (limited to 'src/mem/ruby/system/DirectoryMemory.cc') 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> (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() { -- cgit v1.2.3