DirectoryMemory.cc revision 7025
14120Sgblack@eecs.umich.edu 24120Sgblack@eecs.umich.edu/* 37087Snate@binkert.org * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 47087Snate@binkert.org * All rights reserved. 57087Snate@binkert.org * 67087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 77087Snate@binkert.org * modification, are permitted provided that the following conditions are 87087Snate@binkert.org * met: redistributions of source code must retain the above copyright 97087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 107087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 117087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 127087Snate@binkert.org * documentation and/or other materials provided with the distribution; 137087Snate@binkert.org * neither the name of the copyright holders nor the names of its 147087Snate@binkert.org * contributors may be used to endorse or promote products derived from 154120Sgblack@eecs.umich.edu * this software without specific prior written permission. 164120Sgblack@eecs.umich.edu * 174120Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 184120Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 194120Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 204120Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 214120Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 224120Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 234120Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 244120Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 254120Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 264120Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 274120Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 284120Sgblack@eecs.umich.edu */ 294120Sgblack@eecs.umich.edu 304120Sgblack@eecs.umich.edu/* 314120Sgblack@eecs.umich.edu * DirectoryMemory.cc 324120Sgblack@eecs.umich.edu * 334120Sgblack@eecs.umich.edu * Description: See DirectoryMemory.hh 344120Sgblack@eecs.umich.edu * 354120Sgblack@eecs.umich.edu * $Id$ 364120Sgblack@eecs.umich.edu * 374120Sgblack@eecs.umich.edu */ 384120Sgblack@eecs.umich.edu 394120Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 404120Sgblack@eecs.umich.edu#include "mem/ruby/system/DirectoryMemory.hh" 414120Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 424120Sgblack@eecs.umich.edu#include "mem/gems_common/util.hh" 434202Sbinkertn@umich.edu 445069Sgblack@eecs.umich.eduint DirectoryMemory::m_num_directories = 0; 454202Sbinkertn@umich.eduint DirectoryMemory::m_num_directories_bits = 0; 465659Sgblack@eecs.umich.eduuint64_t DirectoryMemory::m_total_size_bytes = 0; 479022Sgblack@eecs.umich.edu 489023Sgblack@eecs.umich.eduDirectoryMemory::DirectoryMemory(const Params *p) 494601Sgblack@eecs.umich.edu : SimObject(p) 505124Sgblack@eecs.umich.edu{ 517966Sgblack@eecs.umich.edu m_version = p->version; 525083Sgblack@eecs.umich.edu m_size_bytes = p->size; 534679Sgblack@eecs.umich.edu m_size_bits = log_int(m_size_bytes); 546515Sgblack@eecs.umich.edu m_num_entries = 0; 555083Sgblack@eecs.umich.edu m_use_map = p->use_map; 564679Sgblack@eecs.umich.edu m_map_levels = p->map_levels; 574679Sgblack@eecs.umich.edu} 588745Sgblack@eecs.umich.edu 596313Sgblack@eecs.umich.eduvoid DirectoryMemory::init() 608771Sgblack@eecs.umich.edu{ 618771Sgblack@eecs.umich.edu m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); 628771Sgblack@eecs.umich.edu 638771Sgblack@eecs.umich.edu if (m_use_map) { 646365Sgblack@eecs.umich.edu int entry_bits = log_int(m_num_entries); 655124Sgblack@eecs.umich.edu assert(entry_bits >= m_map_levels); 668752Sgblack@eecs.umich.edu m_sparseMemory = new SparseMemory(entry_bits, m_map_levels); 678771Sgblack@eecs.umich.edu } else { 684202Sbinkertn@umich.edu m_entries = new Directory_Entry*[m_num_entries]; 698771Sgblack@eecs.umich.edu for (int i=0; i < m_num_entries; i++) 708771Sgblack@eecs.umich.edu m_entries[i] = NULL; 714997Sgblack@eecs.umich.edu } 727624Sgblack@eecs.umich.edu 735135Sgblack@eecs.umich.edu m_ram = g_system_ptr->getMemoryVector(); 748753Sgblack@eecs.umich.edu 754997Sgblack@eecs.umich.edu m_num_directories++; 768745Sgblack@eecs.umich.edu m_num_directories_bits = log_int(m_num_directories); 776365Sgblack@eecs.umich.edu m_total_size_bytes += m_size_bytes; 788771Sgblack@eecs.umich.edu} 798740Sgblack@eecs.umich.edu 806365Sgblack@eecs.umich.eduDirectoryMemory::~DirectoryMemory() 818740Sgblack@eecs.umich.edu{ 828745Sgblack@eecs.umich.edu // free up all the directory entries 838752Sgblack@eecs.umich.edu if (m_entries != NULL) { 848752Sgblack@eecs.umich.edu for (uint64 i = 0; i < m_num_entries; i++) { 859023Sgblack@eecs.umich.edu if (m_entries[i] != NULL) { 868335Snate@binkert.org delete m_entries[i]; 874120Sgblack@eecs.umich.edu } 885069Sgblack@eecs.umich.edu } 895081Sgblack@eecs.umich.edu delete [] m_entries; 905081Sgblack@eecs.umich.edu } else if (m_use_map) { 915081Sgblack@eecs.umich.edu delete m_sparseMemory; 925081Sgblack@eecs.umich.edu } 935081Sgblack@eecs.umich.edu} 945081Sgblack@eecs.umich.edu 955081Sgblack@eecs.umich.eduvoid DirectoryMemory::printConfig(ostream& out) const 965081Sgblack@eecs.umich.edu{ 975081Sgblack@eecs.umich.edu out << "DirectoryMemory module config: " << m_name << endl; 985081Sgblack@eecs.umich.edu out << " version: " << m_version << endl; 995081Sgblack@eecs.umich.edu out << " memory_bits: " << m_size_bits << endl; 1005081Sgblack@eecs.umich.edu out << " memory_size_bytes: " << m_size_bytes << endl; 1015081Sgblack@eecs.umich.edu out << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl; 1025081Sgblack@eecs.umich.edu out << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl; 1035081Sgblack@eecs.umich.edu out << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl; 1045081Sgblack@eecs.umich.edu} 1055081Sgblack@eecs.umich.edu 1065081Sgblack@eecs.umich.edu// Static method 1075081Sgblack@eecs.umich.eduvoid DirectoryMemory::printGlobalConfig(ostream & out) 1085081Sgblack@eecs.umich.edu{ 1095081Sgblack@eecs.umich.edu out << "DirectoryMemory Global Config: " << endl; 1105081Sgblack@eecs.umich.edu out << " number of directory memories: " << m_num_directories << endl; 1115081Sgblack@eecs.umich.edu if (m_num_directories > 1) { 1125081Sgblack@eecs.umich.edu out << " number of selection bits: " << m_num_directories_bits << endl; 1135081Sgblack@eecs.umich.edu out << " selection bits: " << RubySystem::getBlockSizeBits()+m_num_directories_bits-1 1145081Sgblack@eecs.umich.edu << "-" << RubySystem::getBlockSizeBits() << endl; 1155081Sgblack@eecs.umich.edu } 1165081Sgblack@eecs.umich.edu out << " total memory size bytes: " << m_total_size_bytes << endl; 1175081Sgblack@eecs.umich.edu out << " total memory bits: " << log_int(m_total_size_bytes) << endl; 1185081Sgblack@eecs.umich.edu 1195081Sgblack@eecs.umich.edu} 1205081Sgblack@eecs.umich.edu 1215081Sgblack@eecs.umich.eduuint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) 1225081Sgblack@eecs.umich.edu{ 1235081Sgblack@eecs.umich.edu if (m_num_directories_bits == 0) return 0; 1245081Sgblack@eecs.umich.edu uint64 ret = address.bitSelect(RubySystem::getBlockSizeBits(), 1255081Sgblack@eecs.umich.edu RubySystem::getBlockSizeBits()+m_num_directories_bits-1); 1265081Sgblack@eecs.umich.edu return ret; 1275081Sgblack@eecs.umich.edu} 1285081Sgblack@eecs.umich.edu 1295081Sgblack@eecs.umich.edu// Public method 1305081Sgblack@eecs.umich.edubool DirectoryMemory::isPresent(PhysAddress address) 1315081Sgblack@eecs.umich.edu{ 1325081Sgblack@eecs.umich.edu bool ret = (mapAddressToDirectoryVersion(address) == m_version); 1335081Sgblack@eecs.umich.edu return ret; 1345081Sgblack@eecs.umich.edu} 1355081Sgblack@eecs.umich.edu 1365081Sgblack@eecs.umich.eduuint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address) 1375081Sgblack@eecs.umich.edu{ 1385081Sgblack@eecs.umich.edu uint64 ret = address.getAddress() 1395081Sgblack@eecs.umich.edu >> (RubySystem::getBlockSizeBits() + m_num_directories_bits); 1405081Sgblack@eecs.umich.edu return ret; 1415081Sgblack@eecs.umich.edu} 1425081Sgblack@eecs.umich.edu 1435081Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address) 1445680Sgblack@eecs.umich.edu{ 1455081Sgblack@eecs.umich.edu assert(isPresent(address)); 1465933Sgblack@eecs.umich.edu Directory_Entry* entry; 1475173Sgblack@eecs.umich.edu uint64 idx; 1485359Sgblack@eecs.umich.edu DEBUG_EXPR(CACHE_COMP, HighPrio, address); 1495081Sgblack@eecs.umich.edu 1505149Sgblack@eecs.umich.edu if (m_use_map) { 1515298Sgblack@eecs.umich.edu if (m_sparseMemory->exist(address)) { 1525081Sgblack@eecs.umich.edu entry = m_sparseMemory->lookup(address); 1535081Sgblack@eecs.umich.edu assert(entry != NULL); 1545081Sgblack@eecs.umich.edu } else { 1555081Sgblack@eecs.umich.edu // 1565081Sgblack@eecs.umich.edu // Note: SparseMemory internally creates a new Directory Entry 1575081Sgblack@eecs.umich.edu // 1585081Sgblack@eecs.umich.edu m_sparseMemory->add(address); 1595081Sgblack@eecs.umich.edu entry = m_sparseMemory->lookup(address); 1605081Sgblack@eecs.umich.edu } 1615081Sgblack@eecs.umich.edu } else { 1625081Sgblack@eecs.umich.edu idx = mapAddressToLocalIdx(address); 1635081Sgblack@eecs.umich.edu assert(idx < m_num_entries); 1645081Sgblack@eecs.umich.edu entry = m_entries[idx]; 1655081Sgblack@eecs.umich.edu 1665081Sgblack@eecs.umich.edu if (entry == NULL) { 1675081Sgblack@eecs.umich.edu entry = new Directory_Entry(); 1685081Sgblack@eecs.umich.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 1695081Sgblack@eecs.umich.edu m_entries[idx] = entry; 1705081Sgblack@eecs.umich.edu } 1715081Sgblack@eecs.umich.edu } 1725081Sgblack@eecs.umich.edu 1735081Sgblack@eecs.umich.edu return (*entry); 1745081Sgblack@eecs.umich.edu} 1755081Sgblack@eecs.umich.edu/* 1765081Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address) 1775081Sgblack@eecs.umich.edu{ 1785081Sgblack@eecs.umich.edu assert(isPresent(address)); 1795081Sgblack@eecs.umich.edu Index index = address.memoryModuleIndex(); 1805081Sgblack@eecs.umich.edu 1815081Sgblack@eecs.umich.edu if (index < 0 || index > m_size) { 1825081Sgblack@eecs.umich.edu WARN_EXPR(address.getAddress()); 1835081Sgblack@eecs.umich.edu WARN_EXPR(index); 1845081Sgblack@eecs.umich.edu WARN_EXPR(m_size); 1855081Sgblack@eecs.umich.edu ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); 1865081Sgblack@eecs.umich.edu } 1875081Sgblack@eecs.umich.edu Directory_Entry* entry = m_entries[index]; 1885081Sgblack@eecs.umich.edu 1895081Sgblack@eecs.umich.edu // allocate the directory entry on demand. 1905081Sgblack@eecs.umich.edu if (entry == NULL) { 1915081Sgblack@eecs.umich.edu entry = new Directory_Entry; 1925081Sgblack@eecs.umich.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 1935081Sgblack@eecs.umich.edu 1945081Sgblack@eecs.umich.edu // store entry to the table 1955081Sgblack@eecs.umich.edu m_entries[index] = entry; 1965081Sgblack@eecs.umich.edu } 1975081Sgblack@eecs.umich.edu 1985081Sgblack@eecs.umich.edu return (*entry); 1995081Sgblack@eecs.umich.edu} 2005081Sgblack@eecs.umich.edu*/ 2015081Sgblack@eecs.umich.edu 2025081Sgblack@eecs.umich.eduvoid DirectoryMemory::invalidateBlock(PhysAddress address) 2035081Sgblack@eecs.umich.edu{ 2045081Sgblack@eecs.umich.edu 2055081Sgblack@eecs.umich.edu if (m_use_map) { 2065081Sgblack@eecs.umich.edu assert(m_sparseMemory->exist(address)); 2075081Sgblack@eecs.umich.edu m_sparseMemory->remove(address); 2085081Sgblack@eecs.umich.edu } 2095081Sgblack@eecs.umich.edu /* 2105081Sgblack@eecs.umich.edu else { 2115081Sgblack@eecs.umich.edu assert(isPresent(address)); 2125081Sgblack@eecs.umich.edu 2135081Sgblack@eecs.umich.edu Index index = address.memoryModuleIndex(); 2145081Sgblack@eecs.umich.edu 2155081Sgblack@eecs.umich.edu if (index < 0 || index > m_size) { 2165081Sgblack@eecs.umich.edu ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); 2175081Sgblack@eecs.umich.edu } 2185081Sgblack@eecs.umich.edu 2195081Sgblack@eecs.umich.edu if(m_entries[index] != NULL){ 2205081Sgblack@eecs.umich.edu delete m_entries[index]; 2215081Sgblack@eecs.umich.edu m_entries[index] = NULL; 2225081Sgblack@eecs.umich.edu } 2235081Sgblack@eecs.umich.edu } 2245081Sgblack@eecs.umich.edu */ 2255081Sgblack@eecs.umich.edu 2265081Sgblack@eecs.umich.edu 2275081Sgblack@eecs.umich.edu} 2285081Sgblack@eecs.umich.edu 2295081Sgblack@eecs.umich.eduvoid DirectoryMemory::print(ostream& out) const 2305081Sgblack@eecs.umich.edu{ 2315081Sgblack@eecs.umich.edu 2325081Sgblack@eecs.umich.edu} 2335081Sgblack@eecs.umich.edu 2345081Sgblack@eecs.umich.eduvoid DirectoryMemory::printStats(ostream& out) const 2355081Sgblack@eecs.umich.edu{ 2365081Sgblack@eecs.umich.edu if (m_use_map) { 2375081Sgblack@eecs.umich.edu m_sparseMemory->printStats(out); 2385081Sgblack@eecs.umich.edu } 2395081Sgblack@eecs.umich.edu} 2405081Sgblack@eecs.umich.edu 2415081Sgblack@eecs.umich.eduDirectoryMemory * 2425081Sgblack@eecs.umich.eduRubyDirectoryMemoryParams::create() 2435081Sgblack@eecs.umich.edu{ 2445081Sgblack@eecs.umich.edu return new DirectoryMemory(this); 2455081Sgblack@eecs.umich.edu} 2465081Sgblack@eecs.umich.edu