CacheMemory.cc (10301:44839e8febbd) CacheMemory.cc (10314:94b6b28fc968)
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
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
107Index
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
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(Index cacheSet, const Address& tag) const
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
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(Index cacheSet,
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);
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 Index cacheSet = addressToCacheSet(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);
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 Index cacheSet = addressToCacheSet(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));
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 Index cacheSet = addressToCacheSet(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
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 Index cacheSet = addressToCacheSet(address);
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
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 Index cacheSet = addressToCacheSet(address);
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);
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 Index cacheSet = addressToCacheSet(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
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 Index cacheSet = addressToCacheSet(address);
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));
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 Index cacheSet = addressToCacheSet(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));
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 Index cacheSet = addressToCacheSet(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{
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 Index cacheSet = addressToCacheSet(address);
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));
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 Index cacheSet = addressToCacheSet(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));
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 Index cacheSet = addressToCacheSet(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));
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 Index cacheSet = addressToCacheSet(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 ---
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 ---