DirectoryMemory.cc revision 10520
16145SN/A/* 26145SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 36145SN/A * All rights reserved. 46145SN/A * 56145SN/A * Redistribution and use in source and binary forms, with or without 66145SN/A * modification, are permitted provided that the following conditions are 76145SN/A * met: redistributions of source code must retain the above copyright 86145SN/A * notice, this list of conditions and the following disclaimer; 96145SN/A * redistributions in binary form must reproduce the above copyright 106145SN/A * notice, this list of conditions and the following disclaimer in the 116145SN/A * documentation and/or other materials provided with the distribution; 126145SN/A * neither the name of the copyright holders nor the names of its 136145SN/A * contributors may be used to endorse or promote products derived from 146145SN/A * this software without specific prior written permission. 156145SN/A * 166145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145SN/A */ 286145SN/A 297056SN/A#include "base/intmath.hh" 308232SN/A#include "debug/RubyCache.hh" 319104SN/A#include "debug/RubyStats.hh" 327039SN/A#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 3310301Snilay@cs.wisc.edu#include "mem/ruby/structures/DirectoryMemory.hh" 346154SN/A#include "mem/ruby/system/System.hh" 356145SN/A 367055SN/Ausing namespace std; 377055SN/A 386285SN/Aint DirectoryMemory::m_num_directories = 0; 396285SN/Aint DirectoryMemory::m_num_directories_bits = 0; 406861SN/Auint64_t DirectoryMemory::m_total_size_bytes = 0; 417027SN/Aint DirectoryMemory::m_numa_high_bit = 0; 426285SN/A 436876SN/ADirectoryMemory::DirectoryMemory(const Params *p) 446876SN/A : SimObject(p) 456145SN/A{ 466876SN/A m_version = p->version; 476903SN/A m_size_bytes = p->size; 487056SN/A m_size_bits = floorLog2(m_size_bytes); 497025SN/A m_num_entries = 0; 507027SN/A m_numa_high_bit = p->numa_high_bit; 516285SN/A} 526285SN/A 537039SN/Avoid 547039SN/ADirectoryMemory::init() 556285SN/A{ 567039SN/A m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); 5710520Snilay@cs.wisc.edu m_entries = new AbstractEntry*[m_num_entries]; 5810520Snilay@cs.wisc.edu for (int i = 0; i < m_num_entries; i++) 5910520Snilay@cs.wisc.edu m_entries[i] = NULL; 6010520Snilay@cs.wisc.edu m_ram = g_system_ptr->getMemoryVector(); 616285SN/A 627039SN/A m_num_directories++; 6310004SN/A m_num_directories_bits = ceilLog2(m_num_directories); 647039SN/A m_total_size_bytes += m_size_bytes; 657027SN/A 667039SN/A if (m_numa_high_bit == 0) { 677563SN/A m_numa_high_bit = RubySystem::getMemorySizeBits() - 1; 687039SN/A } 697039SN/A assert(m_numa_high_bit != 0); 706145SN/A} 716145SN/A 726145SN/ADirectoryMemory::~DirectoryMemory() 736145SN/A{ 747039SN/A // free up all the directory entries 7510520Snilay@cs.wisc.edu for (uint64 i = 0; i < m_num_entries; i++) { 7610520Snilay@cs.wisc.edu if (m_entries[i] != NULL) { 7710520Snilay@cs.wisc.edu delete m_entries[i]; 787039SN/A } 797039SN/A } 8010520Snilay@cs.wisc.edu delete [] m_entries; 816285SN/A} 826145SN/A 837039SN/Auint64 847039SN/ADirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) 856285SN/A{ 867039SN/A if (m_num_directories_bits == 0) 877039SN/A return 0; 887039SN/A 897563SN/A uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits + 1, 907039SN/A m_numa_high_bit); 917039SN/A return ret; 926145SN/A} 936145SN/A 947039SN/Abool 957039SN/ADirectoryMemory::isPresent(PhysAddress address) 966145SN/A{ 977039SN/A bool ret = (mapAddressToDirectoryVersion(address) == m_version); 987039SN/A return ret; 996145SN/A} 1006145SN/A 1017039SN/Auint64 1027039SN/ADirectoryMemory::mapAddressToLocalIdx(PhysAddress address) 1036161SN/A{ 1047563SN/A uint64 ret; 1057563SN/A if (m_num_directories_bits > 0) { 1067563SN/A ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits + 1, 1077563SN/A m_numa_high_bit); 1087563SN/A } else { 1097563SN/A ret = address.getAddress(); 1107563SN/A } 1117563SN/A 1127563SN/A return ret >> (RubySystem::getBlockSizeBits()); 1136161SN/A} 1146161SN/A 1158644SN/AAbstractEntry* 1167039SN/ADirectoryMemory::lookup(PhysAddress address) 1176145SN/A{ 1187039SN/A assert(isPresent(address)); 1198644SN/A DPRINTF(RubyCache, "Looking up address: %s\n", address); 1208644SN/A 12110520Snilay@cs.wisc.edu uint64_t idx = mapAddressToLocalIdx(address); 12210520Snilay@cs.wisc.edu assert(idx < m_num_entries); 12310520Snilay@cs.wisc.edu return m_entries[idx]; 1248644SN/A} 1258644SN/A 1268644SN/AAbstractEntry* 1278644SN/ADirectoryMemory::allocate(const PhysAddress& address, AbstractEntry* entry) 1288644SN/A{ 1298644SN/A assert(isPresent(address)); 1307039SN/A uint64 idx; 1318436SN/A DPRINTF(RubyCache, "Looking up address: %s\n", address); 1327025SN/A 13310520Snilay@cs.wisc.edu idx = mapAddressToLocalIdx(address); 13410520Snilay@cs.wisc.edu assert(idx < m_num_entries); 13510520Snilay@cs.wisc.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 13610520Snilay@cs.wisc.edu entry->changePermission(AccessPermission_Read_Only); 13710520Snilay@cs.wisc.edu m_entries[idx] = entry; 1386145SN/A 1398644SN/A return entry; 1406145SN/A} 1416145SN/A 1427039SN/Avoid 1437039SN/ADirectoryMemory::print(ostream& out) const 1447039SN/A{ 1457039SN/A} 1467039SN/A 1477039SN/Avoid 1489104SN/ADirectoryMemory::recordRequestType(DirectoryRequestType requestType) { 1499104SN/A DPRINTF(RubyStats, "Recorded statistic: %s\n", 1509104SN/A DirectoryRequestType_to_string(requestType)); 1519104SN/A} 1529104SN/A 1536876SN/ADirectoryMemory * 1546876SN/ARubyDirectoryMemoryParams::create() 1556876SN/A{ 1566876SN/A return new DirectoryMemory(this); 1576876SN/A} 158