CacheMemory.hh revision 6374
110037SARM gem5 Developers/* 212504Snikos.nikoleris@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 310037SARM gem5 Developers * All rights reserved. 410037SARM gem5 Developers * 510037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without 610037SARM gem5 Developers * modification, are permitted provided that the following conditions are 710037SARM gem5 Developers * met: redistributions of source code must retain the above copyright 810037SARM gem5 Developers * notice, this list of conditions and the following disclaimer; 910037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright 1010037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the 1110037SARM gem5 Developers * documentation and/or other materials provided with the distribution; 1210037SARM gem5 Developers * neither the name of the copyright holders nor the names of its 1310037SARM gem5 Developers * contributors may be used to endorse or promote products derived from 1410037SARM gem5 Developers * this software without specific prior written permission. 1510037SARM gem5 Developers * 1610037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710037SARM gem5 Developers */ 2810037SARM gem5 Developers 2910037SARM gem5 Developers/* 3010037SARM gem5 Developers * CacheMemory.hh 3110037SARM gem5 Developers * 3210037SARM gem5 Developers * Description: 3310037SARM gem5 Developers * 3410037SARM gem5 Developers * $Id: CacheMemory.hh,v 3.7 2004/06/18 20:15:15 beckmann Exp $ 3510037SARM gem5 Developers * 3610037SARM gem5 Developers */ 3710037SARM gem5 Developers 3810037SARM gem5 Developers#ifndef CACHEMEMORY_H 3910037SARM gem5 Developers#define CACHEMEMORY_H 4010037SARM gem5 Developers 4111793Sbrandon.potter@amd.com#include "mem/ruby/common/Global.hh" 4210037SARM gem5 Developers#include "mem/protocol/AccessPermission.hh" 4310037SARM gem5 Developers#include "mem/ruby/common/Address.hh" 4410037SARM gem5 Developers#include "mem/ruby/recorder/CacheRecorder.hh" 4510037SARM gem5 Developers#include "mem/protocol/CacheRequestType.hh" 4610037SARM gem5 Developers#include "mem/gems_common/Vector.hh" 4710037SARM gem5 Developers#include "mem/ruby/common/DataBlock.hh" 4810037SARM gem5 Developers#include "mem/protocol/MachineType.hh" 4910037SARM gem5 Developers#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" 5010037SARM gem5 Developers#include "mem/ruby/system/PseudoLRUPolicy.hh" 5110037SARM gem5 Developers#include "mem/ruby/system/LRUPolicy.hh" 5210037SARM gem5 Developers#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" 5310037SARM gem5 Developers#include "mem/ruby/system/System.hh" 5410037SARM gem5 Developers#include "mem/ruby/slicc_interface/AbstractController.hh" 5510037SARM gem5 Developers#include "mem/ruby/profiler/CacheProfiler.hh" 5612504Snikos.nikoleris@arm.com#include "mem/protocol/CacheMsg.hh" 5712104Snathanael.premillieu@arm.com#include <vector> 5810037SARM gem5 Developers 5910037SARM gem5 Developersclass CacheMemory { 6010037SARM gem5 Developerspublic: 6110037SARM gem5 Developers 6210037SARM gem5 Developers // Constructors 6310037SARM gem5 Developers CacheMemory(const string & name); 6410037SARM gem5 Developers void init(const vector<string> & argv); 6510037SARM gem5 Developers 6610037SARM gem5 Developers // Destructor 6713367Syuetsu.kodama@riken.jp ~CacheMemory(); 6813367Syuetsu.kodama@riken.jp 6913367Syuetsu.kodama@riken.jp // factory 7013367Syuetsu.kodama@riken.jp // static CacheMemory* createCache(int level, int num, char split_type, AbstractCacheEntry* (*entry_factory)()); 7113367Syuetsu.kodama@riken.jp // static CacheMemory* getCache(int cache_id); 7210037SARM gem5 Developers 7312104Snathanael.premillieu@arm.com // Public Methods 7410037SARM gem5 Developers void printConfig(ostream& out); 7510037SARM gem5 Developers 7610037SARM gem5 Developers // perform a cache access and see if we hit or not. Return true on a hit. 7710037SARM gem5 Developers bool tryCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr); 7810037SARM gem5 Developers 7910037SARM gem5 Developers // similar to above, but doesn't require full access check 8010037SARM gem5 Developers bool testCacheAccess(const Address& address, CacheRequestType type, DataBlock*& data_ptr); 8110037SARM gem5 Developers 8210037SARM gem5 Developers // tests to see if an address is present in the cache 8310037SARM gem5 Developers bool isTagPresent(const Address& address) const; 8410037SARM gem5 Developers 8510037SARM gem5 Developers // Returns true if there is: 8610037SARM gem5 Developers // a) a tag match on this address or there is 8710037SARM gem5 Developers // b) an unused line in the same cache "way" 8810037SARM gem5 Developers bool cacheAvail(const Address& address) const; 8910037SARM gem5 Developers 9010037SARM gem5 Developers // find an unused entry and sets the tag appropriate for the address 9110037SARM gem5 Developers void allocate(const Address& address, AbstractCacheEntry* new_entry); 9210037SARM gem5 Developers 9310037SARM gem5 Developers // Explicitly free up this address 9410037SARM gem5 Developers void deallocate(const Address& address); 9510037SARM gem5 Developers 9610037SARM gem5 Developers // Returns with the physical address of the conflicting cache line 9710037SARM gem5 Developers Address cacheProbe(const Address& address) const; 9810037SARM gem5 Developers 9910037SARM gem5 Developers // looks an address up in the cache 10010037SARM gem5 Developers AbstractCacheEntry& lookup(const Address& address); 10110037SARM gem5 Developers const AbstractCacheEntry& lookup(const Address& address) const; 10210037SARM gem5 Developers 10310037SARM gem5 Developers // Get/Set permission of cache block 10410037SARM gem5 Developers AccessPermission getPermission(const Address& address) const; 10510037SARM gem5 Developers void changePermission(const Address& address, AccessPermission new_perm); 10612104Snathanael.premillieu@arm.com 10710037SARM gem5 Developers int getLatency() const { return m_latency; } 10812104Snathanael.premillieu@arm.com 10910037SARM gem5 Developers // Hook for checkpointing the contents of the cache 11012104Snathanael.premillieu@arm.com void recordCacheContents(CacheRecorder& tr) const; 11110037SARM gem5 Developers void setAsInstructionCache(bool is_icache) { m_is_instruction_only_cache = is_icache; } 11210037SARM gem5 Developers 11310037SARM gem5 Developers // Set this address to most recently used 11410037SARM gem5 Developers void setMRU(const Address& address); 11510037SARM gem5 Developers 11610037SARM gem5 Developers void profileMiss(const CacheMsg & msg); 11710037SARM gem5 Developers 11810037SARM gem5 Developers void getMemoryValue(const Address& addr, char* value, 11910037SARM gem5 Developers unsigned int size_in_bytes ); 12010037SARM gem5 Developers void setMemoryValue(const Address& addr, char* value, 12110037SARM gem5 Developers unsigned int size_in_bytes ); 12212104Snathanael.premillieu@arm.com 12310037SARM gem5 Developers void setLocked (const Address& addr, int context); 12412104Snathanael.premillieu@arm.com void clearLocked (const Address& addr); 12510037SARM gem5 Developers bool isLocked (const Address& addr, int context); 12612104Snathanael.premillieu@arm.com // Print cache contents 12710037SARM gem5 Developers void print(ostream& out) const; 12812104Snathanael.premillieu@arm.com void printData(ostream& out) const; 12910037SARM gem5 Developers 13010037SARM gem5 Developers void printStats(ostream& out) const; 13110037SARM gem5 Developers 13210037SARM gem5 Developersprivate: 13310037SARM gem5 Developers // Private Methods 13410037SARM gem5 Developers 13510037SARM gem5 Developers // convert a Address to its location in the cache 13610037SARM gem5 Developers Index addressToCacheSet(const Address& address) const; 13710037SARM gem5 Developers 13810037SARM gem5 Developers // Given a cache tag: returns the index of the tag in a set. 13910037SARM gem5 Developers // returns -1 if the tag is not found. 14010037SARM gem5 Developers int findTagInSet(Index line, const Address& tag) const; 14110037SARM gem5 Developers int findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const; 14210037SARM gem5 Developers 14310037SARM gem5 Developers // Private copy constructor and assignment operator 14410037SARM gem5 Developers CacheMemory(const CacheMemory& obj); 14510037SARM gem5 Developers CacheMemory& operator=(const CacheMemory& obj); 14610037SARM gem5 Developers 14710037SARM gem5 Developersprivate: 14810037SARM gem5 Developers const string m_cache_name; 14910037SARM gem5 Developers AbstractController* m_controller; 15010037SARM gem5 Developers int m_latency; 15110037SARM gem5 Developers 15210037SARM gem5 Developers // Data Members (m_prefix) 15310037SARM gem5 Developers bool m_is_instruction_only_cache; 15410037SARM gem5 Developers bool m_is_data_only_cache; 15510037SARM gem5 Developers 15610037SARM gem5 Developers // The first index is the # of cache lines. 15710037SARM gem5 Developers // The second index is the the amount associativity. 15810037SARM gem5 Developers Vector<Vector<AbstractCacheEntry*> > m_cache; 15910037SARM gem5 Developers Vector<Vector<int> > m_locked; 16010037SARM gem5 Developers 16110037SARM gem5 Developers AbstractReplacementPolicy *m_replacementPolicy_ptr; 16210037SARM gem5 Developers 16310037SARM gem5 Developers CacheProfiler* m_profiler_ptr; 16410037SARM gem5 Developers 16510037SARM gem5 Developers int m_cache_num_sets; 16610037SARM gem5 Developers int m_cache_num_set_bits; 16710037SARM gem5 Developers int m_cache_assoc; 16810037SARM gem5 Developers 16910037SARM gem5 Developers static Vector< CacheMemory* > m_all_caches; 17010037SARM gem5 Developers}; 17110037SARM gem5 Developers 17210037SARM gem5 Developers// Output operator declaration 17310037SARM gem5 Developers//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj); 17410037SARM gem5 Developers 17510037SARM gem5 Developers// ******************* Definitions ******************* 17610037SARM gem5 Developers 17710037SARM gem5 Developers// Output operator definition 17810037SARM gem5 Developersinline 17912104Snathanael.premillieu@arm.comostream& operator<<(ostream& out, const CacheMemory& obj) 18010037SARM gem5 Developers{ 18112104Snathanael.premillieu@arm.com obj.print(out); 18210037SARM gem5 Developers out << flush; 18312104Snathanael.premillieu@arm.com return out; 18410037SARM gem5 Developers} 18510037SARM gem5 Developers 18610037SARM gem5 Developers 18710037SARM gem5 Developers// **************************************************************** 18810037SARM gem5 Developers 18910037SARM gem5 Developersinline 19010037SARM gem5 DevelopersCacheMemory::CacheMemory(const string & name) 19110037SARM gem5 Developers : m_cache_name(name) 19210037SARM gem5 Developers{ 19312104Snathanael.premillieu@arm.com m_profiler_ptr = new CacheProfiler(name); 19410037SARM gem5 Developers} 19510037SARM gem5 Developers 19610037SARM gem5 Developersinline 19710037SARM gem5 Developersvoid CacheMemory::init(const vector<string> & argv) 198{ 199 int cache_size = 0; 200 string policy; 201 202 m_controller = NULL; 203 for (uint32 i=0; i<argv.size(); i+=2) { 204 if (argv[i] == "size_kb") { 205 cache_size = atoi(argv[i+1].c_str()); 206 } else if (argv[i] == "latency") { 207 m_latency = atoi(argv[i+1].c_str()); 208 } else if (argv[i] == "assoc") { 209 m_cache_assoc = atoi(argv[i+1].c_str()); 210 } else if (argv[i] == "replacement_policy") { 211 policy = argv[i+1]; 212 } else if (argv[i] == "controller") { 213 m_controller = RubySystem::getController(argv[i+1]); 214 } else { 215 cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; 216 } 217 } 218 219 m_cache_num_sets = cache_size / m_cache_assoc; 220 m_cache_num_set_bits = log_int(m_cache_num_sets); 221 222 if(policy == "PSEUDO_LRU") 223 m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); 224 else if (policy == "LRU") 225 m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); 226 else 227 assert(false); 228 229 m_cache.setSize(m_cache_num_sets); 230 m_locked.setSize(m_cache_num_sets); 231 for (int i = 0; i < m_cache_num_sets; i++) { 232 m_cache[i].setSize(m_cache_assoc); 233 m_locked[i].setSize(m_cache_assoc); 234 for (int j = 0; j < m_cache_assoc; j++) { 235 m_cache[i][j] = NULL; 236 m_locked[i][j] = -1; 237 } 238 } 239} 240 241inline 242CacheMemory::~CacheMemory() 243{ 244 if(m_replacementPolicy_ptr != NULL) 245 delete m_replacementPolicy_ptr; 246} 247 248inline 249void CacheMemory::printConfig(ostream& out) 250{ 251 out << "Cache config: " << m_cache_name << endl; 252 if (m_controller != NULL) 253 out << " controller: " << m_controller->getName() << endl; 254 out << " cache_associativity: " << m_cache_assoc << endl; 255 out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; 256 const int cache_num_sets = 1 << m_cache_num_set_bits; 257 out << " num_cache_sets: " << cache_num_sets << endl; 258 out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; 259 out << " cache_set_size_Kbytes: " 260 << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; 261 out << " cache_set_size_Mbytes: " 262 << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; 263 out << " cache_size_bytes: " 264 << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; 265 out << " cache_size_Kbytes: " 266 << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; 267 out << " cache_size_Mbytes: " 268 << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; 269} 270 271// PRIVATE METHODS 272 273// convert a Address to its location in the cache 274inline 275Index CacheMemory::addressToCacheSet(const Address& address) const 276{ 277 assert(address == line_address(address)); 278 return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); 279} 280 281// Given a cache index: returns the index of the tag in a set. 282// returns -1 if the tag is not found. 283inline 284int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const 285{ 286 assert(tag == line_address(tag)); 287 // search the set for the tags 288 for (int i=0; i < m_cache_assoc; i++) { 289 if ((m_cache[cacheSet][i] != NULL) && 290 (m_cache[cacheSet][i]->m_Address == tag) && 291 (m_cache[cacheSet][i]->m_Permission != AccessPermission_NotPresent)) { 292 return i; 293 } 294 } 295 return -1; // Not found 296} 297 298// Given a cache index: returns the index of the tag in a set. 299// returns -1 if the tag is not found. 300inline 301int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const 302{ 303 assert(tag == line_address(tag)); 304 // search the set for the tags 305 for (int i=0; i < m_cache_assoc; i++) { 306 if (m_cache[cacheSet][i] != NULL && m_cache[cacheSet][i]->m_Address == tag) 307 return i; 308 } 309 return -1; // Not found 310} 311 312// PUBLIC METHODS 313inline 314bool CacheMemory::tryCacheAccess(const Address& address, 315 CacheRequestType type, 316 DataBlock*& data_ptr) 317{ 318 assert(address == line_address(address)); 319 DEBUG_EXPR(CACHE_COMP, HighPrio, address); 320 Index cacheSet = addressToCacheSet(address); 321 int loc = findTagInSet(cacheSet, address); 322 if(loc != -1){ // Do we even have a tag match? 323 AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 324 m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); 325 data_ptr = &(entry->getDataBlk()); 326 327 if(entry->m_Permission == AccessPermission_Read_Write) { 328 return true; 329 } 330 if ((entry->m_Permission == AccessPermission_Read_Only) && 331 (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { 332 return true; 333 } 334 // The line must not be accessible 335 } 336 data_ptr = NULL; 337 return false; 338} 339 340inline 341bool CacheMemory::testCacheAccess(const Address& address, 342 CacheRequestType type, 343 DataBlock*& data_ptr) 344{ 345 assert(address == line_address(address)); 346 DEBUG_EXPR(CACHE_COMP, HighPrio, address); 347 Index cacheSet = addressToCacheSet(address); 348 int loc = findTagInSet(cacheSet, address); 349 if(loc != -1){ // Do we even have a tag match? 350 AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 351 m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); 352 data_ptr = &(entry->getDataBlk()); 353 354 return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); 355 } 356 data_ptr = NULL; 357 return false; 358} 359 360// tests to see if an address is present in the cache 361inline 362bool CacheMemory::isTagPresent(const Address& address) const 363{ 364 assert(address == line_address(address)); 365 Index cacheSet = addressToCacheSet(address); 366 int location = findTagInSet(cacheSet, address); 367 368 if (location == -1) { 369 // We didn't find the tag 370 DEBUG_EXPR(CACHE_COMP, LowPrio, address); 371 DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); 372 return false; 373 } 374 DEBUG_EXPR(CACHE_COMP, LowPrio, address); 375 DEBUG_MSG(CACHE_COMP, LowPrio, "found"); 376 return true; 377} 378 379// Returns true if there is: 380// a) a tag match on this address or there is 381// b) an unused line in the same cache "way" 382inline 383bool CacheMemory::cacheAvail(const Address& address) const 384{ 385 assert(address == line_address(address)); 386 387 Index cacheSet = addressToCacheSet(address); 388 389 for (int i=0; i < m_cache_assoc; i++) { 390 AbstractCacheEntry* entry = m_cache[cacheSet][i]; 391 if (entry != NULL) { 392 if (entry->m_Address == address || // Already in the cache 393 entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry 394 return true; 395 } 396 } else { 397 return true; 398 } 399 } 400 return false; 401} 402 403inline 404void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) 405{ 406 assert(address == line_address(address)); 407 assert(!isTagPresent(address)); 408 assert(cacheAvail(address)); 409 DEBUG_EXPR(CACHE_COMP, HighPrio, address); 410 411 // Find the first open slot 412 Index cacheSet = addressToCacheSet(address); 413 for (int i=0; i < m_cache_assoc; i++) { 414 if (m_cache[cacheSet][i] == NULL || 415 m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { 416 m_cache[cacheSet][i] = entry; // Init entry 417 m_cache[cacheSet][i]->m_Address = address; 418 m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; 419 m_locked[cacheSet][i] = -1; 420 421 m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); 422 423 return; 424 } 425 } 426 ERROR_MSG("Allocate didn't find an available entry"); 427} 428 429inline 430void CacheMemory::deallocate(const Address& address) 431{ 432 assert(address == line_address(address)); 433 assert(isTagPresent(address)); 434 DEBUG_EXPR(CACHE_COMP, HighPrio, address); 435 Index cacheSet = addressToCacheSet(address); 436 int location = findTagInSet(cacheSet, address); 437 if (location != -1){ 438 delete m_cache[cacheSet][location]; 439 m_cache[cacheSet][location] = NULL; 440 m_locked[cacheSet][location] = -1; 441 } 442} 443 444// Returns with the physical address of the conflicting cache line 445inline 446Address CacheMemory::cacheProbe(const Address& address) const 447{ 448 assert(address == line_address(address)); 449 assert(!cacheAvail(address)); 450 451 Index cacheSet = addressToCacheSet(address); 452 return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; 453} 454 455// looks an address up in the cache 456inline 457AbstractCacheEntry& CacheMemory::lookup(const Address& address) 458{ 459 assert(address == line_address(address)); 460 Index cacheSet = addressToCacheSet(address); 461 int loc = findTagInSet(cacheSet, address); 462 assert(loc != -1); 463 return *m_cache[cacheSet][loc]; 464} 465 466// looks an address up in the cache 467inline 468const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const 469{ 470 assert(address == line_address(address)); 471 Index cacheSet = addressToCacheSet(address); 472 int loc = findTagInSet(cacheSet, address); 473 assert(loc != -1); 474 return *m_cache[cacheSet][loc]; 475} 476 477inline 478AccessPermission CacheMemory::getPermission(const Address& address) const 479{ 480 assert(address == line_address(address)); 481 return lookup(address).m_Permission; 482} 483 484inline 485void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) 486{ 487 assert(address == line_address(address)); 488 lookup(address).m_Permission = new_perm; 489 Index cacheSet = addressToCacheSet(address); 490 int loc = findTagInSet(cacheSet, address); 491 m_locked[cacheSet][loc] = -1; 492 assert(getPermission(address) == new_perm); 493} 494 495// Sets the most recently used bit for a cache block 496inline 497void CacheMemory::setMRU(const Address& address) 498{ 499 Index cacheSet; 500 501 cacheSet = addressToCacheSet(address); 502 m_replacementPolicy_ptr->touch(cacheSet, 503 findTagInSet(cacheSet, address), 504 g_eventQueue_ptr->getTime()); 505} 506 507inline 508void CacheMemory::profileMiss(const CacheMsg & msg) 509{ 510 m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), 511 msg.getSize(), msg.getPrefetch()); 512} 513 514inline 515void CacheMemory::recordCacheContents(CacheRecorder& tr) const 516{ 517 for (int i = 0; i < m_cache_num_sets; i++) { 518 for (int j = 0; j < m_cache_assoc; j++) { 519 AccessPermission perm = m_cache[i][j]->m_Permission; 520 CacheRequestType request_type = CacheRequestType_NULL; 521 if (perm == AccessPermission_Read_Only) { 522 if (m_is_instruction_only_cache) { 523 request_type = CacheRequestType_IFETCH; 524 } else { 525 request_type = CacheRequestType_LD; 526 } 527 } else if (perm == AccessPermission_Read_Write) { 528 request_type = CacheRequestType_ST; 529 } 530 531 if (request_type != CacheRequestType_NULL) { 532 // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, 533 // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); 534 } 535 } 536 } 537} 538 539inline 540void CacheMemory::print(ostream& out) const 541{ 542 out << "Cache dump: " << m_cache_name << endl; 543 for (int i = 0; i < m_cache_num_sets; i++) { 544 for (int j = 0; j < m_cache_assoc; j++) { 545 if (m_cache[i][j] != NULL) { 546 out << " Index: " << i 547 << " way: " << j 548 << " entry: " << *m_cache[i][j] << endl; 549 } else { 550 out << " Index: " << i 551 << " way: " << j 552 << " entry: NULL" << endl; 553 } 554 } 555 } 556} 557 558inline 559void CacheMemory::printData(ostream& out) const 560{ 561 out << "printData() not supported" << endl; 562} 563 564inline 565void CacheMemory::printStats(ostream& out) const 566{ 567 m_profiler_ptr->printStats(out); 568} 569 570inline 571void CacheMemory::getMemoryValue(const Address& addr, char* value, 572 unsigned int size_in_bytes ){ 573 AbstractCacheEntry& entry = lookup(line_address(addr)); 574 unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); 575 for(unsigned int i=0; i<size_in_bytes; ++i){ 576 value[i] = entry.getDataBlk().getByte(i + startByte); 577 } 578} 579 580inline 581void CacheMemory::setMemoryValue(const Address& addr, char* value, 582 unsigned int size_in_bytes ){ 583 AbstractCacheEntry& entry = lookup(line_address(addr)); 584 unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); 585 assert(size_in_bytes > 0); 586 for(unsigned int i=0; i<size_in_bytes; ++i){ 587 entry.getDataBlk().setByte(i + startByte, value[i]); 588 } 589 590 // entry = lookup(line_address(addr)); 591} 592 593inline 594void 595CacheMemory::setLocked(const Address& address, int context) 596{ 597 assert(address == line_address(address)); 598 Index cacheSet = addressToCacheSet(address); 599 int loc = findTagInSet(cacheSet, address); 600 assert(loc != -1); 601 m_locked[cacheSet][loc] = context; 602} 603 604inline 605void 606CacheMemory::clearLocked(const Address& address) 607{ 608 assert(address == line_address(address)); 609 Index cacheSet = addressToCacheSet(address); 610 int loc = findTagInSet(cacheSet, address); 611 assert(loc != -1); 612 m_locked[cacheSet][loc] = -1; 613} 614 615inline 616bool 617CacheMemory::isLocked(const Address& address, int context) 618{ 619 assert(address == line_address(address)); 620 Index cacheSet = addressToCacheSet(address); 621 int loc = findTagInSet(cacheSet, address); 622 assert(loc != -1); 623 return m_locked[cacheSet][loc] == context; 624} 625 626#endif //CACHEMEMORY_H 627 628