DirectoryMemory.cc revision 6876
15443Sgblack@eecs.umich.edu 25443Sgblack@eecs.umich.edu/* 35443Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 45443Sgblack@eecs.umich.edu * All rights reserved. 55443Sgblack@eecs.umich.edu * 65443Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 75443Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 85443Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 95443Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 105443Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 115443Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 125443Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 135443Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 145443Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 155443Sgblack@eecs.umich.edu * this software without specific prior written permission. 165443Sgblack@eecs.umich.edu * 175443Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185443Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195443Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205443Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215443Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225443Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235443Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245443Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255443Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265443Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275443Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285443Sgblack@eecs.umich.edu */ 295443Sgblack@eecs.umich.edu 305443Sgblack@eecs.umich.edu/* 315443Sgblack@eecs.umich.edu * DirectoryMemory.cc 325443Sgblack@eecs.umich.edu * 3311793Sbrandon.potter@amd.com * Description: See DirectoryMemory.hh 3411793Sbrandon.potter@amd.com * 3512334Sgabeblack@google.com * $Id$ 368232Snate@binkert.org * 375443Sgblack@eecs.umich.edu */ 385443Sgblack@eecs.umich.edu 395443Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 405635Sgblack@eecs.umich.edu#include "mem/ruby/system/DirectoryMemory.hh" 415635Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 425635Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/AbstractController.hh" 435443Sgblack@eecs.umich.edu#include "mem/gems_common/util.hh" 445635Sgblack@eecs.umich.edu 455635Sgblack@eecs.umich.eduint DirectoryMemory::m_num_directories = 0; 465635Sgblack@eecs.umich.eduint DirectoryMemory::m_num_directories_bits = 0; 475635Sgblack@eecs.umich.eduuint64_t DirectoryMemory::m_total_size_bytes = 0; 485635Sgblack@eecs.umich.edu 495635Sgblack@eecs.umich.eduDirectoryMemory::DirectoryMemory(const Params *p) 505635Sgblack@eecs.umich.edu : SimObject(p) 515635Sgblack@eecs.umich.edu{ 525642Sgblack@eecs.umich.edu m_version = p->version; 535642Sgblack@eecs.umich.edu m_size_bytes = p->size_mb * static_cast<uint64>(1<<20); 545642Sgblack@eecs.umich.edu m_size_bits = log_int(m_size_bytes); 555443Sgblack@eecs.umich.edu m_controller = p->controller; 565443Sgblack@eecs.umich.edu} 575443Sgblack@eecs.umich.edu 585443Sgblack@eecs.umich.eduvoid DirectoryMemory::init() 595443Sgblack@eecs.umich.edu{ 605443Sgblack@eecs.umich.edu m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes(); 615443Sgblack@eecs.umich.edu m_entries = new Directory_Entry*[m_num_entries]; 625443Sgblack@eecs.umich.edu for (int i=0; i < m_num_entries; i++) 635443Sgblack@eecs.umich.edu m_entries[i] = NULL; 645443Sgblack@eecs.umich.edu 655443Sgblack@eecs.umich.edu m_ram = g_system_ptr->getMemoryVector(); 665443Sgblack@eecs.umich.edu 675443Sgblack@eecs.umich.edu m_num_directories++; 685443Sgblack@eecs.umich.edu m_num_directories_bits = log_int(m_num_directories); 695443Sgblack@eecs.umich.edu m_total_size_bytes += m_size_bytes; 705443Sgblack@eecs.umich.edu} 715443Sgblack@eecs.umich.edu 725443Sgblack@eecs.umich.eduDirectoryMemory::~DirectoryMemory() 735443Sgblack@eecs.umich.edu{ 745443Sgblack@eecs.umich.edu // free up all the directory entries 7510905Sandreas.sandberg@arm.com for (uint64 i=0;i<m_num_entries;i++) { 765443Sgblack@eecs.umich.edu if (m_entries[i] != NULL) { 775443Sgblack@eecs.umich.edu delete m_entries[i]; 7810905Sandreas.sandberg@arm.com } 7910905Sandreas.sandberg@arm.com } 8010905Sandreas.sandberg@arm.com if (m_entries != NULL) { 815443Sgblack@eecs.umich.edu delete [] m_entries; 825443Sgblack@eecs.umich.edu } 835443Sgblack@eecs.umich.edu} 8410905Sandreas.sandberg@arm.com 855443Sgblack@eecs.umich.eduvoid DirectoryMemory::printConfig(ostream& out) const 865443Sgblack@eecs.umich.edu{ 8710905Sandreas.sandberg@arm.com out << "DirectoryMemory module config: " << m_name << endl; 8810905Sandreas.sandberg@arm.com out << " controller: " << m_controller->getName() << endl; 8910905Sandreas.sandberg@arm.com out << " version: " << m_version << endl; 905443Sgblack@eecs.umich.edu out << " memory_bits: " << m_size_bits << endl; 915443Sgblack@eecs.umich.edu out << " memory_size_bytes: " << m_size_bytes << endl; 9210642Scdirik@micron.com out << " memory_size_Kbytes: " << double(m_size_bytes) / (1<<10) << endl; 9310642Scdirik@micron.com out << " memory_size_Mbytes: " << double(m_size_bytes) / (1<<20) << endl; 9410642Scdirik@micron.com out << " memory_size_Gbytes: " << double(m_size_bytes) / (1<<30) << endl; 9510642Scdirik@micron.com} 9610642Scdirik@micron.com 9710642Scdirik@micron.com// Static method 9810642Scdirik@micron.comvoid DirectoryMemory::printGlobalConfig(ostream & out) 9910642Scdirik@micron.com{ 1005642Sgblack@eecs.umich.edu out << "DirectoryMemory Global Config: " << endl; 1015642Sgblack@eecs.umich.edu out << " number of directory memories: " << m_num_directories << endl; 10210642Scdirik@micron.com if (m_num_directories > 1) { 10310642Scdirik@micron.com out << " number of selection bits: " << m_num_directories_bits << endl; 10410642Scdirik@micron.com out << " selection bits: " << RubySystem::getBlockSizeBits()+m_num_directories_bits-1 10510642Scdirik@micron.com << "-" << RubySystem::getBlockSizeBits() << endl; 1065443Sgblack@eecs.umich.edu } 10710642Scdirik@micron.com out << " total memory size bytes: " << m_total_size_bytes << endl; 1085443Sgblack@eecs.umich.edu out << " total memory size bits: " << log_int(m_total_size_bytes) << endl; 1095443Sgblack@eecs.umich.edu 1105443Sgblack@eecs.umich.edu} 1115443Sgblack@eecs.umich.edu 1125443Sgblack@eecs.umich.eduint DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address) 1135443Sgblack@eecs.umich.edu{ 11411321Ssteve.reinhardt@amd.com if (m_num_directories_bits == 0) return 0; 1155443Sgblack@eecs.umich.edu int ret = address.bitSelect(RubySystem::getBlockSizeBits(), 1165443Sgblack@eecs.umich.edu RubySystem::getBlockSizeBits()+m_num_directories_bits-1); 1176067Sgblack@eecs.umich.edu return ret; 1185443Sgblack@eecs.umich.edu} 1195443Sgblack@eecs.umich.edu 1205443Sgblack@eecs.umich.edu// Public method 1216067Sgblack@eecs.umich.edubool DirectoryMemory::isPresent(PhysAddress address) 1226067Sgblack@eecs.umich.edu{ 1236067Sgblack@eecs.umich.edu bool ret = (mapAddressToDirectoryVersion(address) == m_version); 1246067Sgblack@eecs.umich.edu return ret; 1256067Sgblack@eecs.umich.edu} 1266067Sgblack@eecs.umich.edu 1276067Sgblack@eecs.umich.eduint DirectoryMemory::mapAddressToLocalIdx(PhysAddress address) 1286067Sgblack@eecs.umich.edu{ 1296067Sgblack@eecs.umich.edu int ret = address.getAddress() >> (RubySystem::getBlockSizeBits() + m_num_directories_bits); 1306067Sgblack@eecs.umich.edu return ret; 1316067Sgblack@eecs.umich.edu} 1326067Sgblack@eecs.umich.edu 1336067Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address) 1346067Sgblack@eecs.umich.edu{ 1355443Sgblack@eecs.umich.edu assert(isPresent(address)); 1365443Sgblack@eecs.umich.edu Directory_Entry* entry; 1375443Sgblack@eecs.umich.edu int idx = mapAddressToLocalIdx(address); 1385443Sgblack@eecs.umich.edu entry = m_entries[idx]; 1395443Sgblack@eecs.umich.edu if (entry == NULL) { 1405443Sgblack@eecs.umich.edu entry = new Directory_Entry; 1415443Sgblack@eecs.umich.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 1425443Sgblack@eecs.umich.edu m_entries[idx] = entry; 1435443Sgblack@eecs.umich.edu } 1445443Sgblack@eecs.umich.edu return (*entry); 1455443Sgblack@eecs.umich.edu} 1465443Sgblack@eecs.umich.edu/* 1475443Sgblack@eecs.umich.eduDirectory_Entry& DirectoryMemory::lookup(PhysAddress address) 1485443Sgblack@eecs.umich.edu{ 1495443Sgblack@eecs.umich.edu assert(isPresent(address)); 1505443Sgblack@eecs.umich.edu Index index = address.memoryModuleIndex(); 1515443Sgblack@eecs.umich.edu 1525443Sgblack@eecs.umich.edu if (index < 0 || index > m_size) { 1536067Sgblack@eecs.umich.edu WARN_EXPR(address.getAddress()); 1545443Sgblack@eecs.umich.edu WARN_EXPR(index); 1555443Sgblack@eecs.umich.edu WARN_EXPR(m_size); 1565443Sgblack@eecs.umich.edu ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); 1575443Sgblack@eecs.umich.edu } 1585443Sgblack@eecs.umich.edu Directory_Entry* entry = m_entries[index]; 1595443Sgblack@eecs.umich.edu 1605443Sgblack@eecs.umich.edu // allocate the directory entry on demand. 1615443Sgblack@eecs.umich.edu if (entry == NULL) { 1625443Sgblack@eecs.umich.edu entry = new Directory_Entry; 1635443Sgblack@eecs.umich.edu entry->getDataBlk().assign(m_ram->getBlockPtr(address)); 1645443Sgblack@eecs.umich.edu 1655443Sgblack@eecs.umich.edu // store entry to the table 1665443Sgblack@eecs.umich.edu m_entries[index] = entry; 1675443Sgblack@eecs.umich.edu } 1685443Sgblack@eecs.umich.edu 1695443Sgblack@eecs.umich.edu return (*entry); 1705443Sgblack@eecs.umich.edu} 1715443Sgblack@eecs.umich.edu*/ 1725443Sgblack@eecs.umich.edu 1735443Sgblack@eecs.umich.eduvoid DirectoryMemory::invalidateBlock(PhysAddress address) 1746067Sgblack@eecs.umich.edu{ 1755443Sgblack@eecs.umich.edu /* 1765443Sgblack@eecs.umich.edu assert(isPresent(address)); 1775606Snate@binkert.org 1785443Sgblack@eecs.umich.edu Index index = address.memoryModuleIndex(); 1795443Sgblack@eecs.umich.edu 1805443Sgblack@eecs.umich.edu if (index < 0 || index > m_size) { 1815443Sgblack@eecs.umich.edu ERROR_MSG("Directory Memory Assertion: accessing memory out of range."); 1825443Sgblack@eecs.umich.edu } 1836067Sgblack@eecs.umich.edu 1845444Sgblack@eecs.umich.edu if(m_entries[index] != NULL){ 1855444Sgblack@eecs.umich.edu delete m_entries[index]; 1865444Sgblack@eecs.umich.edu m_entries[index] = NULL; 1876067Sgblack@eecs.umich.edu } 1885444Sgblack@eecs.umich.edu */ 1896067Sgblack@eecs.umich.edu} 1905443Sgblack@eecs.umich.edu 19110642Scdirik@micron.comvoid DirectoryMemory::print(ostream& out) const 19210642Scdirik@micron.com{ 19310642Scdirik@micron.com 1945444Sgblack@eecs.umich.edu} 1955444Sgblack@eecs.umich.edu 1965443Sgblack@eecs.umich.eduDirectoryMemory * 1975443Sgblack@eecs.umich.eduRubyDirectoryMemoryParams::create() 1985443Sgblack@eecs.umich.edu{ 1995443Sgblack@eecs.umich.edu return new DirectoryMemory(this); 2005443Sgblack@eecs.umich.edu} 2015443Sgblack@eecs.umich.edu