gem5  v20.1.0.0
smmu_v3_caches.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 2018-2019 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
39 
40 #include <numeric>
41 
42 #include "base/bitfield.hh"
43 #include "base/intmath.hh"
44 #include "base/logging.hh"
45 #include "sim/stats.hh"
46 
47 
48 // taken from hex expansion of pi
49 #define SMMUTLB_SEED 0xEA752DFE
50 #define ARMARCHTLB_SEED 0x8B021FA1
51 #define IPACACHE_SEED 0xE5A0CC0F
52 #define CONFIGCACHE_SEED 0xB56F74E8
53 #define WALKCACHE_SEED 0x18ACF3D6
54 
55 /*
56  * BaseCache
57  *
58  * TODO: move more code into this base class to reduce duplication.
59  */
60 
61 SMMUv3BaseCache::SMMUv3BaseCache(const std::string &policy_name, uint32_t seed) :
62  replacementPolicy(decodePolicyName(policy_name)),
63  nextToReplace(0),
64  random(seed),
65  useStamp(0)
66 {}
67 
68 int
69 SMMUv3BaseCache::decodePolicyName(const std::string &policy_name)
70 {
71  if (policy_name == "rr") {
73  } else if (policy_name == "rand") {
75  } else if (policy_name == "lru") {
76  return SMMU_CACHE_REPL_LRU;
77  } else {
78  panic("Unknown cache replacement policy '%s'\n", policy_name);
79  }
80 }
81 
82 void
83 SMMUv3BaseCache::regStats(const std::string &name)
84 {
85  using namespace Stats;
86 
87 
89  .name(name + ".averageLookups")
90  .desc("Average number lookups per second")
91  .flags(pdf);
92 
94  .name(name + ".totalLookups")
95  .desc("Total number of lookups")
96  .flags(pdf);
97 
99 
100 
102  .name(name + ".averageMisses")
103  .desc("Average number misses per second")
104  .flags(pdf);
105 
107  .name(name + ".totalMisses")
108  .desc("Total number of misses")
109  .flags(pdf);
110 
112 
113 
115  .name(name + ".averageUpdates")
116  .desc("Average number updates per second")
117  .flags(pdf);
118 
120  .name(name + ".totalUpdates")
121  .desc("Total number of updates")
122  .flags(pdf);
123 
125 
126 
128  .name(name + ".averageHitRate")
129  .desc("Average hit rate")
130  .flags(pdf);
131 
133 
134  insertions
135  .name(name + ".insertions")
136  .desc("Number of insertions (not replacements)")
137  .flags(pdf);
138 }
139 
140 
141 
142 /*
143  * SMMUTLB
144  */
145 
146 SMMUTLB::SMMUTLB(unsigned numEntries, unsigned _associativity,
147  const std::string &policy)
148 :
149  SMMUv3BaseCache(policy, SMMUTLB_SEED),
150  associativity(_associativity)
151 {
152  if (associativity == 0)
153  associativity = numEntries; // fully associative
154 
155  if (numEntries == 0)
156  fatal("SMMUTLB must have at least one entry\n");
157 
158  if (associativity > numEntries)
159  fatal("SMMUTLB associativity cannot be higher than "
160  "its number of entries\n");
161 
162  unsigned num_sets = numEntries / associativity;
163 
164  if (num_sets*associativity != numEntries)
165  fatal("Number of SMMUTLB entries must be divisible "
166  "by its associativity\n");
167 
168  Entry e;
169  e.valid = false;
170 
171  Set set(associativity, e);
172  sets.resize(num_sets, set);
173 }
174 
175 const SMMUTLB::Entry*
176 SMMUTLB::lookup(uint32_t sid, uint32_t ssid,
177  Addr va, bool updStats)
178 {
179  const Entry *result = NULL;
180 
181  Set &set = sets[pickSetIdx(va)];
182 
183  for (size_t i = 0; i < set.size(); i++) {
184  const Entry &e = set[i];
185 
186  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
187  e.sid==sid && e.ssid==ssid)
188  {
189  if (result != NULL)
190  panic("SMMUTLB: duplicate entry found!\n");
191 
192  result = &e;
193  break;
194  }
195  }
196 
197  if (updStats) {
198  if (result)
199  result->lastUsed = useStamp++;
200 
201  totalLookups++;
202  if (result == NULL)
203  totalMisses++;
204  }
205 
206  return result;
207 }
208 
209 const SMMUTLB::Entry*
210 SMMUTLB::lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats)
211 {
212  const Entry *result = NULL;
213 
214  for (size_t s = 0; s < sets.size(); s++) {
215  Set &set = sets[s];
216 
217  for (size_t i = 0; i < set.size(); i++) {
218  const Entry &e = set[i];
219 
220  if (e.valid && e.sid==sid && e.ssid==ssid) {
221  result = &e;
222  break;
223  }
224  }
225  }
226 
227  if (updStats) {
228  totalLookups++;
229  if (result == NULL)
230  totalMisses++;
231  }
232 
233  return result;
234 }
235 
236 void
237 SMMUTLB::store(const Entry &incoming, AllocPolicy alloc)
238 {
239  if (!incoming.valid)
240  panic("Tried to store an invalid entry\n");
241 
242  incoming.lastUsed = 0;
243 
244  const Entry *existing =
245  lookup(incoming.sid, incoming.ssid, incoming.va, false);
246 
247  if (existing) {
248  *const_cast<Entry *> (existing) = incoming;
249  } else {
250  Set &set = sets[pickSetIdx(incoming.va)];
251  set[pickEntryIdxToReplace(set, alloc)] = incoming;
252  }
253 
254  totalUpdates++;
255 }
256 
257 void
258 SMMUTLB::invalidateSSID(uint32_t sid, uint32_t ssid)
259 {
260  Set &set = sets[pickSetIdx(sid, ssid)];
261 
262  for (size_t i = 0; i < set.size(); i++) {
263  Entry &e = set[i];
264 
265  if (e.sid == sid && e.ssid == ssid)
266  e.valid = false;
267  }
268 }
269 
270 void
272 {
273  for (size_t s = 0; s < sets.size(); s++) {
274  Set &set = sets[s];
275 
276  for (size_t i = 0; i < set.size(); i++) {
277  Entry &e = set[i];
278 
279  if (e.sid == sid)
280  e.valid = false;
281  }
282  }
283 }
284 
285 void
286 SMMUTLB::invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
287 {
288  Set &set = sets[pickSetIdx(va)];
289 
290  for (size_t i = 0; i < set.size(); i++) {
291  Entry &e = set[i];
292 
293  if ((e.va & e.vaMask) == (va & e.vaMask) &&
294  e.asid==asid && e.vmid==vmid)
295  {
296  e.valid = false;
297  }
298  }
299 }
300 
301 void
303 {
304  Set &set = sets[pickSetIdx(va)];
305 
306  for (size_t i = 0; i < set.size(); i++) {
307  Entry &e = set[i];
308 
309  if ((e.va & e.vaMask) == (va & e.vaMask) && e.vmid==vmid)
310  e.valid = false;
311  }
312 }
313 
314 void
315 SMMUTLB::invalidateASID(uint16_t asid, uint16_t vmid)
316 {
317  for (size_t s = 0; s < sets.size(); s++) {
318  Set &set = sets[s];
319 
320  for (size_t i = 0; i < set.size(); i++) {
321  Entry &e = set[i];
322 
323  if (e.asid==asid && e.vmid==vmid)
324  e.valid = false;
325  }
326  }
327 }
328 
329 void
331 {
332  for (size_t s = 0; s < sets.size(); s++) {
333  Set &set = sets[s];
334 
335  for (size_t i = 0; i < set.size(); i++) {
336  Entry &e = set[i];
337 
338  if (e.vmid == vmid)
339  e.valid = false;
340  }
341  }
342 }
343 
344 void
346 {
347  for (size_t s = 0; s < sets.size(); s++) {
348  Set &set = sets[s];
349 
350  for (size_t i = 0; i < set.size(); i++)
351  set[i].valid = false;
352  }
353 }
354 
355 size_t
357 {
358  return (va >> 12) % sets.size();
359 }
360 
361 size_t
362 SMMUTLB::pickSetIdx(uint32_t sid, uint32_t ssid) const
363 {
364  return (sid^ssid) % sets.size();
365 }
366 
367 size_t
369 {
370  if (alloc == ALLOC_LAST_WAY)
371  return associativity - 1;
372 
373  uint32_t lru_tick = UINT32_MAX;
374  size_t lru_idx = 0;
375  size_t max_idx =
376  alloc==ALLOC_ANY_BUT_LAST_WAY ?
377  set.size()-1 : set.size();
378 
379  for (size_t i = 0; i < max_idx; i++) {
380  if (!set[i].valid) {
381  insertions++;
382  return i;
383  }
384 
385  if (set[i].lastUsed < lru_tick) {
386  lru_idx = i;
387  lru_tick = set[i].lastUsed;
388  }
389  }
390 
391  switch (replacementPolicy) {
393  switch (alloc) {
394  case ALLOC_ANY_WAY:
395  return nextToReplace = ((nextToReplace+1) % associativity);
397  return nextToReplace = ((nextToReplace+1) % (associativity-1));
398  default:
399  panic("Unknown allocation mode %d\n", alloc);
400  }
401 
403  switch (alloc) {
404  case ALLOC_ANY_WAY:
405  return random.random<size_t>(0, associativity-1);
407  return random.random<size_t>(0, associativity-2);
408  default:
409  panic("Unknown allocation mode %d\n", alloc);
410  }
411 
412  case SMMU_CACHE_REPL_LRU:
413  return lru_idx;
414 
415  default:
416  panic("Unknown replacement policy %d\n", replacementPolicy);
417  }
418 }
419 
420 
421 
422 /*
423  * ARMArchTLB
424  */
425 
426 ARMArchTLB::ARMArchTLB(unsigned numEntries, unsigned _associativity,
427  const std::string &policy)
428 :
430  associativity(_associativity)
431 {
432  if (associativity == 0)
433  associativity = numEntries; // fully associative
434 
435  if (numEntries == 0)
436  fatal("ARMArchTLB must have at least one entry\n");
437 
438  if (associativity > numEntries)
439  fatal("ARMArchTLB associativity cannot be higher than "
440  "its number of entries\n");
441 
442  unsigned num_sets = numEntries / associativity;
443 
444  if (num_sets*associativity != numEntries)
445  fatal("Number of ARMArchTLB entries must be divisible "
446  "by its associativity\n");
447 
448  Entry e;
449  e.valid = false;
450 
451  Set set(associativity, e);
452  sets.resize(num_sets, set);
453 }
454 
455 const ARMArchTLB::Entry *
456 ARMArchTLB::lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats)
457 {
458  const Entry *result = NULL;
459 
460  Set &set = sets[pickSetIdx(va, asid, vmid)];
461 
462  for (size_t i = 0; i < set.size(); i++) {
463  const Entry &e = set[i];
464 
465  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
466  e.asid==asid && e.vmid==vmid)
467  {
468  if (result != NULL)
469  panic("ARMArchTLB: duplicate entry found!\n");
470 
471  result = &e;
472  break;
473  }
474  }
475 
476  if (updStats) {
477  if (result)
478  result->lastUsed = useStamp++;
479 
480  totalLookups++;
481  if (result == NULL)
482  totalMisses++;
483  }
484 
485  return result;
486 }
487 
488 void
489 ARMArchTLB::store(const Entry &incoming)
490 {
491  if (!incoming.valid)
492  panic("Tried to store an invalid entry\n");
493 
494  incoming.lastUsed = 0;
495 
496  const Entry *existing =
497  lookup(incoming.va, incoming.asid, incoming.vmid, false);
498 
499  if (existing) {
500  *const_cast<Entry *> (existing) = incoming;
501  } else {
502  Set &set = sets[pickSetIdx(incoming.va, incoming.asid, incoming.vmid)];
503  set[pickEntryIdxToReplace(set)] = incoming;
504  }
505 
506  totalUpdates++;
507 }
508 
509 void
510 ARMArchTLB::invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
511 {
512  Set &set = sets[pickSetIdx(va, asid, vmid)];
513 
514  for (size_t i = 0; i < set.size(); i++) {
515  Entry &e = set[i];
516 
517  if ((e.va & e.vaMask) == (va & e.vaMask) &&
518  e.asid==asid && e.vmid==vmid)
519  {
520  e.valid = false;
521  }
522  }
523 }
524 
525 void
527 {
528  for (size_t s = 0; s < sets.size(); s++) {
529  Set &set = sets[s];
530 
531  for (size_t i = 0; i < set.size(); i++) {
532  Entry &e = set[i];
533 
534  if ((e.va & e.vaMask) == (va & e.vaMask) && e.vmid==vmid)
535  e.valid = false;
536  }
537  }
538 }
539 
540 void
541 ARMArchTLB::invalidateASID(uint16_t asid, uint16_t vmid)
542 {
543  for (size_t s = 0; s < sets.size(); s++) {
544  Set &set = sets[s];
545 
546  for (size_t i = 0; i < set.size(); i++) {
547  Entry &e = set[i];
548 
549  if (e.asid==asid && e.vmid==vmid)
550  e.valid = false;
551  }
552  }
553 }
554 
555 void
557 {
558  for (size_t s = 0; s < sets.size(); s++) {
559  Set &set = sets[s];
560 
561  for (size_t i = 0; i < set.size(); i++) {
562  Entry &e = set[i];
563 
564  if (e.vmid == vmid)
565  e.valid = false;
566  }
567  }
568 }
569 
570 void
572 {
573  for (size_t s = 0; s < sets.size(); s++) {
574  Set &set = sets[s];
575 
576  for (size_t i = 0; i < set.size(); i++)
577  set[i].valid = false;
578  }
579 }
580 
581 size_t
582 ARMArchTLB::pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
583 {
584  return ((va >> 12) ^ asid ^ vmid) % sets.size();
585 }
586 
587 size_t
589 {
590  size_t lru_idx = 0;
591  uint32_t lru_tick = UINT32_MAX;
592 
593  for (size_t i = 0; i < set.size(); i++) {
594  if (!set[i].valid) {
595  insertions++;
596  return i;
597  }
598 
599  if (set[i].lastUsed < lru_tick) {
600  lru_idx = i;
601  lru_tick = set[i].lastUsed;
602  }
603  }
604 
605  switch (replacementPolicy) {
607  return nextToReplace = ((nextToReplace+1) % associativity);
608 
610  return random.random<size_t>(0, associativity-1);
611 
612  case SMMU_CACHE_REPL_LRU:
613  return lru_idx;
614 
615  default:
616  panic("Unknown replacement policy %d\n", replacementPolicy);
617  }
618 
619 }
620 
621 /*
622  * IPACache
623  */
624 
625 IPACache::IPACache(unsigned numEntries, unsigned _associativity,
626  const std::string &policy)
627 :
629  associativity(_associativity)
630 {
631  if (associativity == 0)
632  associativity = numEntries; // fully associative
633 
634  if (numEntries == 0)
635  fatal("IPACache must have at least one entry\n");
636 
637  if (associativity > numEntries)
638  fatal("IPACache associativity cannot be higher than "
639  "its number of entries\n");
640 
641  unsigned num_sets = numEntries / associativity;
642 
643  if (num_sets*associativity != numEntries)
644  fatal("Number of IPACache entries must be divisible "
645  "by its associativity\n");
646 
647  Entry e;
648  e.valid = false;
649 
650  Set set(associativity, e);
651  sets.resize(num_sets, set);
652 }
653 
654 const IPACache::Entry*
655 IPACache::lookup(Addr ipa, uint16_t vmid, bool updStats)
656 {
657  const Entry *result = NULL;
658 
659  Set &set = sets[pickSetIdx(ipa, vmid)];
660 
661  for (size_t i = 0; i < set.size(); i++) {
662  const Entry &e = set[i];
663 
664  if (e.valid && (e.ipa & e.ipaMask) == (ipa & e.ipaMask) &&
665  e.vmid==vmid)
666  {
667  if (result != NULL)
668  panic("IPACache: duplicate entry found!\n");
669 
670  result = &e;
671  break;
672  }
673  }
674 
675  if (updStats) {
676  if (result)
677  result->lastUsed = useStamp++;
678 
679  totalLookups++;
680  if (result == NULL)
681  totalMisses++;
682  }
683 
684  return result;
685 }
686 
687 void
688 IPACache::store(const Entry &incoming)
689 {
690  if (!incoming.valid)
691  panic("Tried to store an invalid entry\n");
692 
693  incoming.lastUsed = 0;
694 
695  const Entry *existing = lookup(incoming.ipa, incoming.vmid, false);
696 
697  if (existing) {
698  *const_cast<Entry *> (existing) = incoming;
699  } else {
700  Set &set = sets[pickSetIdx(incoming.ipa, incoming.vmid)];
701  set[pickEntryIdxToReplace(set)] = incoming;
702  }
703 
704  totalUpdates++;
705 }
706 
707 void
708 IPACache::invalidateIPA(Addr ipa, uint16_t vmid)
709 {
710  Set &set = sets[pickSetIdx(ipa, vmid)];
711 
712  for (size_t i = 0; i < set.size(); i++) {
713  Entry &e = set[i];
714 
715  if ((e.ipa & e.ipaMask) == (ipa & e.ipaMask) && e.vmid==vmid)
716  e.valid = false;
717  }
718 }
719 
720 void
722 {
723  for (size_t s = 0; s < sets.size(); s++) {
724  Set &set = sets[s];
725 
726  for (size_t i = 0; i < set.size(); i++) {
727  Entry &e = set[i];
728 
729  if ((e.ipa & e.ipaMask) == (ipa & e.ipaMask))
730  e.valid = false;
731  }
732  }
733 }
734 
735 void
737 {
738  for (size_t s = 0; s < sets.size(); s++) {
739  Set &set = sets[s];
740 
741  for (size_t i = 0; i < set.size(); i++) {
742  Entry &e = set[i];
743 
744  if (e.vmid == vmid)
745  e.valid = false;
746  }
747  }
748 }
749 
750 void
752 {
753  for (size_t s = 0; s < sets.size(); s++) {
754  Set &set = sets[s];
755 
756  for (size_t i = 0; i < set.size(); i++)
757  set[i].valid = false;
758  }
759 }
760 
761 size_t
762 IPACache::pickSetIdx(Addr va, uint16_t vmid) const
763 {
764  return ((va >> 12) ^ vmid) % sets.size();
765 }
766 
767 size_t
769 {
770  size_t lru_idx = 0;
771  uint32_t lru_tick = UINT32_MAX;
772 
773  for (size_t i = 0; i < set.size(); i++) {
774  if (!set[i].valid) {
775  insertions++;
776  return i;
777  }
778 
779  if (set[i].lastUsed < lru_tick) {
780  lru_idx = i;
781  lru_tick = set[i].lastUsed;
782  }
783  }
784 
785  switch (replacementPolicy) {
787  return nextToReplace = ((nextToReplace+1) % associativity);
788 
790  return random.random<size_t>(0, associativity-1);
791 
792  case SMMU_CACHE_REPL_LRU:
793  return lru_idx;
794 
795  default:
796  panic("Unknown replacement policy %d\n", replacementPolicy);
797  }
798 
799 }
800 
801 /*
802  * ConfigCache
803  */
804 
805 ConfigCache::ConfigCache(unsigned numEntries, unsigned _associativity,
806  const std::string &policy)
807 :
809  associativity(_associativity)
810 {
811  if (associativity == 0)
812  associativity = numEntries; // fully associative
813 
814  if (numEntries == 0)
815  fatal("ConfigCache must have at least one entry\n");
816 
817  if (associativity > numEntries)
818  fatal("ConfigCache associativity cannot be higher than "
819  "its number of entries\n");
820 
821  unsigned num_sets = numEntries / associativity;
822 
823  if (num_sets*associativity != numEntries)
824  fatal("Number of ConfigCache entries must be divisible "
825  "by its associativity\n");
826 
827  Entry e;
828  e.valid = false;
829 
830  Set set(associativity, e);
831  sets.resize(num_sets, set);
832 }
833 
834 const ConfigCache::Entry *
835 ConfigCache::lookup(uint32_t sid, uint32_t ssid, bool updStats)
836 {
837  const Entry *result = NULL;
838 
839  Set &set = sets[pickSetIdx(sid, ssid)];
840 
841  for (size_t i = 0; i < set.size(); i++) {
842  const Entry &e = set[i];
843 
844  if (e.valid && e.sid==sid && e.ssid==ssid)
845  {
846  if (result != NULL)
847  panic("ConfigCache: duplicate entry found!\n");
848 
849  result = &e;
850  break;
851  }
852  }
853 
854  if (updStats) {
855  if (result)
856  result->lastUsed = useStamp++;
857 
858  totalLookups++;
859  if (result == NULL)
860  totalMisses++;
861  }
862 
863  return result;
864 }
865 
866 void
867 ConfigCache::store(const Entry &incoming)
868 {
869  if (!incoming.valid)
870  panic("Tried to store an invalid entry\n");
871 
872  incoming.lastUsed = 0;
873 
874  const Entry *existing = lookup(incoming.sid, incoming.ssid, false);
875 
876  if (existing) {
877  *const_cast<Entry *> (existing) = incoming;
878  } else {
879  Set &set = sets[pickSetIdx(incoming.sid, incoming.ssid)];
880  set[pickEntryIdxToReplace(set)] = incoming;
881  }
882 
883  totalUpdates++;
884 }
885 
886 void
887 ConfigCache::invalidateSSID(uint32_t sid, uint32_t ssid)
888 {
889  Set &set = sets[pickSetIdx(sid, ssid)];
890 
891  for (size_t i = 0; i < set.size(); i++) {
892  Entry &e = set[i];
893 
894  if (e.sid==sid && e.ssid==ssid)
895  e.valid = false;
896  }
897 }
898 
899 void
901 {
902  for (size_t s = 0; s < sets.size(); s++) {
903  Set &set = sets[s];
904 
905  for (size_t i = 0; i < set.size(); i++) {
906  Entry &e = set[i];
907 
908  if (e.sid == sid)
909  e.valid = false;
910  }
911  }
912 }
913 
914 void
916 {
917  for (size_t s = 0; s < sets.size(); s++) {
918  Set &set = sets[s];
919 
920  for (size_t i = 0; i < set.size(); i++)
921  set[i].valid = false;
922  }
923 }
924 
925 size_t
926 ConfigCache::pickSetIdx(uint32_t sid, uint32_t ssid) const
927 {
928  return (sid^ssid) % sets.size();
929 }
930 
931 size_t
933 {
934  size_t lru_idx = 0;
935  uint32_t lru_tick = UINT32_MAX;
936 
937  for (size_t i = 0; i < set.size(); i++) {
938  if (!set[i].valid) {
939  insertions++;
940  return i;
941  }
942 
943  if (set[i].lastUsed < lru_tick) {
944  lru_idx = i;
945  lru_tick = set[i].lastUsed;
946  }
947  }
948 
949  switch (replacementPolicy) {
951  return nextToReplace = ((nextToReplace+1) % associativity);
952 
954  return random.random<size_t>(0, associativity-1);
955 
956  case SMMU_CACHE_REPL_LRU:
957  return lru_idx;
958 
959  default:
960  panic("Unknown replacement policy %d\n", replacementPolicy);
961  }
962 
963 }
964 
965 /*
966  * WalkCache
967  */
968 
969 WalkCache::WalkCache(const std::array<unsigned, 2*WALK_CACHE_LEVELS> &_sizes,
970  unsigned _associativity, const std::string &policy) :
972  associativity(_associativity),
973  sizes()
974 {
975  unsigned numEntries = std::accumulate(&_sizes[0],
976  &_sizes[2*WALK_CACHE_LEVELS], 0);
977 
978  if (associativity == 0)
979  associativity = numEntries; // fully associative
980 
981  if (numEntries == 0)
982  fatal("WalkCache must have at least one entry\n");
983 
984  for (size_t i = 0; i < 2*WALK_CACHE_LEVELS; i++){
985  if (_sizes[i] % associativity != 0)
986  fatal("Number of WalkCache entries at each level must be "
987  "divisible by WalkCache associativity\n");
988 
989  sizes[i] = _sizes[i] / associativity;
990  offsets[i] = i==0 ? 0 : offsets[i-1] + sizes[i-1];
991  }
992 
993  if (associativity > numEntries)
994  fatal("WalkCache associativity cannot be higher than "
995  "its number of entries\n");
996 
997  unsigned num_sets = numEntries / associativity;
998 
999  if (num_sets*associativity != numEntries)
1000  fatal("Number of WalkCache entries must be divisible "
1001  "by its associativity\n");
1002 
1003  Entry e;
1004  e.valid = false;
1005 
1006  Set set(associativity, e);
1007  sets.resize(num_sets, set);
1008 }
1009 
1010 const WalkCache::Entry*
1012  uint16_t asid, uint16_t vmid,
1013  unsigned stage, unsigned level,
1014  bool updStats)
1015 {
1016  const Entry *result = NULL;
1017 
1018  Set &set = sets[pickSetIdx(va, vaMask, stage, level)];
1019 
1020  for (size_t i = 0; i < set.size(); i++) {
1021  const Entry &e = set[i];
1022 
1023  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
1024  e.asid==asid && e.vmid==vmid && e.stage==stage && e.level==level)
1025  {
1026  if (result != NULL)
1027  panic("WalkCache: duplicate entry found!\n");
1028 
1029  result = &e;
1030  break;
1031  }
1032  }
1033 
1034  if (updStats) {
1035  if (result)
1036  result->lastUsed = useStamp++;
1037 
1038  totalLookups++;
1039  if (result == NULL)
1040  totalMisses++;
1041 
1042  lookupsByStageLevel[stage-1][level]++;
1043  totalLookupsByStageLevel[stage-1][level]++;
1044  if (result == NULL) {
1045  missesByStageLevel[stage-1][level]++;
1046  totalMissesByStageLevel[stage-1][level]++;
1047  }
1048  }
1049 
1050  return result;
1051 }
1052 
1053 void
1054 WalkCache::store(const Entry &incoming)
1055 {
1056  if (!incoming.valid)
1057  panic("Tried to store an invalid entry\n");
1058 
1059  assert(incoming.stage==1 || incoming.stage==2);
1060  assert(incoming.level<=WALK_CACHE_LEVELS);
1061 
1062  incoming.lastUsed = 0;
1063 
1064  const Entry *existing = lookup(incoming.va, incoming.vaMask,
1065  incoming.asid, incoming.vmid,
1066  incoming.stage, incoming.level, false);
1067 
1068  if (existing) {
1069  *const_cast<Entry *> (existing) = incoming;
1070  } else {
1071  Set &set = sets[pickSetIdx(incoming.va, incoming.vaMask,
1072  incoming.stage, incoming.level)];
1073  set[pickEntryIdxToReplace(set, incoming.stage, incoming.level)] =
1074  incoming;
1075  }
1076 
1077  totalUpdates++;
1078  updatesByStageLevel[incoming.stage-1][incoming.level]++;
1079  totalUpdatesByStageLevel[incoming.stage-1][incoming.level]++;
1080 }
1081 
1082 void
1083 WalkCache::invalidateVA(Addr va, uint16_t asid, uint16_t vmid,
1084  const bool leaf_only)
1085 {
1086  for (size_t s = 0; s < sets.size(); s++) {
1087  Set &set = sets[s];
1088 
1089  for (size_t i = 0; i < set.size(); i++) {
1090  Entry &e = set[i];
1091 
1092  if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
1093  && e.asid == asid && e.vmid == vmid)
1094  {
1095  e.valid = false;
1096  }
1097  }
1098  }
1099 }
1100 
1101 void
1102 WalkCache::invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
1103 {
1104  for (size_t s = 0; s < sets.size(); s++) {
1105  Set &set = sets[s];
1106 
1107  for (size_t i = 0; i < set.size(); i++) {
1108  Entry &e = set[i];
1109 
1110  if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
1111  && e.vmid == vmid)
1112  {
1113  e.valid = false;
1114  }
1115  }
1116  }
1117 }
1118 
1119 void
1120 WalkCache::invalidateASID(uint16_t asid, uint16_t vmid)
1121 {
1122  for (size_t s = 0; s < sets.size(); s++) {
1123  Set &set = sets[s];
1124 
1125  for (size_t i = 0; i < set.size(); i++) {
1126  Entry &e = set[i];
1127 
1128  if (e.asid==asid && e.vmid==vmid)
1129  e.valid = false;
1130  }
1131  }
1132 }
1133 
1134 void
1136 {
1137  for (size_t s = 0; s < sets.size(); s++) {
1138  Set &set = sets[s];
1139 
1140  for (size_t i = 0; i < set.size(); i++) {
1141  Entry &e = set[i];
1142 
1143  if (e.vmid == vmid)
1144  e.valid = false;
1145  }
1146  }
1147 }
1148 
1149 void
1151 {
1152  for (size_t s = 0; s < sets.size(); s++) {
1153  Set &set = sets[s];
1154 
1155  for (size_t i = 0; i < set.size(); i++)
1156  set[i].valid = false;
1157  }
1158 }
1159 
1160 size_t
1162  unsigned stage, unsigned level) const
1163 {
1164  (void) stage;
1165 
1166  int size, offset;
1167 
1168  switch (stage) {
1169  case 1:
1170  assert (level<=3);
1171  size = sizes[0*WALK_CACHE_LEVELS + level];
1173  break;
1174 
1175  case 2:
1176  assert (level<=3);
1177  size = sizes[1*WALK_CACHE_LEVELS + level];
1179  break;
1180 
1181  default:
1182  panic("bad stage");
1183  }
1184 
1185  return ((va >> findLsbSet(vaMask)) % size) + offset;
1186 }
1187 
1188 size_t
1190  unsigned stage, unsigned level)
1191 {
1192  size_t lru_idx = 0;
1193  uint32_t lru_tick = UINT32_MAX;
1194 
1195  for (size_t i = 0; i < set.size(); i++) {
1196  if (!set[i].valid) {
1197  insertions++;
1198  insertionsByStageLevel[stage-1][level]++;
1199  return i;
1200  }
1201 
1202  if (set[i].lastUsed < lru_tick) {
1203  lru_idx = i;
1204  lru_tick = set[i].lastUsed;
1205  }
1206  }
1207 
1208  switch (replacementPolicy) {
1210  return nextToReplace = ((nextToReplace+1) % associativity);
1211 
1213  return random.random<size_t>(0, associativity-1);
1214 
1215  case SMMU_CACHE_REPL_LRU:
1216  return lru_idx;
1217 
1218  default:
1219  panic("Unknown replacement policy %d\n", replacementPolicy);
1220  }
1221 
1222 }
1223 
1224 void
1225 WalkCache::regStats(const std::string &name)
1226 {
1227  using namespace Stats;
1228 
1230 
1231  for (int s = 0; s < 2; s++) {
1232  for (int l = 0; l < WALK_CACHE_LEVELS; l++) {
1234  .name(csprintf("%s.averageLookupsS%dL%d", name, s+1, l))
1235  .desc("Average number lookups per second")
1236  .flags(pdf);
1237 
1239  .name(csprintf("%s.totalLookupsS%dL%d", name, s+1, l))
1240  .desc("Total number of lookups")
1241  .flags(pdf);
1242 
1245 
1246 
1248  .name(csprintf("%s.averageMissesS%dL%d", name, s+1, l))
1249  .desc("Average number misses per second")
1250  .flags(pdf);
1251 
1253  .name(csprintf("%s.totalMissesS%dL%d", name, s+1, l))
1254  .desc("Total number of misses")
1255  .flags(pdf);
1256 
1259 
1260 
1262  .name(csprintf("%s.averageUpdatesS%dL%d", name, s+1, l))
1263  .desc("Average number updates per second")
1264  .flags(pdf);
1265 
1267  .name(csprintf("%s.totalUpdatesS%dL%d", name, s+1, l))
1268  .desc("Total number of updates")
1269  .flags(pdf);
1270 
1273 
1274 
1276  .name(csprintf("%s.averageHitRateS%dL%d", name, s+1, l))
1277  .desc("Average hit rate")
1278  .flags(pdf);
1279 
1284 
1286  .name(csprintf("%s.insertionsS%dL%d", name, s+1, l))
1287  .desc("Number of insertions (not replacements)")
1288  .flags(pdf);
1289  }
1290  }
1291 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
WalkCache::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:287
IPACache::invalidateIPAA
void invalidateIPAA(Addr ipa)
Definition: smmu_v3_caches.cc:721
SMMUTLB::lookup
const Entry * lookup(uint32_t sid, uint32_t ssid, Addr va, bool updStats=true)
Definition: smmu_v3_caches.cc:176
SMMUv3BaseCache::totalLookups
Stats::Scalar totalLookups
Definition: smmu_v3_caches.hh:69
SMMU_CACHE_REPL_ROUND_ROBIN
@ SMMU_CACHE_REPL_ROUND_ROBIN
Definition: smmu_v3_caches.hh:55
CONFIGCACHE_SEED
#define CONFIGCACHE_SEED
Definition: smmu_v3_caches.cc:52
IPACache::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:200
SMMUv3BaseCache::averageLookups
Stats::Formula averageLookups
Definition: smmu_v3_caches.hh:68
WalkCache::lookup
const Entry * lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid, unsigned stage, unsigned level, bool updStats=true)
Definition: smmu_v3_caches.cc:1011
ConfigCache::invalidateSSID
void invalidateSSID(uint32_t sid, uint32_t ssid)
Definition: smmu_v3_caches.cc:887
WalkCache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:286
WalkCache::pickSetIdx
size_t pickSetIdx(Addr va, Addr vaMask, unsigned stage, unsigned level) const
Definition: smmu_v3_caches.cc:1161
IPACache::lookup
const Entry * lookup(Addr ipa, uint16_t vmid, bool updStats=true)
Definition: smmu_v3_caches.cc:655
WalkCache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:339
WalkCache::Entry::level
unsigned level
Definition: smmu_v3_caches.hh:295
SMMU_CACHE_REPL_RANDOM
@ SMMU_CACHE_REPL_RANDOM
Definition: smmu_v3_caches.hh:56
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
IPACache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:688
IPACache::invalidateIPA
void invalidateIPA(Addr ipa, uint16_t vmid)
Definition: smmu_v3_caches.cc:708
WALKCACHE_SEED
#define WALKCACHE_SEED
Definition: smmu_v3_caches.cc:53
SMMUTLB::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:141
ARMArchTLB::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:162
SMMUv3BaseCache::averageMisses
Stats::Formula averageMisses
Definition: smmu_v3_caches.hh:71
ARMArchTLB::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:155
SMMUv3BaseCache
Definition: smmu_v3_caches.hh:60
SMMUTLB::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:330
ConfigCache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:275
WalkCache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:1054
WalkCache::missesByStageLevel
unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:325
WalkCache::lookupsByStageLevel
unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:321
WalkCache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:1150
std::vector< Entry >
WalkCache::Entry
Definition: smmu_v3_caches.hh:284
ConfigCache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:867
SMMUTLB::pickSetIdx
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Definition: smmu_v3_caches.cc:362
SMMUv3BaseCache::useStamp
uint32_t useStamp
Definition: smmu_v3_caches.hh:66
WalkCache::sizes
std::array< unsigned, 2 *WALK_CACHE_LEVELS > sizes
Definition: smmu_v3_caches.hh:342
SMMUTLB::Entry::va
Addr va
Definition: smmu_v3_caches.hh:108
ARMArchTLB::lookup
const Entry * lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats=true)
Definition: smmu_v3_caches.cc:456
SMMUTLB::invalidateSSID
void invalidateSSID(uint32_t sid, uint32_t ssid)
Definition: smmu_v3_caches.cc:258
WalkCache::Entry::vaMask
Addr vaMask
Definition: smmu_v3_caches.hh:291
WalkCache::Entry::asid
uint16_t asid
Definition: smmu_v3_caches.hh:292
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:331
WalkCache::averageMissesByStageLevel
Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:326
SMMUTLB::Entry
Definition: smmu_v3_caches.hh:99
SMMUTLB::invalidateVA
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:286
SMMU_CACHE_REPL_LRU
@ SMMU_CACHE_REPL_LRU
Definition: smmu_v3_caches.hh:57
SMMUTLB::ALLOC_ANY_WAY
@ ALLOC_ANY_WAY
Definition: smmu_v3_caches.hh:94
WalkCache::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
Definition: smmu_v3_caches.cc:1102
IPACache::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:205
IPACache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:228
IPACache::Entry
Definition: smmu_v3_caches.hh:197
SMMUTLB::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:345
stats.hh
WalkCache::totalUpdatesByStageLevel
Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:331
SMMUTLB::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid)
Definition: smmu_v3_caches.cc:302
SMMUTLB::AllocPolicy
AllocPolicy
Definition: smmu_v3_caches.hh:93
WALK_CACHE_LEVELS
#define WALK_CACHE_LEVELS
Definition: smmu_v3_caches.hh:52
WalkCache::invalidateVA
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid, const bool leaf_only)
Definition: smmu_v3_caches.cc:1083
SMMUv3BaseCache::nextToReplace
size_t nextToReplace
Definition: smmu_v3_caches.hh:64
SMMUv3BaseCache::random
Random random
Definition: smmu_v3_caches.hh:65
bitfield.hh
ARMArchTLB::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:156
IPACache::IPACache
IPACache(unsigned numEntries, unsigned _associativity, const std::string &policy)
Definition: smmu_v3_caches.cc:625
SMMUTLB::ALLOC_ANY_BUT_LAST_WAY
@ ALLOC_ANY_BUT_LAST_WAY
Definition: smmu_v3_caches.hh:95
SMMUTLB::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:103
SMMUTLB::invalidateASID
void invalidateASID(uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:315
WalkCache::Entry::stage
unsigned stage
Definition: smmu_v3_caches.hh:294
simSeconds
Stats::Formula simSeconds
Definition: stat_control.cc:61
SMMUv3BaseCache::averageUpdates
Stats::Formula averageUpdates
Definition: smmu_v3_caches.hh:74
SMMUv3BaseCache::totalUpdates
Stats::Scalar totalUpdates
Definition: smmu_v3_caches.hh:75
ConfigCache::Entry::sid
uint32_t sid
Definition: smmu_v3_caches.hh:243
IPACACHE_SEED
#define IPACACHE_SEED
Definition: smmu_v3_caches.cc:51
SMMUv3BaseCache::insertions
Stats::Scalar insertions
Definition: smmu_v3_caches.hh:79
IPACache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:751
WalkCache::WalkCache
WalkCache(const std::array< unsigned, 2 *WALK_CACHE_LEVELS > &_sizes, unsigned _associativity, const std::string &policy)
Definition: smmu_v3_caches.cc:969
ConfigCache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:239
SMMUTLB::ALLOC_LAST_WAY
@ ALLOC_LAST_WAY
Definition: smmu_v3_caches.hh:96
WalkCache::averageHitRateByStageLevel
Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:333
ConfigCache::lookup
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
Definition: smmu_v3_caches.cc:835
ARMArchTLB::ARMArchTLB
ARMArchTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
Definition: smmu_v3_caches.cc:426
ARMArchTLB::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:489
ConfigCache::Entry::ssid
uint32_t ssid
Definition: smmu_v3_caches.hh:244
ARMArchTLB::Entry
Definition: smmu_v3_caches.hh:153
IPACache::Entry::ipa
Addr ipa
Definition: smmu_v3_caches.hh:203
ConfigCache::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:932
IPACache::pickSetIdx
size_t pickSetIdx(Addr ipa, uint16_t vmid) const
Definition: smmu_v3_caches.cc:762
IPACache::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:768
WalkCache::totalLookupsByStageLevel
Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:323
SMMUTLB::SMMUTLB
SMMUTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
Definition: smmu_v3_caches.cc:146
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Stats::DataWrap::name
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:274
WalkCache::averageLookupsByStageLevel
Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:322
name
const std::string & name()
Definition: trace.cc:50
ConfigCache::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:240
WalkCache::insertionsByStageLevel
Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:335
WalkCache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:341
ARMArchTLB::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:588
WalkCache::regStats
void regStats(const std::string &name) override
Definition: smmu_v3_caches.cc:1225
WalkCache::Entry::va
Addr va
Definition: smmu_v3_caches.hh:290
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
IPACache::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:736
ArmISA::asid
asid
Definition: miscregs_types.hh:611
WalkCache::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set, unsigned stage, unsigned level)
Definition: smmu_v3_caches.cc:1189
WalkCache::invalidateASID
void invalidateASID(uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:1120
ConfigCache::invalidateSID
void invalidateSID(uint32_t sid)
Definition: smmu_v3_caches.cc:900
ConfigCache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:273
X86ISA::level
Bitfield< 20 > level
Definition: intmessage.hh:47
smmu_v3_caches.hh
ARMArchTLB::invalidateASID
void invalidateASID(uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:541
ConfigCache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:915
SMMUTLB::Entry::ssid
uint32_t ssid
Definition: smmu_v3_caches.hh:107
IPACache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:199
ARMArchTLB::Entry::asid
uint16_t asid
Definition: smmu_v3_caches.hh:161
SMMUTLB::store
void store(const Entry &incoming, AllocPolicy alloc)
Definition: smmu_v3_caches.cc:237
SMMUTLB::invalidateSID
void invalidateSID(uint32_t sid)
Definition: smmu_v3_caches.cc:271
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:51
SMMUv3BaseCache::replacementPolicy
int replacementPolicy
Definition: smmu_v3_caches.hh:63
ARMARCHTLB_SEED
#define ARMARCHTLB_SEED
Definition: smmu_v3_caches.cc:50
SMMUv3BaseCache::decodePolicyName
static int decodePolicyName(const std::string &policy_name)
Definition: smmu_v3_caches.cc:69
ARMArchTLB::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid)
Definition: smmu_v3_caches.cc:526
SMMUv3BaseCache::totalMisses
Stats::Scalar totalMisses
Definition: smmu_v3_caches.hh:72
SMMUTLB::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc)
Definition: smmu_v3_caches.cc:368
SMMUv3BaseCache::SMMUv3BaseCache
SMMUv3BaseCache(const std::string &policy_name, uint32_t seed)
Definition: smmu_v3_caches.cc:61
ARMArchTLB::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:186
IPACache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:226
ARMArchTLB::Entry::va
Addr va
Definition: smmu_v3_caches.hh:159
logging.hh
SMMUTLB_SEED
#define SMMUTLB_SEED
Definition: smmu_v3_caches.cc:49
ARMArchTLB::associativity
size_t associativity
Definition: smmu_v3_caches.hh:188
Random::random
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:86
SMMUTLB::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:101
ARMArchTLB::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:571
WalkCache::averageUpdatesByStageLevel
Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:330
Stats
Definition: statistics.cc:61
WalkCache::offsets
std::array< unsigned, 2 *WALK_CACHE_LEVELS > offsets
Definition: smmu_v3_caches.hh:343
ARMArchTLB::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:556
ARMArchTLB::pickSetIdx
size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
Definition: smmu_v3_caches.cc:582
MipsISA::random
random
Definition: pra_constants.hh:50
ConfigCache::ConfigCache
ConfigCache(unsigned numEntries, unsigned _associativity, const std::string &policy)
Definition: smmu_v3_caches.cc:805
findLsbSet
int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Definition: bitfield.hh:253
SMMUv3BaseCache::averageHitRate
Stats::Formula averageHitRate
Definition: smmu_v3_caches.hh:77
WalkCache::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:293
ARMArchTLB::invalidateVA
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:510
SMMUTLB::Entry::sid
uint32_t sid
Definition: smmu_v3_caches.hh:106
WalkCache::updatesByStageLevel
unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:329
SMMUv3BaseCache::regStats
virtual void regStats(const std::string &name)
Definition: smmu_v3_caches.cc:83
intmath.hh
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
SMMUTLB::associativity
size_t associativity
Definition: smmu_v3_caches.hh:143
ConfigCache::pickSetIdx
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Definition: smmu_v3_caches.cc:926
MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:320
Stats::DataWrap::desc
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:307
ConfigCache::Entry
Definition: smmu_v3_caches.hh:237
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
ArmISA::va
Bitfield< 8 > va
Definition: miscregs_types.hh:272
WalkCache::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:1135
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
WalkCache::totalMissesByStageLevel
Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS]
Definition: smmu_v3_caches.hh:327
SMMUTLB::lookupAnyVA
const Entry * lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats=true)
Definition: smmu_v3_caches.cc:210

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17