CacheMemory.cc revision 7056
112837Sgabeblack@google.com/* 212837Sgabeblack@google.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 312837Sgabeblack@google.com * All rights reserved. 412837Sgabeblack@google.com * 512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412837Sgabeblack@google.com * this software without specific prior written permission. 1512837Sgabeblack@google.com * 1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712837Sgabeblack@google.com */ 2812837Sgabeblack@google.com 2912837Sgabeblack@google.com#include "base/intmath.hh" 3012901Sgabeblack@google.com#include "mem/ruby/system/CacheMemory.hh" 3113135Sgabeblack@google.com 3212901Sgabeblack@google.comusing namespace std; 3312901Sgabeblack@google.com 3412837Sgabeblack@google.comostream& 3513280Sgabeblack@google.comoperator<<(ostream& out, const CacheMemory& obj) 3612982Sgabeblack@google.com{ 3712951Sgabeblack@google.com obj.print(out); 3813280Sgabeblack@google.com out << flush; 3913288Sgabeblack@google.com return out; 4012953Sgabeblack@google.com} 4113260Sgabeblack@google.com 4213288Sgabeblack@google.comCacheMemory * 4313288Sgabeblack@google.comRubyCacheParams::create() 4413288Sgabeblack@google.com{ 4513155Sgabeblack@google.com return new CacheMemory(this); 4612837Sgabeblack@google.com} 4712951Sgabeblack@google.com 4813155Sgabeblack@google.comCacheMemory::CacheMemory(const Params *p) 4913135Sgabeblack@google.com : SimObject(p) 5012837Sgabeblack@google.com{ 5112952Sgabeblack@google.com m_cache_size = p->size; 5212952Sgabeblack@google.com m_latency = p->latency; 5312952Sgabeblack@google.com m_cache_assoc = p->assoc; 5412952Sgabeblack@google.com m_policy = p->replacement_policy; 5512952Sgabeblack@google.com m_profiler_ptr = new CacheProfiler(name()); 5612952Sgabeblack@google.com} 5713135Sgabeblack@google.com 5813135Sgabeblack@google.comvoid 5913135Sgabeblack@google.comCacheMemory::init() 6013135Sgabeblack@google.com{ 6113135Sgabeblack@google.com m_cache_num_sets = (m_cache_size / m_cache_assoc) / 6213135Sgabeblack@google.com RubySystem::getBlockSizeBytes(); 6313135Sgabeblack@google.com assert(m_cache_num_sets > 1); 6413135Sgabeblack@google.com m_cache_num_set_bits = floorLog2(m_cache_num_sets); 6512993Sgabeblack@google.com assert(m_cache_num_set_bits > 0); 6612993Sgabeblack@google.com 6712952Sgabeblack@google.com if (m_policy == "PSEUDO_LRU") 6812952Sgabeblack@google.com m_replacementPolicy_ptr = 6912952Sgabeblack@google.com new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); 7012952Sgabeblack@google.com else if (m_policy == "LRU") 7112952Sgabeblack@google.com m_replacementPolicy_ptr = 7213135Sgabeblack@google.com new LRUPolicy(m_cache_num_sets, m_cache_assoc); 7313135Sgabeblack@google.com else 7413135Sgabeblack@google.com assert(false); 7513135Sgabeblack@google.com 7613135Sgabeblack@google.com m_cache.setSize(m_cache_num_sets); 7713135Sgabeblack@google.com m_locked.setSize(m_cache_num_sets); 7813135Sgabeblack@google.com for (int i = 0; i < m_cache_num_sets; i++) { 7913135Sgabeblack@google.com m_cache[i].setSize(m_cache_assoc); 8012993Sgabeblack@google.com m_locked[i].setSize(m_cache_assoc); 8112993Sgabeblack@google.com for (int j = 0; j < m_cache_assoc; j++) { 8212952Sgabeblack@google.com m_cache[i][j] = NULL; 8312952Sgabeblack@google.com m_locked[i][j] = -1; 8412952Sgabeblack@google.com } 8512952Sgabeblack@google.com } 8612952Sgabeblack@google.com} 8713135Sgabeblack@google.com 8813135Sgabeblack@google.comCacheMemory::~CacheMemory() 8913135Sgabeblack@google.com{ 9013135Sgabeblack@google.com if (m_replacementPolicy_ptr != NULL) 9113135Sgabeblack@google.com delete m_replacementPolicy_ptr; 9213135Sgabeblack@google.com delete m_profiler_ptr; 9313135Sgabeblack@google.com for (int i = 0; i < m_cache_num_sets; i++) { 9413135Sgabeblack@google.com for (int j = 0; j < m_cache_assoc; j++) { 9512993Sgabeblack@google.com delete m_cache[i][j]; 9613194Sgabeblack@google.com } 9712993Sgabeblack@google.com } 9812952Sgabeblack@google.com} 9912952Sgabeblack@google.com 10012952Sgabeblack@google.comvoid 10112952Sgabeblack@google.comCacheMemory::printConfig(ostream& out) 10212837Sgabeblack@google.com{ 10312837Sgabeblack@google.com int block_size = RubySystem::getBlockSizeBytes(); 10412837Sgabeblack@google.com 10513091Sgabeblack@google.com out << "Cache config: " << m_cache_name << endl; 10612951Sgabeblack@google.com out << " cache_associativity: " << m_cache_assoc << endl; 10712951Sgabeblack@google.com out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; 10812837Sgabeblack@google.com const int cache_num_sets = 1 << m_cache_num_set_bits; 10913091Sgabeblack@google.com out << " num_cache_sets: " << cache_num_sets << endl; 11012951Sgabeblack@google.com out << " cache_set_size_bytes: " << cache_num_sets * block_size << endl; 11112951Sgabeblack@google.com out << " cache_set_size_Kbytes: " 11212837Sgabeblack@google.com << double(cache_num_sets * block_size) / (1<<10) << endl; 11313091Sgabeblack@google.com out << " cache_set_size_Mbytes: " 11412837Sgabeblack@google.com << double(cache_num_sets * block_size) / (1<<20) << endl; 11512982Sgabeblack@google.com out << " cache_size_bytes: " 11612837Sgabeblack@google.com << cache_num_sets * block_size * m_cache_assoc << endl; 11713091Sgabeblack@google.com out << " cache_size_Kbytes: " 11812837Sgabeblack@google.com << double(cache_num_sets * block_size * m_cache_assoc) / (1<<10) 11912837Sgabeblack@google.com << endl; 12012837Sgabeblack@google.com out << " cache_size_Mbytes: " 12112837Sgabeblack@google.com << double(cache_num_sets * block_size * m_cache_assoc) / (1<<20) 12212837Sgabeblack@google.com << endl; 12312837Sgabeblack@google.com} 12412837Sgabeblack@google.com 12512837Sgabeblack@google.com// convert a Address to its location in the cache 12612837Sgabeblack@google.comIndex 12712837Sgabeblack@google.comCacheMemory::addressToCacheSet(const Address& address) const 12812837Sgabeblack@google.com{ 12912837Sgabeblack@google.com assert(address == line_address(address)); 13012837Sgabeblack@google.com return address.bitSelect(RubySystem::getBlockSizeBits(), 13112837Sgabeblack@google.com RubySystem::getBlockSizeBits() + m_cache_num_set_bits - 1); 13212837Sgabeblack@google.com} 13312837Sgabeblack@google.com 13412837Sgabeblack@google.com// Given a cache index: returns the index of the tag in a set. 13512837Sgabeblack@google.com// returns -1 if the tag is not found. 13612837Sgabeblack@google.comint 13712837Sgabeblack@google.comCacheMemory::findTagInSet(Index cacheSet, const Address& tag) const 13812837Sgabeblack@google.com{ 13912837Sgabeblack@google.com assert(tag == line_address(tag)); 14012837Sgabeblack@google.com // search the set for the tags 14112837Sgabeblack@google.com m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); 14212837Sgabeblack@google.com if (it != m_tag_index.end()) 14312837Sgabeblack@google.com if (m_cache[cacheSet][it->second]->m_Permission != 14412837Sgabeblack@google.com AccessPermission_NotPresent) 14512837Sgabeblack@google.com return it->second; 14612837Sgabeblack@google.com return -1; // Not found 14712837Sgabeblack@google.com} 14812837Sgabeblack@google.com 14912837Sgabeblack@google.com// Given a cache index: returns the index of the tag in a set. 15012837Sgabeblack@google.com// returns -1 if the tag is not found. 15112837Sgabeblack@google.comint 15212837Sgabeblack@google.comCacheMemory::findTagInSetIgnorePermissions(Index cacheSet, 15312837Sgabeblack@google.com const Address& tag) const 15412837Sgabeblack@google.com{ 15512837Sgabeblack@google.com assert(tag == line_address(tag)); 15612837Sgabeblack@google.com // search the set for the tags 15712837Sgabeblack@google.com m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); 15812837Sgabeblack@google.com if (it != m_tag_index.end()) 15912837Sgabeblack@google.com return it->second; 16012837Sgabeblack@google.com return -1; // Not found 16112837Sgabeblack@google.com} 16212837Sgabeblack@google.com 16312837Sgabeblack@google.combool 16412837Sgabeblack@google.comCacheMemory::tryCacheAccess(const Address& address, CacheRequestType type, 16512837Sgabeblack@google.com DataBlock*& data_ptr) 16612837Sgabeblack@google.com{ 16712837Sgabeblack@google.com assert(address == line_address(address)); 16812837Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, HighPrio, address); 16912837Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 17012837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 17112837Sgabeblack@google.com if (loc != -1) { 17212837Sgabeblack@google.com // Do we even have a tag match? 17312837Sgabeblack@google.com AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 17412837Sgabeblack@google.com m_replacementPolicy_ptr-> 17512837Sgabeblack@google.com touch(cacheSet, loc, g_eventQueue_ptr->getTime()); 17612837Sgabeblack@google.com data_ptr = &(entry->getDataBlk()); 17712837Sgabeblack@google.com 17812837Sgabeblack@google.com if (entry->m_Permission == AccessPermission_Read_Write) { 17912837Sgabeblack@google.com return true; 18012837Sgabeblack@google.com } 18112837Sgabeblack@google.com if ((entry->m_Permission == AccessPermission_Read_Only) && 18212837Sgabeblack@google.com (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { 18312837Sgabeblack@google.com return true; 18412837Sgabeblack@google.com } 18513091Sgabeblack@google.com // The line must not be accessible 18613091Sgabeblack@google.com } 18713091Sgabeblack@google.com data_ptr = NULL; 18813091Sgabeblack@google.com return false; 18913091Sgabeblack@google.com} 19013091Sgabeblack@google.com 19113091Sgabeblack@google.combool 19213091Sgabeblack@google.comCacheMemory::testCacheAccess(const Address& address, CacheRequestType type, 19313091Sgabeblack@google.com DataBlock*& data_ptr) 19413091Sgabeblack@google.com{ 19513091Sgabeblack@google.com assert(address == line_address(address)); 19613091Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, HighPrio, address); 19713091Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 19813091Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 19913091Sgabeblack@google.com 20013091Sgabeblack@google.com if (loc != -1) { 20113091Sgabeblack@google.com // Do we even have a tag match? 20213091Sgabeblack@google.com AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 20313091Sgabeblack@google.com m_replacementPolicy_ptr-> 20413091Sgabeblack@google.com touch(cacheSet, loc, g_eventQueue_ptr->getTime()); 20513091Sgabeblack@google.com data_ptr = &(entry->getDataBlk()); 20613091Sgabeblack@google.com 20713091Sgabeblack@google.com return m_cache[cacheSet][loc]->m_Permission != 20813091Sgabeblack@google.com AccessPermission_NotPresent; 20912837Sgabeblack@google.com } 21012837Sgabeblack@google.com 21113292Sgabeblack@google.com data_ptr = NULL; 21213292Sgabeblack@google.com return false; 21313292Sgabeblack@google.com} 21413292Sgabeblack@google.com 21513292Sgabeblack@google.com// tests to see if an address is present in the cache 21613292Sgabeblack@google.combool 21713292Sgabeblack@google.comCacheMemory::isTagPresent(const Address& address) const 21813292Sgabeblack@google.com{ 21913292Sgabeblack@google.com assert(address == line_address(address)); 22013292Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 22113292Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 22213292Sgabeblack@google.com 22313292Sgabeblack@google.com if (loc == -1) { 22413292Sgabeblack@google.com // We didn't find the tag 22513292Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, LowPrio, address); 22613292Sgabeblack@google.com DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); 22713292Sgabeblack@google.com return false; 22813292Sgabeblack@google.com } 22913292Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, LowPrio, address); 23013292Sgabeblack@google.com DEBUG_MSG(CACHE_COMP, LowPrio, "found"); 23113292Sgabeblack@google.com return true; 23213292Sgabeblack@google.com} 23313292Sgabeblack@google.com 23413292Sgabeblack@google.com// Returns true if there is: 23513292Sgabeblack@google.com// a) a tag match on this address or there is 23613292Sgabeblack@google.com// b) an unused line in the same cache "way" 23713292Sgabeblack@google.combool 23813292Sgabeblack@google.comCacheMemory::cacheAvail(const Address& address) const 23912837Sgabeblack@google.com{ 24012837Sgabeblack@google.com assert(address == line_address(address)); 24112837Sgabeblack@google.com 24212951Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 24312837Sgabeblack@google.com 24412837Sgabeblack@google.com for (int i = 0; i < m_cache_assoc; i++) { 24512837Sgabeblack@google.com AbstractCacheEntry* entry = m_cache[cacheSet][i]; 24612837Sgabeblack@google.com if (entry != NULL) { 24712837Sgabeblack@google.com if (entry->m_Address == address || 24812951Sgabeblack@google.com entry->m_Permission == AccessPermission_NotPresent) { 24912837Sgabeblack@google.com // Already in the cache or we found an empty entry 25012837Sgabeblack@google.com return true; 25112951Sgabeblack@google.com } 25213079Sgabeblack@google.com } else { 25312951Sgabeblack@google.com return true; 25413284Sgabeblack@google.com } 25513284Sgabeblack@google.com } 25613284Sgabeblack@google.com return false; 25713284Sgabeblack@google.com} 25813284Sgabeblack@google.com 25913284Sgabeblack@google.comvoid 26013284Sgabeblack@google.comCacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) 26113284Sgabeblack@google.com{ 26213284Sgabeblack@google.com assert(address == line_address(address)); 26313284Sgabeblack@google.com assert(!isTagPresent(address)); 26412837Sgabeblack@google.com assert(cacheAvail(address)); 26512951Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, HighPrio, address); 26613191Sgabeblack@google.com 26713191Sgabeblack@google.com // Find the first open slot 26813191Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 26913191Sgabeblack@google.com Vector<AbstractCacheEntry*> &set = m_cache[cacheSet]; 27013191Sgabeblack@google.com for (int i = 0; i < m_cache_assoc; i++) { 27113191Sgabeblack@google.com if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) { 27213191Sgabeblack@google.com set[i] = entry; // Init entry 27312951Sgabeblack@google.com set[i]->m_Address = address; 27412951Sgabeblack@google.com set[i]->m_Permission = AccessPermission_Invalid; 27513191Sgabeblack@google.com DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n", 27613191Sgabeblack@google.com address); 27713191Sgabeblack@google.com m_locked[cacheSet][i] = -1; 27813191Sgabeblack@google.com m_tag_index[address] = i; 27913191Sgabeblack@google.com 28013191Sgabeblack@google.com m_replacementPolicy_ptr-> 28113191Sgabeblack@google.com touch(cacheSet, i, g_eventQueue_ptr->getTime()); 28213191Sgabeblack@google.com 28313191Sgabeblack@google.com return; 28413191Sgabeblack@google.com } 28513191Sgabeblack@google.com } 28613191Sgabeblack@google.com ERROR_MSG("Allocate didn't find an available entry"); 28712928Sgabeblack@google.com} 28812837Sgabeblack@google.com 28913260Sgabeblack@google.comvoid 29012837Sgabeblack@google.comCacheMemory::deallocate(const Address& address) 29113288Sgabeblack@google.com{ 29212837Sgabeblack@google.com assert(address == line_address(address)); 29312837Sgabeblack@google.com assert(isTagPresent(address)); 29412837Sgabeblack@google.com DEBUG_EXPR(CACHE_COMP, HighPrio, address); 29513260Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 29612837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 29713288Sgabeblack@google.com if (loc != -1) { 29812837Sgabeblack@google.com delete m_cache[cacheSet][loc]; 29912837Sgabeblack@google.com m_cache[cacheSet][loc] = NULL; 30012837Sgabeblack@google.com DPRINTF(RubyCache, "Deallocate clearing lock for addr: %x\n", 30113260Sgabeblack@google.com address); 30212837Sgabeblack@google.com m_locked[cacheSet][loc] = -1; 30313288Sgabeblack@google.com m_tag_index.erase(address); 30412837Sgabeblack@google.com } 30512837Sgabeblack@google.com} 30612837Sgabeblack@google.com 30713260Sgabeblack@google.com// Returns with the physical address of the conflicting cache line 30812837Sgabeblack@google.comAddress 30913288Sgabeblack@google.comCacheMemory::cacheProbe(const Address& address) const 31012837Sgabeblack@google.com{ 31112837Sgabeblack@google.com assert(address == line_address(address)); 31212837Sgabeblack@google.com assert(!cacheAvail(address)); 31312837Sgabeblack@google.com 31413260Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 31512837Sgabeblack@google.com return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]-> 31613288Sgabeblack@google.com m_Address; 31712837Sgabeblack@google.com} 31812837Sgabeblack@google.com 31912837Sgabeblack@google.com// looks an address up in the cache 32013260Sgabeblack@google.comAbstractCacheEntry& 32112837Sgabeblack@google.comCacheMemory::lookup(const Address& address) 32213288Sgabeblack@google.com{ 32312837Sgabeblack@google.com assert(address == line_address(address)); 32412837Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 32512837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 32613260Sgabeblack@google.com assert(loc != -1); 32712837Sgabeblack@google.com return *m_cache[cacheSet][loc]; 32813288Sgabeblack@google.com} 32912837Sgabeblack@google.com 33012837Sgabeblack@google.com// looks an address up in the cache 33112837Sgabeblack@google.comconst AbstractCacheEntry& 33213260Sgabeblack@google.comCacheMemory::lookup(const Address& address) const 33312837Sgabeblack@google.com{ 33413288Sgabeblack@google.com assert(address == line_address(address)); 33512837Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 33612837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 33712837Sgabeblack@google.com assert(loc != -1); 33812837Sgabeblack@google.com return *m_cache[cacheSet][loc]; 33912837Sgabeblack@google.com} 34012837Sgabeblack@google.com 34113194Sgabeblack@google.comAccessPermission 34212837Sgabeblack@google.comCacheMemory::getPermission(const Address& address) const 34312837Sgabeblack@google.com{ 34412837Sgabeblack@google.com assert(address == line_address(address)); 34512953Sgabeblack@google.com return lookup(address).m_Permission; 34612837Sgabeblack@google.com} 34712953Sgabeblack@google.com 34812837Sgabeblack@google.comvoid 34912837Sgabeblack@google.comCacheMemory::changePermission(const Address& address, 35012837Sgabeblack@google.com AccessPermission new_perm) 35112951Sgabeblack@google.com{ 35212951Sgabeblack@google.com assert(address == line_address(address)); 35312837Sgabeblack@google.com lookup(address).m_Permission = new_perm; 35412951Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 35512837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 35612951Sgabeblack@google.com if (new_perm != AccessPermission_Read_Write) { 35712837Sgabeblack@google.com DPRINTF(RubyCache, "Permission clearing lock for addr: %x\n", address); 35812837Sgabeblack@google.com m_locked[cacheSet][loc] = -1; 35912837Sgabeblack@google.com } 36012951Sgabeblack@google.com assert(getPermission(address) == new_perm); 36112837Sgabeblack@google.com} 36212951Sgabeblack@google.com 36312837Sgabeblack@google.com// Sets the most recently used bit for a cache block 36412837Sgabeblack@google.comvoid 36512837Sgabeblack@google.comCacheMemory::setMRU(const Address& address) 36612951Sgabeblack@google.com{ 36712837Sgabeblack@google.com Index cacheSet; 36812951Sgabeblack@google.com 36912837Sgabeblack@google.com cacheSet = addressToCacheSet(address); 37012837Sgabeblack@google.com m_replacementPolicy_ptr-> 37112837Sgabeblack@google.com touch(cacheSet, findTagInSet(cacheSet, address), 37212951Sgabeblack@google.com g_eventQueue_ptr->getTime()); 37312837Sgabeblack@google.com} 37412951Sgabeblack@google.com 37512837Sgabeblack@google.comvoid 37612837Sgabeblack@google.comCacheMemory::profileMiss(const CacheMsg& msg) 37712837Sgabeblack@google.com{ 37812951Sgabeblack@google.com m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), 37912837Sgabeblack@google.com msg.getSize(), msg.getPrefetch()); 38012951Sgabeblack@google.com} 38112837Sgabeblack@google.com 38212837Sgabeblack@google.comvoid 38312837Sgabeblack@google.comCacheMemory::recordCacheContents(CacheRecorder& tr) const 38412951Sgabeblack@google.com{ 38512837Sgabeblack@google.com for (int i = 0; i < m_cache_num_sets; i++) { 38612951Sgabeblack@google.com for (int j = 0; j < m_cache_assoc; j++) { 38712837Sgabeblack@google.com AccessPermission perm = m_cache[i][j]->m_Permission; 38812837Sgabeblack@google.com CacheRequestType request_type = CacheRequestType_NULL; 38912837Sgabeblack@google.com if (perm == AccessPermission_Read_Only) { 39012951Sgabeblack@google.com if (m_is_instruction_only_cache) { 39112837Sgabeblack@google.com request_type = CacheRequestType_IFETCH; 39212951Sgabeblack@google.com } else { 39312837Sgabeblack@google.com request_type = CacheRequestType_LD; 39412837Sgabeblack@google.com } 39512837Sgabeblack@google.com } else if (perm == AccessPermission_Read_Write) { 39612951Sgabeblack@google.com request_type = CacheRequestType_ST; 39712837Sgabeblack@google.com } 39812951Sgabeblack@google.com 39912837Sgabeblack@google.com if (request_type != CacheRequestType_NULL) { 40012837Sgabeblack@google.com#if 0 40112837Sgabeblack@google.com tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, 40212951Sgabeblack@google.com Address(0), request_type, 40312837Sgabeblack@google.com m_replacementPolicy_ptr->getLastAccess(i, j)); 40412951Sgabeblack@google.com#endif 40512837Sgabeblack@google.com } 40612837Sgabeblack@google.com } 40712837Sgabeblack@google.com } 40812951Sgabeblack@google.com} 40912837Sgabeblack@google.com 41012951Sgabeblack@google.comvoid 41112837Sgabeblack@google.comCacheMemory::print(ostream& out) const 41212837Sgabeblack@google.com{ 41312837Sgabeblack@google.com out << "Cache dump: " << m_cache_name << endl; 41412951Sgabeblack@google.com for (int i = 0; i < m_cache_num_sets; i++) { 41512837Sgabeblack@google.com for (int j = 0; j < m_cache_assoc; j++) { 41612951Sgabeblack@google.com if (m_cache[i][j] != NULL) { 41712837Sgabeblack@google.com out << " Index: " << i 41812837Sgabeblack@google.com << " way: " << j 41912837Sgabeblack@google.com << " entry: " << *m_cache[i][j] << endl; 42012929Sgabeblack@google.com } else { 42112929Sgabeblack@google.com out << " Index: " << i 42212929Sgabeblack@google.com << " way: " << j 42313189Sgabeblack@google.com << " entry: NULL" << endl; 42412929Sgabeblack@google.com } 42512929Sgabeblack@google.com } 42612929Sgabeblack@google.com } 42712837Sgabeblack@google.com} 42812837Sgabeblack@google.com 42912837Sgabeblack@google.comvoid 43012951Sgabeblack@google.comCacheMemory::printData(ostream& out) const 43112837Sgabeblack@google.com{ 43212837Sgabeblack@google.com out << "printData() not supported" << endl; 43312837Sgabeblack@google.com} 43412951Sgabeblack@google.com 43512837Sgabeblack@google.comvoid 43612951Sgabeblack@google.comCacheMemory::clearStats() const 43712837Sgabeblack@google.com{ 43812837Sgabeblack@google.com m_profiler_ptr->clearStats(); 43912837Sgabeblack@google.com} 44012951Sgabeblack@google.com 44112837Sgabeblack@google.comvoid 44212951Sgabeblack@google.comCacheMemory::printStats(ostream& out) const 44312837Sgabeblack@google.com{ 44412837Sgabeblack@google.com m_profiler_ptr->printStats(out); 44512837Sgabeblack@google.com} 44612951Sgabeblack@google.com 44712837Sgabeblack@google.comvoid 44812951Sgabeblack@google.comCacheMemory::getMemoryValue(const Address& addr, char* value, 44912837Sgabeblack@google.com unsigned size_in_bytes) 45012837Sgabeblack@google.com{ 45112837Sgabeblack@google.com AbstractCacheEntry& entry = lookup(line_address(addr)); 45212951Sgabeblack@google.com unsigned startByte = addr.getAddress() - line_address(addr).getAddress(); 45312837Sgabeblack@google.com for (unsigned i = 0; i < size_in_bytes; ++i) { 45412951Sgabeblack@google.com value[i] = entry.getDataBlk().getByte(i + startByte); 45512837Sgabeblack@google.com } 45612837Sgabeblack@google.com} 45712837Sgabeblack@google.com 45812951Sgabeblack@google.comvoid 45912837Sgabeblack@google.comCacheMemory::setMemoryValue(const Address& addr, char* value, 46012951Sgabeblack@google.com unsigned size_in_bytes) 46112837Sgabeblack@google.com{ 46212837Sgabeblack@google.com AbstractCacheEntry& entry = lookup(line_address(addr)); 46312837Sgabeblack@google.com unsigned startByte = addr.getAddress() - line_address(addr).getAddress(); 46412951Sgabeblack@google.com assert(size_in_bytes > 0); 46512837Sgabeblack@google.com for (unsigned i = 0; i < size_in_bytes; ++i) { 46612951Sgabeblack@google.com entry.getDataBlk().setByte(i + startByte, value[i]); 46712837Sgabeblack@google.com } 46812837Sgabeblack@google.com 46912837Sgabeblack@google.com // entry = lookup(line_address(addr)); 47012951Sgabeblack@google.com} 47112837Sgabeblack@google.com 47212951Sgabeblack@google.comvoid 47312837Sgabeblack@google.comCacheMemory::setLocked(const Address& address, int context) 47412837Sgabeblack@google.com{ 47512837Sgabeblack@google.com DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context); 47612951Sgabeblack@google.com assert(address == line_address(address)); 47712837Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 47812951Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 47912837Sgabeblack@google.com assert(loc != -1); 48012837Sgabeblack@google.com m_locked[cacheSet][loc] = context; 48112837Sgabeblack@google.com} 48212951Sgabeblack@google.com 48312837Sgabeblack@google.comvoid 48412951Sgabeblack@google.comCacheMemory::clearLocked(const Address& address) 48512837Sgabeblack@google.com{ 48612837Sgabeblack@google.com DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address); 48712837Sgabeblack@google.com assert(address == line_address(address)); 48812951Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 48912837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 49012951Sgabeblack@google.com assert(loc != -1); 49112837Sgabeblack@google.com m_locked[cacheSet][loc] = -1; 49212837Sgabeblack@google.com} 49312837Sgabeblack@google.com 49412951Sgabeblack@google.combool 49512837Sgabeblack@google.comCacheMemory::isLocked(const Address& address, int context) 49612951Sgabeblack@google.com{ 49712837Sgabeblack@google.com assert(address == line_address(address)); 49812837Sgabeblack@google.com Index cacheSet = addressToCacheSet(address); 49912837Sgabeblack@google.com int loc = findTagInSet(cacheSet, address); 50012951Sgabeblack@google.com assert(loc != -1); 50112837Sgabeblack@google.com DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n", 50212951Sgabeblack@google.com address, m_locked[cacheSet][loc], context); 50312837Sgabeblack@google.com return m_locked[cacheSet][loc] == context; 50412837Sgabeblack@google.com} 50512837Sgabeblack@google.com 50612837Sgabeblack@google.com