DirectoryMemory.cc revision 11903
16145SN/A/* 26145SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 311903Sleolson@google.com * Copyright (c) 2017 Google Inc. 46145SN/A * All rights reserved. 56145SN/A * 66145SN/A * Redistribution and use in source and binary forms, with or without 76145SN/A * modification, are permitted provided that the following conditions are 86145SN/A * met: redistributions of source code must retain the above copyright 96145SN/A * notice, this list of conditions and the following disclaimer; 106145SN/A * redistributions in binary form must reproduce the above copyright 116145SN/A * notice, this list of conditions and the following disclaimer in the 126145SN/A * documentation and/or other materials provided with the distribution; 136145SN/A * neither the name of the copyright holders nor the names of its 146145SN/A * contributors may be used to endorse or promote products derived from 156145SN/A * this software without specific prior written permission. 166145SN/A * 176145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811903Sleolson@google.com * 2911903Sleolson@google.com * Authors: Lena Olson 306145SN/A */ 316145SN/A 3211793Sbrandon.potter@amd.com#include "mem/ruby/structures/DirectoryMemory.hh" 3311793Sbrandon.potter@amd.com 347056SN/A#include "base/intmath.hh" 358232SN/A#include "debug/RubyCache.hh" 369104SN/A#include "debug/RubyStats.hh" 377039SN/A#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 3811108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh" 3911903Sleolson@google.com#include "sim/system.hh" 406145SN/A 417055SN/Ausing namespace std; 427055SN/A 436285SN/Aint DirectoryMemory::m_num_directories = 0; 446285SN/Aint DirectoryMemory::m_num_directories_bits = 0; 457027SN/Aint DirectoryMemory::m_numa_high_bit = 0; 466285SN/A 476876SN/ADirectoryMemory::DirectoryMemory(const Params *p) 486876SN/A : SimObject(p) 496145SN/A{ 506876SN/A m_version = p->version; 5111903Sleolson@google.com // In X86, there is an IO gap in the 3-4GB range. 5211903Sleolson@google.com if (p->system->getArch() == Arch::X86ISA && p->size > 0xc0000000){ 5311903Sleolson@google.com // We need to add 1GB to the size for the gap 5411903Sleolson@google.com m_size_bytes = p->size + 0x40000000; 5511903Sleolson@google.com } 5611903Sleolson@google.com else { 5711903Sleolson@google.com m_size_bytes = p->size; 5811903Sleolson@google.com } 597056SN/A m_size_bits = floorLog2(m_size_bytes); 607025SN/A m_num_entries = 0; 617027SN/A m_numa_high_bit = p->numa_high_bit; 626285SN/A} 636285SN/A 647039SN/Avoid 657039SN/ADirectoryMemory::init() 666285SN/A{ 677039SN/A m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); 6810520Snilay@cs.wisc.edu m_entries = new AbstractEntry*[m_num_entries]; 6910520Snilay@cs.wisc.edu for (int i = 0; i < m_num_entries; i++) 7010520Snilay@cs.wisc.edu m_entries[i] = NULL; 716285SN/A 727039SN/A m_num_directories++; 7310004SN/A m_num_directories_bits = ceilLog2(m_num_directories); 747027SN/A 757039SN/A if (m_numa_high_bit == 0) { 767563SN/A m_numa_high_bit = RubySystem::getMemorySizeBits() - 1; 777039SN/A } 787039SN/A assert(m_numa_high_bit != 0); 796145SN/A} 806145SN/A 816145SN/ADirectoryMemory::~DirectoryMemory() 826145SN/A{ 837039SN/A // free up all the directory entries 8411025Snilay@cs.wisc.edu for (uint64_t i = 0; i < m_num_entries; i++) { 8510520Snilay@cs.wisc.edu if (m_entries[i] != NULL) { 8610520Snilay@cs.wisc.edu delete m_entries[i]; 877039SN/A } 887039SN/A } 8910520Snilay@cs.wisc.edu delete [] m_entries; 906285SN/A} 916145SN/A 9211025Snilay@cs.wisc.eduuint64_t 9311025Snilay@cs.wisc.eduDirectoryMemory::mapAddressToDirectoryVersion(Addr address) 946285SN/A{ 957039SN/A if (m_num_directories_bits == 0) 967039SN/A return 0; 977039SN/A 9811025Snilay@cs.wisc.edu uint64_t ret = bitSelect(address, 9911025Snilay@cs.wisc.edu m_numa_high_bit - m_num_directories_bits + 1, 10011025Snilay@cs.wisc.edu m_numa_high_bit); 1017039SN/A return ret; 1026145SN/A} 1036145SN/A 1047039SN/Abool 10511025Snilay@cs.wisc.eduDirectoryMemory::isPresent(Addr address) 1066145SN/A{ 1077039SN/A bool ret = (mapAddressToDirectoryVersion(address) == m_version); 1087039SN/A return ret; 1096145SN/A} 1106145SN/A 11111025Snilay@cs.wisc.eduuint64_t 11211025Snilay@cs.wisc.eduDirectoryMemory::mapAddressToLocalIdx(Addr address) 1136161SN/A{ 11411025Snilay@cs.wisc.edu uint64_t ret; 1157563SN/A if (m_num_directories_bits > 0) { 11611025Snilay@cs.wisc.edu ret = bitRemove(address, m_numa_high_bit - m_num_directories_bits + 1, 11711025Snilay@cs.wisc.edu m_numa_high_bit); 1187563SN/A } else { 11911025Snilay@cs.wisc.edu ret = address; 1207563SN/A } 1217563SN/A 1227563SN/A return ret >> (RubySystem::getBlockSizeBits()); 1236161SN/A} 1246161SN/A 1258644SN/AAbstractEntry* 12611025Snilay@cs.wisc.eduDirectoryMemory::lookup(Addr address) 1276145SN/A{ 1287039SN/A assert(isPresent(address)); 12911118Snilay@cs.wisc.edu DPRINTF(RubyCache, "Looking up address: %#x\n", address); 1308644SN/A 13110520Snilay@cs.wisc.edu uint64_t idx = mapAddressToLocalIdx(address); 13210520Snilay@cs.wisc.edu assert(idx < m_num_entries); 13310520Snilay@cs.wisc.edu return m_entries[idx]; 1348644SN/A} 1358644SN/A 1368644SN/AAbstractEntry* 13711025Snilay@cs.wisc.eduDirectoryMemory::allocate(Addr address, AbstractEntry *entry) 1388644SN/A{ 1398644SN/A assert(isPresent(address)); 14011025Snilay@cs.wisc.edu uint64_t idx; 14111118Snilay@cs.wisc.edu DPRINTF(RubyCache, "Looking up address: %#x\n", address); 1427025SN/A 14310520Snilay@cs.wisc.edu idx = mapAddressToLocalIdx(address); 14410520Snilay@cs.wisc.edu assert(idx < m_num_entries); 14510520Snilay@cs.wisc.edu entry->changePermission(AccessPermission_Read_Only); 14610520Snilay@cs.wisc.edu m_entries[idx] = entry; 1476145SN/A 1488644SN/A return entry; 1496145SN/A} 1506145SN/A 1517039SN/Avoid 1527039SN/ADirectoryMemory::print(ostream& out) const 1537039SN/A{ 1547039SN/A} 1557039SN/A 1567039SN/Avoid 1579104SN/ADirectoryMemory::recordRequestType(DirectoryRequestType requestType) { 1589104SN/A DPRINTF(RubyStats, "Recorded statistic: %s\n", 1599104SN/A DirectoryRequestType_to_string(requestType)); 1609104SN/A} 1619104SN/A 1626876SN/ADirectoryMemory * 1636876SN/ARubyDirectoryMemoryParams::create() 1646876SN/A{ 1656876SN/A return new DirectoryMemory(this); 1666876SN/A} 167