DirectoryMemory.cc revision 8232
12689Sktlim@umich.edu/* 22689Sktlim@umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 32689Sktlim@umich.edu * All rights reserved. 42689Sktlim@umich.edu * 52689Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 62689Sktlim@umich.edu * modification, are permitted provided that the following conditions are 72689Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 82689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 92689Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 102689Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 112689Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 122689Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 132689Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 142689Sktlim@umich.edu * this software without specific prior written permission. 152689Sktlim@umich.edu * 162689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172689Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182689Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192689Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202689Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212689Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222689Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232689Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242689Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252689Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262689Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272689Sktlim@umich.edu */ 282689Sktlim@umich.edu 292689Sktlim@umich.edu#include "base/intmath.hh" 302689Sktlim@umich.edu#include "debug/RubyCache.hh" 312689Sktlim@umich.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 322689Sktlim@umich.edu#include "mem/ruby/system/DirectoryMemory.hh" 332689Sktlim@umich.edu#include "mem/ruby/system/System.hh" 342521SN/A 353960Sgblack@eecs.umich.eduusing namespace std; 364194Ssaidi@eecs.umich.edu 371070SN/Aint DirectoryMemory::m_num_directories = 0; 381070SN/Aint DirectoryMemory::m_num_directories_bits = 0; 392521SN/Auint64_t DirectoryMemory::m_total_size_bytes = 0; 402680Sktlim@umich.eduint DirectoryMemory::m_numa_high_bit = 0; 412521SN/A 422522SN/ADirectoryMemory::DirectoryMemory(const Params *p) 432037SN/A : SimObject(p) 4456SN/A{ 455512SMichael.Adler@intel.com m_version = p->version; 462378SN/A m_size_bytes = p->size; 472521SN/A m_size_bits = floorLog2(m_size_bytes); 482378SN/A m_num_entries = 0; 494762Snate@binkert.org m_use_map = p->use_map; 504762Snate@binkert.org m_map_levels = p->map_levels; 512378SN/A m_numa_high_bit = p->numa_high_bit; 522SN/A} 532SN/A 542107SN/Avoid 552SN/ADirectoryMemory::init() 562SN/A{ 572SN/A m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); 582SN/A 592SN/A if (m_use_map) { 601070SN/A m_sparseMemory = new SparseMemory(m_map_levels); 615034Smilesck@eecs.umich.edu } else { 622378SN/A m_entries = new Directory_Entry*[m_num_entries]; 632521SN/A for (int i = 0; i < m_num_entries; i++) 642640Sstever@eecs.umich.edu m_entries[i] = NULL; 652640Sstever@eecs.umich.edu m_ram = g_system_ptr->getMemoryVector(); 662378SN/A } 672378SN/A 684997Sgblack@eecs.umich.edu m_num_directories++; 692378SN/A m_num_directories_bits = floorLog2(m_num_directories); 702902Ssaidi@eecs.umich.edu m_total_size_bytes += m_size_bytes; 712SN/A 721070SN/A if (m_numa_high_bit == 0) { 731070SN/A m_numa_high_bit = RubySystem::getMemorySizeBits() - 1; 741070SN/A } 752378SN/A assert(m_numa_high_bit != 0); 761070SN/A} 774838Ssaidi@eecs.umich.edu 784838Ssaidi@eecs.umich.eduDirectoryMemory::~DirectoryMemory() 791070SN/A{ 802520SN/A // free up all the directory entries 812520SN/A if (m_entries != NULL) { 822520SN/A for (uint64 i = 0; i < m_num_entries; i++) { 832520SN/A if (m_entries[i] != NULL) { 842520SN/A delete m_entries[i]; 852520SN/A } 862520SN/A } 872520SN/A delete [] m_entries; 882520SN/A } else if (m_use_map) { 892521SN/A delete m_sparseMemory; 902521SN/A } 912521SN/A} 922521SN/A 932520SN/Avoid 941070SN/ADirectoryMemory::printConfig(ostream& out) const 952158SN/A{ 961070SN/A out << "DirectoryMemory module config: " << m_name << endl 974762Snate@binkert.org << " version: " << m_version << endl 983812Ssaidi@eecs.umich.edu << " memory_bits: " << m_size_bits << endl 993812Ssaidi@eecs.umich.edu << " memory_size_bytes: " << m_size_bytes << endl 1003812Ssaidi@eecs.umich.edu << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl 1013812Ssaidi@eecs.umich.edu << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl 1024762Snate@binkert.org << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl; 1035222Sksewell@umich.edu} 1045222Sksewell@umich.edu 1053812Ssaidi@eecs.umich.edu// Static method 1064762Snate@binkert.orgvoid 1071070SN/ADirectoryMemory::printGlobalConfig(ostream & out) 1083812Ssaidi@eecs.umich.edu{ 1093812Ssaidi@eecs.umich.edu out << "DirectoryMemory Global Config: " << endl; 1101070SN/A out << " number of directory memories: " << m_num_directories << endl; 1113812Ssaidi@eecs.umich.edu if (m_num_directories > 1) { 1123812Ssaidi@eecs.umich.edu out << " number of selection bits: " << m_num_directories_bits << endl 1133812Ssaidi@eecs.umich.edu << " selection bits: " << m_numa_high_bit 1143812Ssaidi@eecs.umich.edu << "-" << m_numa_high_bit-m_num_directories_bits 1151070SN/A << endl; 1163812Ssaidi@eecs.umich.edu } 1173812Ssaidi@eecs.umich.edu out << " total memory size bytes: " << m_total_size_bytes << endl; 1183812Ssaidi@eecs.umich.edu out << " total memory bits: " << floorLog2(m_total_size_bytes) << endl; 1191070SN/A} 1203812Ssaidi@eecs.umich.edu 1213812Ssaidi@eecs.umich.eduuint64 1221070SN/ADirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) 1233812Ssaidi@eecs.umich.edu{ 1243812Ssaidi@eecs.umich.edu if (m_num_directories_bits == 0) 1251074SN/A return 0; 1263812Ssaidi@eecs.umich.edu 1273812Ssaidi@eecs.umich.edu uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits + 1, 1281074SN/A m_numa_high_bit); 1293812Ssaidi@eecs.umich.edu return ret; 1303812Ssaidi@eecs.umich.edu} 1313812Ssaidi@eecs.umich.edu 1323812Ssaidi@eecs.umich.edubool 1333812Ssaidi@eecs.umich.eduDirectoryMemory::isPresent(PhysAddress address) 1342378SN/A{ 1352378SN/A bool ret = (mapAddressToDirectoryVersion(address) == m_version); 1361070SN/A return ret; 137878SN/A} 1382SN/A 1392SN/Auint64 1402SN/ADirectoryMemory::mapAddressToLocalIdx(PhysAddress address) 1412SN/A{ 1422378SN/A uint64 ret; 1431070SN/A if (m_num_directories_bits > 0) { 1441070SN/A ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits + 1, 1452378SN/A m_numa_high_bit); 1462378SN/A } else { 1472378SN/A ret = address.getAddress(); 1482378SN/A } 1492SN/A 1502SN/A return ret >> (RubySystem::getBlockSizeBits()); 1511808SN/A} 1524095Sbinkertn@umich.edu 1531808SN/ADirectory_Entry& 1542901Ssaidi@eecs.umich.eduDirectoryMemory::lookup(PhysAddress address) 1554762Snate@binkert.org{ 1562901Ssaidi@eecs.umich.edu assert(isPresent(address)); 1572901Ssaidi@eecs.umich.edu Directory_Entry* entry; 1582901Ssaidi@eecs.umich.edu uint64 idx; 1592901Ssaidi@eecs.umich.edu DPRINTF(RubyCache, "address: %s\n", address); 1602901Ssaidi@eecs.umich.edu 1613960Sgblack@eecs.umich.edu if (m_use_map) { 1623960Sgblack@eecs.umich.edu if (m_sparseMemory->exist(address)) { 1634095Sbinkertn@umich.edu entry = m_sparseMemory->lookup(address); 1644095Sbinkertn@umich.edu assert(entry != NULL); 1654095Sbinkertn@umich.edu } else { 1663960Sgblack@eecs.umich.edu // Note: SparseMemory internally creates a new Directory Entry 1673960Sgblack@eecs.umich.edu m_sparseMemory->add(address); 168180SN/A entry = m_sparseMemory->lookup(address); 1695712Shsul@eecs.umich.edu } 1702SN/A } else { 1715712Shsul@eecs.umich.edu idx = mapAddressToLocalIdx(address); 1725712Shsul@eecs.umich.edu assert(idx < m_num_entries); 1735712Shsul@eecs.umich.edu entry = m_entries[idx]; 1745712Shsul@eecs.umich.edu 1751806SN/A if (entry == NULL) { 1761806SN/A entry = new Directory_Entry(); 1772680Sktlim@umich.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 1782680Sktlim@umich.edu m_entries[idx] = entry; 1791806SN/A } 1802680Sktlim@umich.edu } 1811806SN/A 1821806SN/A return *entry; 1832680Sktlim@umich.edu} 1841806SN/A 1851070SN/A#if 0 1865512SMichael.Adler@intel.comDirectory_Entry& 1875512SMichael.Adler@intel.comDirectoryMemory::lookup(PhysAddress address) 1884095Sbinkertn@umich.edu{ 1895512SMichael.Adler@intel.com assert(isPresent(address)); 1904095Sbinkertn@umich.edu Index index = address.memoryModuleIndex(); 1914095Sbinkertn@umich.edu 1924095Sbinkertn@umich.edu if (index < 0 || index > m_size) { 1934095Sbinkertn@umich.edu WARN_EXPR(address.getAddress()); 1944095Sbinkertn@umich.edu WARN_EXPR(index); 1954095Sbinkertn@umich.edu WARN_EXPR(m_size); 1964095Sbinkertn@umich.edu ERROR_MSG("Directory Memory Assertion: accessing memory out of range"); 1971070SN/A } 1984095Sbinkertn@umich.edu Directory_Entry* entry = m_entries[index]; 1994095Sbinkertn@umich.edu 2004095Sbinkertn@umich.edu // allocate the directory entry on demand. 2014095Sbinkertn@umich.edu if (entry == NULL) { 2024095Sbinkertn@umich.edu entry = new Directory_Entry; 2031070SN/A entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 2041070SN/A 2051806SN/A // store entry to the table 206180SN/A m_entries[index] = entry; 20775SN/A } 208180SN/A 2091129SN/A return *entry; 2101129SN/A} 2115713Shsul@eecs.umich.edu#endif 2122114SN/A 2132680Sktlim@umich.eduvoid 2144194Ssaidi@eecs.umich.eduDirectoryMemory::invalidateBlock(PhysAddress address) 2155713Shsul@eecs.umich.edu{ 2161129SN/A if (m_use_map) { 2171129SN/A assert(m_sparseMemory->exist(address)); 2181129SN/A m_sparseMemory->remove(address); 2195713Shsul@eecs.umich.edu } 220180SN/A#if 0 2215713Shsul@eecs.umich.edu else { 2222680Sktlim@umich.edu assert(isPresent(address)); 2235713Shsul@eecs.umich.edu 224180SN/A Index index = address.memoryModuleIndex(); 225180SN/A 2265713Shsul@eecs.umich.edu if (index < 0 || index > m_size) { 2275713Shsul@eecs.umich.edu ERROR_MSG("Directory Memory Assertion: " 2285713Shsul@eecs.umich.edu "accessing memory out of range."); 2292SN/A } 2302SN/A 2312378SN/A if (m_entries[index] != NULL){ 2322378SN/A delete m_entries[index]; 2332378SN/A m_entries[index] = NULL; 2342378SN/A } 2352378SN/A } 2362378SN/A#endif 2373162Ssaidi@eecs.umich.edu} 2383162Ssaidi@eecs.umich.edu 2392378SN/Avoid 2402378SN/ADirectoryMemory::print(ostream& out) const 2412378SN/A{ 2422378SN/A} 2431070SN/A 2441070SN/Avoid 2451070SN/ADirectoryMemory::printStats(ostream& out) const 2462378SN/A{ 2471984SN/A if (m_use_map) { 2485183Ssaidi@eecs.umich.edu m_sparseMemory->printStats(out); 2495183Ssaidi@eecs.umich.edu } 2505183Ssaidi@eecs.umich.edu} 2511070SN/A 2521070SN/ADirectoryMemory * 2531070SN/ARubyDirectoryMemoryParams::create() 2541070SN/A{ 2551070SN/A return new DirectoryMemory(this); 2561070SN/A} 2572378SN/A