1/* 2 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 90 unchanged lines hidden (view full) --- 99 for (int i = 0; i < m_cache_num_sets; i++) { 100 for (int j = 0; j < m_cache_assoc; j++) { 101 delete m_cache[i][j]; 102 } 103 } 104} 105 106// convert a Address to its location in the cache |
107int64 |
108CacheMemory::addressToCacheSet(const Address& address) const 109{ 110 assert(address == line_address(address)); 111 return address.bitSelect(m_start_index_bit, 112 m_start_index_bit + m_cache_num_set_bits - 1); 113} 114 115// Given a cache index: returns the index of the tag in a set. 116// returns -1 if the tag is not found. 117int |
118CacheMemory::findTagInSet(int64 cacheSet, const Address& tag) const |
119{ 120 assert(tag == line_address(tag)); 121 // search the set for the tags 122 m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); 123 if (it != m_tag_index.end()) 124 if (m_cache[cacheSet][it->second]->m_Permission != 125 AccessPermission_NotPresent) 126 return it->second; 127 return -1; // Not found 128} 129 130// Given a cache index: returns the index of the tag in a set. 131// returns -1 if the tag is not found. 132int |
133CacheMemory::findTagInSetIgnorePermissions(int64 cacheSet, |
134 const Address& tag) const 135{ 136 assert(tag == line_address(tag)); 137 // search the set for the tags 138 m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); 139 if (it != m_tag_index.end()) 140 return it->second; 141 return -1; // Not found 142} 143 144bool 145CacheMemory::tryCacheAccess(const Address& address, RubyRequestType type, 146 DataBlock*& data_ptr) 147{ 148 assert(address == line_address(address)); 149 DPRINTF(RubyCache, "address: %s\n", address); |
150 int64 cacheSet = addressToCacheSet(address); |
151 int loc = findTagInSet(cacheSet, address); 152 if (loc != -1) { 153 // Do we even have a tag match? 154 AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 155 m_replacementPolicy_ptr->touch(cacheSet, loc, curTick()); 156 data_ptr = &(entry->getDataBlk()); 157 158 if (entry->m_Permission == AccessPermission_Read_Write) { --- 10 unchanged lines hidden (view full) --- 169} 170 171bool 172CacheMemory::testCacheAccess(const Address& address, RubyRequestType type, 173 DataBlock*& data_ptr) 174{ 175 assert(address == line_address(address)); 176 DPRINTF(RubyCache, "address: %s\n", address); |
177 int64 cacheSet = addressToCacheSet(address); |
178 int loc = findTagInSet(cacheSet, address); 179 180 if (loc != -1) { 181 // Do we even have a tag match? 182 AbstractCacheEntry* entry = m_cache[cacheSet][loc]; 183 m_replacementPolicy_ptr->touch(cacheSet, loc, curTick()); 184 data_ptr = &(entry->getDataBlk()); 185 --- 5 unchanged lines hidden (view full) --- 191 return false; 192} 193 194// tests to see if an address is present in the cache 195bool 196CacheMemory::isTagPresent(const Address& address) const 197{ 198 assert(address == line_address(address)); |
199 int64 cacheSet = addressToCacheSet(address); |
200 int loc = findTagInSet(cacheSet, address); 201 202 if (loc == -1) { 203 // We didn't find the tag 204 DPRINTF(RubyCache, "No tag match for address: %s\n", address); 205 return false; 206 } 207 DPRINTF(RubyCache, "address: %s found\n", address); 208 return true; 209} 210 211// Returns true if there is: 212// a) a tag match on this address or there is 213// b) an unused line in the same cache "way" 214bool 215CacheMemory::cacheAvail(const Address& address) const 216{ 217 assert(address == line_address(address)); 218 |
219 int64 cacheSet = addressToCacheSet(address); |
220 221 for (int i = 0; i < m_cache_assoc; i++) { 222 AbstractCacheEntry* entry = m_cache[cacheSet][i]; 223 if (entry != NULL) { 224 if (entry->m_Address == address || 225 entry->m_Permission == AccessPermission_NotPresent) { 226 // Already in the cache or we found an empty entry 227 return true; --- 9 unchanged lines hidden (view full) --- 237CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) 238{ 239 assert(address == line_address(address)); 240 assert(!isTagPresent(address)); 241 assert(cacheAvail(address)); 242 DPRINTF(RubyCache, "address: %s\n", address); 243 244 // Find the first open slot |
245 int64 cacheSet = addressToCacheSet(address); |
246 std::vector<AbstractCacheEntry*> &set = m_cache[cacheSet]; 247 for (int i = 0; i < m_cache_assoc; i++) { 248 if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) { 249 set[i] = entry; // Init entry 250 set[i]->m_Address = address; 251 set[i]->m_Permission = AccessPermission_Invalid; 252 DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n", 253 address); --- 9 unchanged lines hidden (view full) --- 263} 264 265void 266CacheMemory::deallocate(const Address& address) 267{ 268 assert(address == line_address(address)); 269 assert(isTagPresent(address)); 270 DPRINTF(RubyCache, "address: %s\n", address); |
271 int64 cacheSet = addressToCacheSet(address); |
272 int loc = findTagInSet(cacheSet, address); 273 if (loc != -1) { 274 delete m_cache[cacheSet][loc]; 275 m_cache[cacheSet][loc] = NULL; 276 m_tag_index.erase(address); 277 } 278} 279 280// Returns with the physical address of the conflicting cache line 281Address 282CacheMemory::cacheProbe(const Address& address) const 283{ 284 assert(address == line_address(address)); 285 assert(!cacheAvail(address)); 286 |
287 int64 cacheSet = addressToCacheSet(address); |
288 return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]-> 289 m_Address; 290} 291 292// looks an address up in the cache 293AbstractCacheEntry* 294CacheMemory::lookup(const Address& address) 295{ 296 assert(address == line_address(address)); |
297 int64 cacheSet = addressToCacheSet(address); |
298 int loc = findTagInSet(cacheSet, address); 299 if(loc == -1) return NULL; 300 return m_cache[cacheSet][loc]; 301} 302 303// looks an address up in the cache 304const AbstractCacheEntry* 305CacheMemory::lookup(const Address& address) const 306{ 307 assert(address == line_address(address)); |
308 int64 cacheSet = addressToCacheSet(address); |
309 int loc = findTagInSet(cacheSet, address); 310 if(loc == -1) return NULL; 311 return m_cache[cacheSet][loc]; 312} 313 314// Sets the most recently used bit for a cache block 315void 316CacheMemory::setMRU(const Address& address) 317{ |
318 int64 cacheSet = addressToCacheSet(address); |
319 int loc = findTagInSet(cacheSet, address); 320 321 if(loc != -1) 322 m_replacementPolicy_ptr->touch(cacheSet, loc, curTick()); 323} 324 325void 326CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const --- 59 unchanged lines hidden (view full) --- 386 out << "printData() not supported" << endl; 387} 388 389void 390CacheMemory::setLocked(const Address& address, int context) 391{ 392 DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context); 393 assert(address == line_address(address)); |
394 int64 cacheSet = addressToCacheSet(address); |
395 int loc = findTagInSet(cacheSet, address); 396 assert(loc != -1); 397 m_cache[cacheSet][loc]->m_locked = context; 398} 399 400void 401CacheMemory::clearLocked(const Address& address) 402{ 403 DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address); 404 assert(address == line_address(address)); |
405 int64 cacheSet = addressToCacheSet(address); |
406 int loc = findTagInSet(cacheSet, address); 407 assert(loc != -1); 408 m_cache[cacheSet][loc]->m_locked = -1; 409} 410 411bool 412CacheMemory::isLocked(const Address& address, int context) 413{ 414 assert(address == line_address(address)); |
415 int64 cacheSet = addressToCacheSet(address); |
416 int loc = findTagInSet(cacheSet, address); 417 assert(loc != -1); 418 DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n", 419 address, m_cache[cacheSet][loc]->m_locked, context); 420 return m_cache[cacheSet][loc]->m_locked == context; 421} 422 423void --- 142 unchanged lines hidden --- |