Deleted Added
sdiff udiff text old ( 11034:a89984ca7d15 ) new ( 11049:dfb0aa3f0649 )
full compact
1/*
2 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

--- 84 unchanged lines hidden (view full) ---

93 for (int i = 0; i < m_cache_num_sets; i++) {
94 for (int j = 0; j < m_cache_assoc; j++) {
95 delete m_cache[i][j];
96 }
97 }
98}
99
100// convert a Address to its location in the cache
101int64_t
102CacheMemory::addressToCacheSet(Addr address) const
103{
104 assert(address == makeLineAddress(address));
105 return bitSelect(address, m_start_index_bit,
106 m_start_index_bit + m_cache_num_set_bits - 1);
107}
108
109// Given a cache index: returns the index of the tag in a set.
110// returns -1 if the tag is not found.
111int
112CacheMemory::findTagInSet(int64_t cacheSet, Addr tag) const
113{
114 assert(tag == makeLineAddress(tag));
115 // search the set for the tags
116 m5::hash_map<Addr, int>::const_iterator it = m_tag_index.find(tag);
117 if (it != m_tag_index.end())
118 if (m_cache[cacheSet][it->second]->m_Permission !=
119 AccessPermission_NotPresent)
120 return it->second;
121 return -1; // Not found
122}
123
124// Given a cache index: returns the index of the tag in a set.
125// returns -1 if the tag is not found.
126int
127CacheMemory::findTagInSetIgnorePermissions(int64_t cacheSet,
128 Addr tag) const
129{
130 assert(tag == makeLineAddress(tag));
131 // search the set for the tags
132 m5::hash_map<Addr, int>::const_iterator it = m_tag_index.find(tag);
133 if (it != m_tag_index.end())
134 return it->second;
135 return -1; // Not found

--- 17 unchanged lines hidden (view full) ---

153 if (entry == NULL ||
154 entry->m_Permission == AccessPermission_Invalid ||
155 entry->m_Permission == AccessPermission_NotPresent) {
156 return tmp;
157 }
158 return entry->m_Address;
159}
160
161// tests to see if an address is present in the cache
162bool
163CacheMemory::isTagPresent(Addr address) const
164{
165 assert(address == makeLineAddress(address));
166 int64_t cacheSet = addressToCacheSet(address);
167 int loc = findTagInSet(cacheSet, address);
168
169 if (loc == -1) {
170 // We didn't find the tag
171 DPRINTF(RubyCache, "No tag match for address: %s\n", address);
172 return false;
173 }
174 DPRINTF(RubyCache, "address: %s found\n", address);
175 return true;
176}
177
178// Returns true if there is:
179// a) a tag match on this address or there is
180// b) an unused line in the same cache "way"
181bool
182CacheMemory::cacheAvail(Addr address) const
183{
184 assert(address == makeLineAddress(address));
185
186 int64_t cacheSet = addressToCacheSet(address);
187
188 for (int i = 0; i < m_cache_assoc; i++) {
189 AbstractCacheEntry* entry = m_cache[cacheSet][i];
190 if (entry != NULL) {
191 if (entry->m_Address == address ||
192 entry->m_Permission == AccessPermission_NotPresent) {
193 // Already in the cache or we found an empty entry
194 return true;
195 }
196 } else {
197 return true;
198 }
199 }
200 return false;
201}
202
203AbstractCacheEntry*
204CacheMemory::allocate(Addr address, AbstractCacheEntry *entry, bool touch)
205{
206 assert(address == makeLineAddress(address));
207 assert(!isTagPresent(address));
208 assert(cacheAvail(address));
209 DPRINTF(RubyCache, "address: %s\n", address);
210
211 // Find the first open slot
212 int64_t cacheSet = addressToCacheSet(address);
213 std::vector<AbstractCacheEntry*> &set = m_cache[cacheSet];
214 for (int i = 0; i < m_cache_assoc; i++) {
215 if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) {
216 set[i] = entry; // Init entry
217 set[i]->m_Address = address;
218 set[i]->m_Permission = AccessPermission_Invalid;
219 DPRINTF(RubyCache, "Allocate clearing lock for addr: %x\n",
220 address);
221 set[i]->m_locked = -1;
222 m_tag_index[address] = i;
223 entry->setSetIndex(cacheSet);
224 entry->setWayIndex(i);
225
226 if (touch) {
227 m_replacementPolicy_ptr->touch(cacheSet, i, curTick());
228 }
229
230 return entry;
231 }
232 }
233 panic("Allocate didn't find an available entry");
234}
235
236void
237CacheMemory::deallocate(Addr address)
238{
239 assert(address == makeLineAddress(address));
240 assert(isTagPresent(address));
241 DPRINTF(RubyCache, "address: %s\n", address);
242 int64_t cacheSet = addressToCacheSet(address);
243 int loc = findTagInSet(cacheSet, address);
244 if (loc != -1) {
245 delete m_cache[cacheSet][loc];
246 m_cache[cacheSet][loc] = NULL;
247 m_tag_index.erase(address);
248 }
249}
250
251// Returns with the physical address of the conflicting cache line
252Addr
253CacheMemory::cacheProbe(Addr address) const
254{
255 assert(address == makeLineAddress(address));
256 assert(!cacheAvail(address));
257
258 int64_t cacheSet = addressToCacheSet(address);
259 return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->
260 m_Address;
261}
262
263// looks an address up in the cache
264AbstractCacheEntry*
265CacheMemory::lookup(Addr address)
266{
267 assert(address == makeLineAddress(address));
268 int64_t cacheSet = addressToCacheSet(address);
269 int loc = findTagInSet(cacheSet, address);
270 if(loc == -1) return NULL;
271 return m_cache[cacheSet][loc];
272}
273
274// looks an address up in the cache
275const AbstractCacheEntry*
276CacheMemory::lookup(Addr address) const
277{
278 assert(address == makeLineAddress(address));
279 int64_t cacheSet = addressToCacheSet(address);
280 int loc = findTagInSet(cacheSet, address);
281 if(loc == -1) return NULL;
282 return m_cache[cacheSet][loc];
283}
284
285// Sets the most recently used bit for a cache block
286void
287CacheMemory::setMRU(Addr address)
288{
289 int64_t cacheSet = addressToCacheSet(address);
290 int loc = findTagInSet(cacheSet, address);
291
292 if(loc != -1)
293 m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
294}
295
296void
297CacheMemory::setMRU(const AbstractCacheEntry *e)
298{
299 uint32_t cacheSet = e->getSetIndex();
300 uint32_t loc = e->getWayIndex();
301 m_replacementPolicy_ptr->touch(cacheSet, loc, curTick());
302}
303
304void
305CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const
306{
307 uint64_t warmedUpBlocks = 0;
308 uint64_t totalBlocks M5_VAR_USED = (uint64_t)m_cache_num_sets *
309 (uint64_t)m_cache_assoc;
310
311 for (int i = 0; i < m_cache_num_sets; i++) {
312 for (int j = 0; j < m_cache_assoc; j++) {
313 if (m_cache[i][j] != NULL) {
314 AccessPermission perm = m_cache[i][j]->m_Permission;
315 RubyRequestType request_type = RubyRequestType_NULL;
316 if (perm == AccessPermission_Read_Only) {
317 if (m_is_instruction_only_cache) {

--- 13 unchanged lines hidden (view full) ---

331 warmedUpBlocks++;
332 }
333 }
334 }
335 }
336
337 DPRINTF(RubyCacheTrace, "%s: %lli blocks of %lli total blocks"
338 "recorded %.2f%% \n", name().c_str(), warmedUpBlocks,
339 totalBlocks, (float(warmedUpBlocks) / float(totalBlocks)) * 100.0);
340}
341
342void
343CacheMemory::print(ostream& out) const
344{
345 out << "Cache dump: " << name() << endl;
346 for (int i = 0; i < m_cache_num_sets; i++) {
347 for (int j = 0; j < m_cache_assoc; j++) {

--- 16 unchanged lines hidden (view full) ---

364 out << "printData() not supported" << endl;
365}
366
367void
368CacheMemory::setLocked(Addr address, int context)
369{
370 DPRINTF(RubyCache, "Setting Lock for addr: %x to %d\n", address, context);
371 assert(address == makeLineAddress(address));
372 int64_t cacheSet = addressToCacheSet(address);
373 int loc = findTagInSet(cacheSet, address);
374 assert(loc != -1);
375 m_cache[cacheSet][loc]->setLocked(context);
376}
377
378void
379CacheMemory::clearLocked(Addr address)
380{
381 DPRINTF(RubyCache, "Clear Lock for addr: %x\n", address);
382 assert(address == makeLineAddress(address));
383 int64_t cacheSet = addressToCacheSet(address);
384 int loc = findTagInSet(cacheSet, address);
385 assert(loc != -1);
386 m_cache[cacheSet][loc]->clearLocked();
387}
388
389bool
390CacheMemory::isLocked(Addr address, int context)
391{
392 assert(address == makeLineAddress(address));
393 int64_t cacheSet = addressToCacheSet(address);
394 int loc = findTagInSet(cacheSet, address);
395 assert(loc != -1);
396 DPRINTF(RubyCache, "Testing Lock for addr: %llx cur %d con %d\n",
397 address, m_cache[cacheSet][loc]->m_locked, context);
398 return m_cache[cacheSet][loc]->isLocked(context);
399}
400
401void
402CacheMemory::regStats()
403{
404 m_demand_hits
405 .name(name() + ".demand_hits")
406 .desc("Number of cache demand hits")

--- 141 unchanged lines hidden (view full) ---

548 }
549 } else {
550 assert(false);
551 return true;
552 }
553}
554
555bool
556CacheMemory::isBlockInvalid(int64_t cache_set, int64_t loc)
557{
558 return (m_cache[cache_set][loc]->m_Permission == AccessPermission_Invalid);
559}
560
561bool
562CacheMemory::isBlockNotBusy(int64_t cache_set, int64_t loc)
563{
564 return (m_cache[cache_set][loc]->m_Permission != AccessPermission_Busy);
565}