gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
smmu_v3_caches.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 2018-2019, 2021 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  Stats::Group *parent, const std::string &name)
63  : replacementPolicy(decodePolicyName(policy_name)),
64  nextToReplace(0),
65  random(seed),
66  useStamp(0),
67  baseCacheStats(parent, name)
68 {}
69 
70 int
71 SMMUv3BaseCache::decodePolicyName(const std::string &policy_name)
72 {
73  if (policy_name == "rr") {
75  } else if (policy_name == "rand") {
77  } else if (policy_name == "lru") {
78  return SMMU_CACHE_REPL_LRU;
79  } else {
80  panic("Unknown cache replacement policy '%s'\n", policy_name);
81  }
82 }
83 
86  Stats::Group *parent, const std::string &name)
87  : Stats::Group(parent, name.c_str()),
88  ADD_STAT(averageLookups,
89  UNIT_RATE(Stats::Units::Count, Stats::Units::Second),
90  "Average number lookups per second"),
91  ADD_STAT(totalLookups, UNIT_COUNT, "Total number of lookups"),
92  ADD_STAT(averageMisses,
93  UNIT_RATE(Stats::Units::Count, Stats::Units::Second),
94  "Average number misses per second"),
95  ADD_STAT(totalMisses, UNIT_COUNT, "Total number of misses"),
96  ADD_STAT(averageUpdates,
97  UNIT_RATE(Stats::Units::Count, Stats::Units::Second),
98  "Average number updates per second"),
99  ADD_STAT(totalUpdates, UNIT_COUNT, "Total number of updates"),
100  ADD_STAT(averageHitRate, UNIT_RATIO, "Average hit rate"),
101  ADD_STAT(insertions, UNIT_COUNT,
102  "Number of insertions (not replacements)")
103 {
104  using namespace Stats;
105 
106 
108  .flags(pdf);
109 
111  .flags(pdf);
112 
114 
115 
117  .flags(pdf);
118 
120  .flags(pdf);
121 
123 
124 
126  .flags(pdf);
127 
129  .flags(pdf);
130 
132 
133 
135  .flags(pdf);
136 
138 
139  insertions
140  .flags(pdf);
141 }
142 
143 /*
144  * SMMUTLB
145  */
146 
147 SMMUTLB::SMMUTLB(unsigned numEntries, unsigned _associativity,
148  const std::string &policy, Stats::Group *parent,
149  const std::string &name)
150 :
151  SMMUv3BaseCache(policy, SMMUTLB_SEED, parent, name),
152  associativity(_associativity)
153 {
154  if (associativity == 0)
155  associativity = numEntries; // fully associative
156 
157  if (numEntries == 0)
158  fatal("SMMUTLB must have at least one entry\n");
159 
160  if (associativity > numEntries)
161  fatal("SMMUTLB associativity cannot be higher than "
162  "its number of entries\n");
163 
164  unsigned num_sets = numEntries / associativity;
165 
166  if (num_sets*associativity != numEntries)
167  fatal("Number of SMMUTLB entries must be divisible "
168  "by its associativity\n");
169 
170  Entry e;
171  e.valid = false;
172 
173  Set set(associativity, e);
174  sets.resize(num_sets, set);
175 }
176 
177 const SMMUTLB::Entry*
178 SMMUTLB::lookup(uint32_t sid, uint32_t ssid,
179  Addr va, bool updStats)
180 {
181  const Entry *result = NULL;
182 
183  Set &set = sets[pickSetIdx(va)];
184 
185  for (size_t i = 0; i < set.size(); i++) {
186  const Entry &e = set[i];
187 
188  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
189  e.sid==sid && e.ssid==ssid)
190  {
191  if (result != NULL)
192  panic("SMMUTLB: duplicate entry found!\n");
193 
194  result = &e;
195  break;
196  }
197  }
198 
199  if (updStats) {
200  if (result)
201  result->lastUsed = useStamp++;
202 
204  if (result == NULL)
206  }
207 
208  return result;
209 }
210 
211 const SMMUTLB::Entry*
212 SMMUTLB::lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats)
213 {
214  const Entry *result = NULL;
215 
216  for (size_t s = 0; s < sets.size(); s++) {
217  Set &set = sets[s];
218 
219  for (size_t i = 0; i < set.size(); i++) {
220  const Entry &e = set[i];
221 
222  if (e.valid && e.sid==sid && e.ssid==ssid) {
223  result = &e;
224  break;
225  }
226  }
227  }
228 
229  if (updStats) {
231  if (result == NULL)
233  }
234 
235  return result;
236 }
237 
238 void
239 SMMUTLB::store(const Entry &incoming, AllocPolicy alloc)
240 {
241  if (!incoming.valid)
242  panic("Tried to store an invalid entry\n");
243 
244  incoming.lastUsed = 0;
245 
246  const Entry *existing =
247  lookup(incoming.sid, incoming.ssid, incoming.va, false);
248 
249  if (existing) {
250  *const_cast<Entry *> (existing) = incoming;
251  } else {
252  Set &set = sets[pickSetIdx(incoming.va)];
253  set[pickEntryIdxToReplace(set, alloc)] = incoming;
254  }
255 
257 }
258 
259 void
260 SMMUTLB::invalidateSSID(uint32_t sid, uint32_t ssid)
261 {
262  Set &set = sets[pickSetIdx(sid, ssid)];
263 
264  for (size_t i = 0; i < set.size(); i++) {
265  Entry &e = set[i];
266 
267  if (e.sid == sid && e.ssid == ssid)
268  e.valid = false;
269  }
270 }
271 
272 void
274 {
275  for (size_t s = 0; s < sets.size(); s++) {
276  Set &set = sets[s];
277 
278  for (size_t i = 0; i < set.size(); i++) {
279  Entry &e = set[i];
280 
281  if (e.sid == sid)
282  e.valid = false;
283  }
284  }
285 }
286 
287 void
288 SMMUTLB::invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
289 {
290  Set &set = sets[pickSetIdx(va)];
291 
292  for (size_t i = 0; i < set.size(); i++) {
293  Entry &e = set[i];
294 
295  if ((e.va & e.vaMask) == (va & e.vaMask) &&
296  e.asid==asid && e.vmid==vmid)
297  {
298  e.valid = false;
299  }
300  }
301 }
302 
303 void
305 {
306  Set &set = sets[pickSetIdx(va)];
307 
308  for (size_t i = 0; i < set.size(); i++) {
309  Entry &e = set[i];
310 
311  if ((e.va & e.vaMask) == (va & e.vaMask) && e.vmid==vmid)
312  e.valid = false;
313  }
314 }
315 
316 void
317 SMMUTLB::invalidateASID(uint16_t asid, uint16_t vmid)
318 {
319  for (size_t s = 0; s < sets.size(); s++) {
320  Set &set = sets[s];
321 
322  for (size_t i = 0; i < set.size(); i++) {
323  Entry &e = set[i];
324 
325  if (e.asid==asid && e.vmid==vmid)
326  e.valid = false;
327  }
328  }
329 }
330 
331 void
333 {
334  for (size_t s = 0; s < sets.size(); s++) {
335  Set &set = sets[s];
336 
337  for (size_t i = 0; i < set.size(); i++) {
338  Entry &e = set[i];
339 
340  if (e.vmid == vmid)
341  e.valid = false;
342  }
343  }
344 }
345 
346 void
348 {
349  for (size_t s = 0; s < sets.size(); s++) {
350  Set &set = sets[s];
351 
352  for (size_t i = 0; i < set.size(); i++)
353  set[i].valid = false;
354  }
355 }
356 
357 size_t
359 {
360  return (va >> 12) % sets.size();
361 }
362 
363 size_t
364 SMMUTLB::pickSetIdx(uint32_t sid, uint32_t ssid) const
365 {
366  return (sid^ssid) % sets.size();
367 }
368 
369 size_t
371 {
372  if (alloc == ALLOC_LAST_WAY)
373  return associativity - 1;
374 
375  uint32_t lru_tick = UINT32_MAX;
376  size_t lru_idx = 0;
377  size_t max_idx =
378  alloc==ALLOC_ANY_BUT_LAST_WAY ?
379  set.size()-1 : set.size();
380 
381  for (size_t i = 0; i < max_idx; i++) {
382  if (!set[i].valid) {
384  return i;
385  }
386 
387  if (set[i].lastUsed < lru_tick) {
388  lru_idx = i;
389  lru_tick = set[i].lastUsed;
390  }
391  }
392 
393  switch (replacementPolicy) {
395  switch (alloc) {
396  case ALLOC_ANY_WAY:
397  return nextToReplace = ((nextToReplace+1) % associativity);
399  return nextToReplace = ((nextToReplace+1) % (associativity-1));
400  default:
401  panic("Unknown allocation mode %d\n", alloc);
402  }
403 
405  switch (alloc) {
406  case ALLOC_ANY_WAY:
407  return random.random<size_t>(0, associativity-1);
409  return random.random<size_t>(0, associativity-2);
410  default:
411  panic("Unknown allocation mode %d\n", alloc);
412  }
413 
414  case SMMU_CACHE_REPL_LRU:
415  return lru_idx;
416 
417  default:
418  panic("Unknown replacement policy %d\n", replacementPolicy);
419  }
420 }
421 
422 
423 
424 /*
425  * ARMArchTLB
426  */
427 
428 ARMArchTLB::ARMArchTLB(unsigned numEntries, unsigned _associativity,
429  const std::string &policy, Stats::Group *parent)
430 :
431  SMMUv3BaseCache(policy, ARMARCHTLB_SEED, parent, "tlb"),
432  associativity(_associativity)
433 {
434  if (associativity == 0)
435  associativity = numEntries; // fully associative
436 
437  if (numEntries == 0)
438  fatal("ARMArchTLB must have at least one entry\n");
439 
440  if (associativity > numEntries)
441  fatal("ARMArchTLB associativity cannot be higher than "
442  "its number of entries\n");
443 
444  unsigned num_sets = numEntries / associativity;
445 
446  if (num_sets*associativity != numEntries)
447  fatal("Number of ARMArchTLB entries must be divisible "
448  "by its associativity\n");
449 
450  Entry e;
451  e.valid = false;
452 
453  Set set(associativity, e);
454  sets.resize(num_sets, set);
455 }
456 
457 const ARMArchTLB::Entry *
458 ARMArchTLB::lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats)
459 {
460  const Entry *result = NULL;
461 
462  Set &set = sets[pickSetIdx(va, asid, vmid)];
463 
464  for (size_t i = 0; i < set.size(); i++) {
465  const Entry &e = set[i];
466 
467  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
468  e.asid==asid && e.vmid==vmid)
469  {
470  if (result != NULL)
471  panic("ARMArchTLB: duplicate entry found!\n");
472 
473  result = &e;
474  break;
475  }
476  }
477 
478  if (updStats) {
479  if (result)
480  result->lastUsed = useStamp++;
481 
483  if (result == NULL)
485  }
486 
487  return result;
488 }
489 
490 void
491 ARMArchTLB::store(const Entry &incoming)
492 {
493  if (!incoming.valid)
494  panic("Tried to store an invalid entry\n");
495 
496  incoming.lastUsed = 0;
497 
498  const Entry *existing =
499  lookup(incoming.va, incoming.asid, incoming.vmid, false);
500 
501  if (existing) {
502  *const_cast<Entry *> (existing) = incoming;
503  } else {
504  Set &set = sets[pickSetIdx(incoming.va, incoming.asid, incoming.vmid)];
505  set[pickEntryIdxToReplace(set)] = incoming;
506  }
507 
509 }
510 
511 void
512 ARMArchTLB::invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
513 {
514  Set &set = sets[pickSetIdx(va, asid, vmid)];
515 
516  for (size_t i = 0; i < set.size(); i++) {
517  Entry &e = set[i];
518 
519  if ((e.va & e.vaMask) == (va & e.vaMask) &&
520  e.asid==asid && e.vmid==vmid)
521  {
522  e.valid = false;
523  }
524  }
525 }
526 
527 void
529 {
530  for (size_t s = 0; s < sets.size(); s++) {
531  Set &set = sets[s];
532 
533  for (size_t i = 0; i < set.size(); i++) {
534  Entry &e = set[i];
535 
536  if ((e.va & e.vaMask) == (va & e.vaMask) && e.vmid==vmid)
537  e.valid = false;
538  }
539  }
540 }
541 
542 void
543 ARMArchTLB::invalidateASID(uint16_t asid, uint16_t vmid)
544 {
545  for (size_t s = 0; s < sets.size(); s++) {
546  Set &set = sets[s];
547 
548  for (size_t i = 0; i < set.size(); i++) {
549  Entry &e = set[i];
550 
551  if (e.asid==asid && e.vmid==vmid)
552  e.valid = false;
553  }
554  }
555 }
556 
557 void
559 {
560  for (size_t s = 0; s < sets.size(); s++) {
561  Set &set = sets[s];
562 
563  for (size_t i = 0; i < set.size(); i++) {
564  Entry &e = set[i];
565 
566  if (e.vmid == vmid)
567  e.valid = false;
568  }
569  }
570 }
571 
572 void
574 {
575  for (size_t s = 0; s < sets.size(); s++) {
576  Set &set = sets[s];
577 
578  for (size_t i = 0; i < set.size(); i++)
579  set[i].valid = false;
580  }
581 }
582 
583 size_t
584 ARMArchTLB::pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
585 {
586  return ((va >> 12) ^ asid ^ vmid) % sets.size();
587 }
588 
589 size_t
591 {
592  size_t lru_idx = 0;
593  uint32_t lru_tick = UINT32_MAX;
594 
595  for (size_t i = 0; i < set.size(); i++) {
596  if (!set[i].valid) {
598  return i;
599  }
600 
601  if (set[i].lastUsed < lru_tick) {
602  lru_idx = i;
603  lru_tick = set[i].lastUsed;
604  }
605  }
606 
607  switch (replacementPolicy) {
609  return nextToReplace = ((nextToReplace+1) % associativity);
610 
612  return random.random<size_t>(0, associativity-1);
613 
614  case SMMU_CACHE_REPL_LRU:
615  return lru_idx;
616 
617  default:
618  panic("Unknown replacement policy %d\n", replacementPolicy);
619  }
620 
621 }
622 
623 /*
624  * IPACache
625  */
626 
627 IPACache::IPACache(unsigned numEntries, unsigned _associativity,
628  const std::string &policy, Stats::Group *parent)
629 :
630  SMMUv3BaseCache(policy, IPACACHE_SEED, parent, "ipa"),
631  associativity(_associativity)
632 {
633  if (associativity == 0)
634  associativity = numEntries; // fully associative
635 
636  if (numEntries == 0)
637  fatal("IPACache must have at least one entry\n");
638 
639  if (associativity > numEntries)
640  fatal("IPACache associativity cannot be higher than "
641  "its number of entries\n");
642 
643  unsigned num_sets = numEntries / associativity;
644 
645  if (num_sets*associativity != numEntries)
646  fatal("Number of IPACache entries must be divisible "
647  "by its associativity\n");
648 
649  Entry e;
650  e.valid = false;
651 
652  Set set(associativity, e);
653  sets.resize(num_sets, set);
654 }
655 
656 const IPACache::Entry*
657 IPACache::lookup(Addr ipa, uint16_t vmid, bool updStats)
658 {
659  const Entry *result = NULL;
660 
661  Set &set = sets[pickSetIdx(ipa, vmid)];
662 
663  for (size_t i = 0; i < set.size(); i++) {
664  const Entry &e = set[i];
665 
666  if (e.valid && (e.ipa & e.ipaMask) == (ipa & e.ipaMask) &&
667  e.vmid==vmid)
668  {
669  if (result != NULL)
670  panic("IPACache: duplicate entry found!\n");
671 
672  result = &e;
673  break;
674  }
675  }
676 
677  if (updStats) {
678  if (result)
679  result->lastUsed = useStamp++;
680 
682  if (result == NULL)
684  }
685 
686  return result;
687 }
688 
689 void
690 IPACache::store(const Entry &incoming)
691 {
692  if (!incoming.valid)
693  panic("Tried to store an invalid entry\n");
694 
695  incoming.lastUsed = 0;
696 
697  const Entry *existing = lookup(incoming.ipa, incoming.vmid, false);
698 
699  if (existing) {
700  *const_cast<Entry *> (existing) = incoming;
701  } else {
702  Set &set = sets[pickSetIdx(incoming.ipa, incoming.vmid)];
703  set[pickEntryIdxToReplace(set)] = incoming;
704  }
705 
707 }
708 
709 void
710 IPACache::invalidateIPA(Addr ipa, uint16_t vmid)
711 {
712  Set &set = sets[pickSetIdx(ipa, vmid)];
713 
714  for (size_t i = 0; i < set.size(); i++) {
715  Entry &e = set[i];
716 
717  if ((e.ipa & e.ipaMask) == (ipa & e.ipaMask) && e.vmid==vmid)
718  e.valid = false;
719  }
720 }
721 
722 void
724 {
725  for (size_t s = 0; s < sets.size(); s++) {
726  Set &set = sets[s];
727 
728  for (size_t i = 0; i < set.size(); i++) {
729  Entry &e = set[i];
730 
731  if ((e.ipa & e.ipaMask) == (ipa & e.ipaMask))
732  e.valid = false;
733  }
734  }
735 }
736 
737 void
739 {
740  for (size_t s = 0; s < sets.size(); s++) {
741  Set &set = sets[s];
742 
743  for (size_t i = 0; i < set.size(); i++) {
744  Entry &e = set[i];
745 
746  if (e.vmid == vmid)
747  e.valid = false;
748  }
749  }
750 }
751 
752 void
754 {
755  for (size_t s = 0; s < sets.size(); s++) {
756  Set &set = sets[s];
757 
758  for (size_t i = 0; i < set.size(); i++)
759  set[i].valid = false;
760  }
761 }
762 
763 size_t
764 IPACache::pickSetIdx(Addr va, uint16_t vmid) const
765 {
766  return ((va >> 12) ^ vmid) % sets.size();
767 }
768 
769 size_t
771 {
772  size_t lru_idx = 0;
773  uint32_t lru_tick = UINT32_MAX;
774 
775  for (size_t i = 0; i < set.size(); i++) {
776  if (!set[i].valid) {
778  return i;
779  }
780 
781  if (set[i].lastUsed < lru_tick) {
782  lru_idx = i;
783  lru_tick = set[i].lastUsed;
784  }
785  }
786 
787  switch (replacementPolicy) {
789  return nextToReplace = ((nextToReplace+1) % associativity);
790 
792  return random.random<size_t>(0, associativity-1);
793 
794  case SMMU_CACHE_REPL_LRU:
795  return lru_idx;
796 
797  default:
798  panic("Unknown replacement policy %d\n", replacementPolicy);
799  }
800 
801 }
802 
803 /*
804  * ConfigCache
805  */
806 
807 ConfigCache::ConfigCache(unsigned numEntries, unsigned _associativity,
808  const std::string &policy, Stats::Group *parent)
809 :
810  SMMUv3BaseCache(policy, CONFIGCACHE_SEED, parent, "cfg"),
811  associativity(_associativity)
812 {
813  if (associativity == 0)
814  associativity = numEntries; // fully associative
815 
816  if (numEntries == 0)
817  fatal("ConfigCache must have at least one entry\n");
818 
819  if (associativity > numEntries)
820  fatal("ConfigCache associativity cannot be higher than "
821  "its number of entries\n");
822 
823  unsigned num_sets = numEntries / associativity;
824 
825  if (num_sets*associativity != numEntries)
826  fatal("Number of ConfigCache entries must be divisible "
827  "by its associativity\n");
828 
829  Entry e;
830  e.valid = false;
831 
832  Set set(associativity, e);
833  sets.resize(num_sets, set);
834 }
835 
836 const ConfigCache::Entry *
837 ConfigCache::lookup(uint32_t sid, uint32_t ssid, bool updStats)
838 {
839  const Entry *result = NULL;
840 
841  Set &set = sets[pickSetIdx(sid, ssid)];
842 
843  for (size_t i = 0; i < set.size(); i++) {
844  const Entry &e = set[i];
845 
846  if (e.valid && e.sid==sid && e.ssid==ssid)
847  {
848  if (result != NULL)
849  panic("ConfigCache: duplicate entry found!\n");
850 
851  result = &e;
852  break;
853  }
854  }
855 
856  if (updStats) {
857  if (result)
858  result->lastUsed = useStamp++;
859 
861  if (result == NULL)
863  }
864 
865  return result;
866 }
867 
868 void
869 ConfigCache::store(const Entry &incoming)
870 {
871  if (!incoming.valid)
872  panic("Tried to store an invalid entry\n");
873 
874  incoming.lastUsed = 0;
875 
876  const Entry *existing = lookup(incoming.sid, incoming.ssid, false);
877 
878  if (existing) {
879  *const_cast<Entry *> (existing) = incoming;
880  } else {
881  Set &set = sets[pickSetIdx(incoming.sid, incoming.ssid)];
882  set[pickEntryIdxToReplace(set)] = incoming;
883  }
884 
886 }
887 
888 void
889 ConfigCache::invalidateSSID(uint32_t sid, uint32_t ssid)
890 {
891  Set &set = sets[pickSetIdx(sid, ssid)];
892 
893  for (size_t i = 0; i < set.size(); i++) {
894  Entry &e = set[i];
895 
896  if (e.sid==sid && e.ssid==ssid)
897  e.valid = false;
898  }
899 }
900 
901 void
903 {
904  for (size_t s = 0; s < sets.size(); s++) {
905  Set &set = sets[s];
906 
907  for (size_t i = 0; i < set.size(); i++) {
908  Entry &e = set[i];
909 
910  if (e.sid == sid)
911  e.valid = false;
912  }
913  }
914 }
915 
916 void
918 {
919  for (size_t s = 0; s < sets.size(); s++) {
920  Set &set = sets[s];
921 
922  for (size_t i = 0; i < set.size(); i++)
923  set[i].valid = false;
924  }
925 }
926 
927 size_t
928 ConfigCache::pickSetIdx(uint32_t sid, uint32_t ssid) const
929 {
930  return (sid^ssid) % sets.size();
931 }
932 
933 size_t
935 {
936  size_t lru_idx = 0;
937  uint32_t lru_tick = UINT32_MAX;
938 
939  for (size_t i = 0; i < set.size(); i++) {
940  if (!set[i].valid) {
942  return i;
943  }
944 
945  if (set[i].lastUsed < lru_tick) {
946  lru_idx = i;
947  lru_tick = set[i].lastUsed;
948  }
949  }
950 
951  switch (replacementPolicy) {
953  return nextToReplace = ((nextToReplace+1) % associativity);
954 
956  return random.random<size_t>(0, associativity-1);
957 
958  case SMMU_CACHE_REPL_LRU:
959  return lru_idx;
960 
961  default:
962  panic("Unknown replacement policy %d\n", replacementPolicy);
963  }
964 
965 }
966 
967 /*
968  * WalkCache
969  */
970 
971 WalkCache::WalkCache(const std::array<unsigned, 2*WALK_CACHE_LEVELS> &_sizes,
972  unsigned _associativity, const std::string &policy,
973  Stats::Group *parent) :
974  SMMUv3BaseCache(policy, WALKCACHE_SEED, parent, "walk"),
975  walkCacheStats(&(SMMUv3BaseCache::baseCacheStats)),
976  associativity(_associativity),
977  sizes()
978 {
979  unsigned numEntries = std::accumulate(&_sizes[0],
980  &_sizes[2*WALK_CACHE_LEVELS], 0);
981 
982  if (associativity == 0)
983  associativity = numEntries; // fully associative
984 
985  if (numEntries == 0)
986  fatal("WalkCache must have at least one entry\n");
987 
988  for (size_t i = 0; i < 2*WALK_CACHE_LEVELS; i++){
989  if (_sizes[i] % associativity != 0)
990  fatal("Number of WalkCache entries at each level must be "
991  "divisible by WalkCache associativity\n");
992 
993  sizes[i] = _sizes[i] / associativity;
994  offsets[i] = i==0 ? 0 : offsets[i-1] + sizes[i-1];
995  }
996 
997  if (associativity > numEntries)
998  fatal("WalkCache associativity cannot be higher than "
999  "its number of entries\n");
1000 
1001  unsigned num_sets = numEntries / associativity;
1002 
1003  if (num_sets*associativity != numEntries)
1004  fatal("Number of WalkCache entries must be divisible "
1005  "by its associativity\n");
1006 
1007  Entry e;
1008  e.valid = false;
1009 
1010  Set set(associativity, e);
1011  sets.resize(num_sets, set);
1012 }
1013 
1014 const WalkCache::Entry*
1016  uint16_t asid, uint16_t vmid,
1017  unsigned stage, unsigned level,
1018  bool updStats)
1019 {
1020  const Entry *result = NULL;
1021 
1022  Set &set = sets[pickSetIdx(va, vaMask, stage, level)];
1023 
1024  for (size_t i = 0; i < set.size(); i++) {
1025  const Entry &e = set[i];
1026 
1027  if (e.valid && (e.va & e.vaMask) == (va & e.vaMask) &&
1028  e.asid==asid && e.vmid==vmid && e.stage==stage && e.level==level)
1029  {
1030  if (result != NULL)
1031  panic("WalkCache: duplicate entry found!\n");
1032 
1033  result = &e;
1034  break;
1035  }
1036  }
1037 
1038  if (updStats) {
1039  if (result)
1040  result->lastUsed = useStamp++;
1041 
1043  if (result == NULL)
1045 
1047  if (result == NULL) {
1049  }
1050  }
1051 
1052  return result;
1053 }
1054 
1055 void
1056 WalkCache::store(const Entry &incoming)
1057 {
1058  if (!incoming.valid)
1059  panic("Tried to store an invalid entry\n");
1060 
1061  assert(incoming.stage==1 || incoming.stage==2);
1062  assert(incoming.level<=WALK_CACHE_LEVELS);
1063 
1064  incoming.lastUsed = 0;
1065 
1066  const Entry *existing = lookup(incoming.va, incoming.vaMask,
1067  incoming.asid, incoming.vmid,
1068  incoming.stage, incoming.level, false);
1069 
1070  if (existing) {
1071  *const_cast<Entry *> (existing) = incoming;
1072  } else {
1073  Set &set = sets[pickSetIdx(incoming.va, incoming.vaMask,
1074  incoming.stage, incoming.level)];
1075  set[pickEntryIdxToReplace(set, incoming.stage, incoming.level)] =
1076  incoming;
1077  }
1078 
1081  .totalUpdatesByStageLevel[incoming.stage-1][incoming.level]++;
1082 }
1083 
1084 void
1085 WalkCache::invalidateVA(Addr va, uint16_t asid, uint16_t vmid,
1086  const bool leaf_only)
1087 {
1088  for (size_t s = 0; s < sets.size(); s++) {
1089  Set &set = sets[s];
1090 
1091  for (size_t i = 0; i < set.size(); i++) {
1092  Entry &e = set[i];
1093 
1094  if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
1095  && e.asid == asid && e.vmid == vmid)
1096  {
1097  e.valid = false;
1098  }
1099  }
1100  }
1101 }
1102 
1103 void
1104 WalkCache::invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
1105 {
1106  for (size_t s = 0; s < sets.size(); s++) {
1107  Set &set = sets[s];
1108 
1109  for (size_t i = 0; i < set.size(); i++) {
1110  Entry &e = set[i];
1111 
1112  if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
1113  && e.vmid == vmid)
1114  {
1115  e.valid = false;
1116  }
1117  }
1118  }
1119 }
1120 
1121 void
1122 WalkCache::invalidateASID(uint16_t asid, uint16_t vmid)
1123 {
1124  for (size_t s = 0; s < sets.size(); s++) {
1125  Set &set = sets[s];
1126 
1127  for (size_t i = 0; i < set.size(); i++) {
1128  Entry &e = set[i];
1129 
1130  if (e.asid==asid && e.vmid==vmid)
1131  e.valid = false;
1132  }
1133  }
1134 }
1135 
1136 void
1138 {
1139  for (size_t s = 0; s < sets.size(); s++) {
1140  Set &set = sets[s];
1141 
1142  for (size_t i = 0; i < set.size(); i++) {
1143  Entry &e = set[i];
1144 
1145  if (e.vmid == vmid)
1146  e.valid = false;
1147  }
1148  }
1149 }
1150 
1151 void
1153 {
1154  for (size_t s = 0; s < sets.size(); s++) {
1155  Set &set = sets[s];
1156 
1157  for (size_t i = 0; i < set.size(); i++)
1158  set[i].valid = false;
1159  }
1160 }
1161 
1162 size_t
1164  unsigned stage, unsigned level) const
1165 {
1166  (void) stage;
1167 
1168  int size, offset;
1169 
1170  switch (stage) {
1171  case 1:
1172  assert (level<=3);
1173  size = sizes[0*WALK_CACHE_LEVELS + level];
1175  break;
1176 
1177  case 2:
1178  assert (level<=3);
1179  size = sizes[1*WALK_CACHE_LEVELS + level];
1181  break;
1182 
1183  default:
1184  panic("bad stage");
1185  }
1186 
1187  return ((va >> findLsbSet(vaMask)) % size) + offset;
1188 }
1189 
1190 size_t
1192  unsigned stage, unsigned level)
1193 {
1194  size_t lru_idx = 0;
1195  uint32_t lru_tick = UINT32_MAX;
1196 
1197  for (size_t i = 0; i < set.size(); i++) {
1198  if (!set[i].valid) {
1201  return i;
1202  }
1203 
1204  if (set[i].lastUsed < lru_tick) {
1205  lru_idx = i;
1206  lru_tick = set[i].lastUsed;
1207  }
1208  }
1209 
1210  switch (replacementPolicy) {
1212  return nextToReplace = ((nextToReplace+1) % associativity);
1213 
1215  return random.random<size_t>(0, associativity-1);
1216 
1217  case SMMU_CACHE_REPL_LRU:
1218  return lru_idx;
1219 
1220  default:
1221  panic("Unknown replacement policy %d\n", replacementPolicy);
1222  }
1223 
1224 }
1225 
1228  : Stats::Group(parent),
1229  ADD_STAT(totalLookupsByStageLevel, UNIT_COUNT,
1230  "Total number of lookups"),
1231  ADD_STAT(totalMissesByStageLevel, UNIT_COUNT,
1232  "Total number of misses"),
1233  ADD_STAT(totalUpdatesByStageLevel, UNIT_COUNT,
1234  "Total number of updates"),
1235  ADD_STAT(insertionsByStageLevel, UNIT_COUNT,
1236  "Number of insertions (not replacements)")
1237 {
1238  using namespace Stats;
1239 
1241  .init(2, WALK_CACHE_LEVELS)
1242  .flags(pdf);
1244  .init(2, WALK_CACHE_LEVELS)
1245  .flags(pdf);
1247  .init(2, WALK_CACHE_LEVELS)
1248  .flags(pdf);
1250  .init(2, WALK_CACHE_LEVELS)
1251  .flags(pdf);
1252 
1253  for (int s = 0; s < 2; s++) {
1255  totalMissesByStageLevel.subname(s, csprintf("S%d", s + 1));
1257  insertionsByStageLevel.subname(s, csprintf("S%d", s + 1));
1258 
1259  for (int l = 0; l < WALK_CACHE_LEVELS; l++) {
1264 
1265  auto avg_lookup = new Stats::Formula(
1266  this,
1267  csprintf("averageLookups_S%dL%d", s+1, l).c_str(),
1269  "Average number lookups per second");
1270  avg_lookup->flags(pdf);
1271  averageLookupsByStageLevel.push_back(avg_lookup);
1272 
1273  *avg_lookup =
1275 
1276  auto avg_misses = new Stats::Formula(
1277  this,
1278  csprintf("averageMisses_S%dL%d", s+1, l).c_str(),
1280  "Average number misses per second");
1281  avg_misses->flags(pdf);
1282  averageMissesByStageLevel.push_back(avg_misses);
1283 
1284  *avg_misses =
1286 
1287  auto avg_updates = new Stats::Formula(
1288  this,
1289  csprintf("averageUpdates_S%dL%d", s+1, l).c_str(),
1291  "Average number updates per second");
1292  avg_updates->flags(pdf);
1293  averageUpdatesByStageLevel.push_back(avg_updates);
1294 
1295  *avg_updates =
1297 
1298  auto avg_hitrate = new Stats::Formula(
1299  this,
1300  csprintf("averageHitRate_S%dL%d", s+1, l).c_str(),
1301  UNIT_RATIO,
1302  "Average hit rate");
1303  avg_hitrate->flags(pdf);
1304  averageHitRateByStageLevel.push_back(avg_hitrate);
1305 
1306  *avg_hitrate =
1310 
1311  }
1312  }
1313 }
1314 
1317 {
1318  for (auto avg_lookup : averageLookupsByStageLevel)
1319  delete avg_lookup;
1320 
1321  for (auto avg_miss : averageMissesByStageLevel)
1322  delete avg_miss;
1323 
1324  for (auto avg_update : averageUpdatesByStageLevel)
1325  delete avg_update;
1326 
1327  for (auto avg_hitrate : averageHitRateByStageLevel)
1328  delete avg_hitrate;
1329 }
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:292
IPACache::invalidateIPAA
void invalidateIPAA(Addr ipa)
Definition: smmu_v3_caches.cc:723
SMMUTLB::lookup
const Entry * lookup(uint32_t sid, uint32_t ssid, Addr va, bool updStats=true)
Definition: smmu_v3_caches.cc:178
CONFIGCACHE_SEED
#define CONFIGCACHE_SEED
Definition: smmu_v3_caches.cc:52
IPACache::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:205
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:1015
ConfigCache::invalidateSSID
void invalidateSSID(uint32_t sid, uint32_t ssid)
Definition: smmu_v3_caches.cc:889
WalkCache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:291
WalkCache::pickSetIdx
size_t pickSetIdx(Addr va, Addr vaMask, unsigned stage, unsigned level) const
Definition: smmu_v3_caches.cc:1163
IPACache::lookup
const Entry * lookup(Addr ipa, uint16_t vmid, bool updStats=true)
Definition: smmu_v3_caches.cc:657
WalkCache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:345
SMMUv3BaseCache::SMMUv3BaseCache
SMMUv3BaseCache(const std::string &policy_name, uint32_t seed, Stats::Group *parent, const std::string &name)
Definition: smmu_v3_caches.cc:61
WalkCache::Entry::level
unsigned level
Definition: smmu_v3_caches.hh:300
IPACache::IPACache
IPACache(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
Definition: smmu_v3_caches.cc:627
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
IPACache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:690
IPACache::invalidateIPA
void invalidateIPA(Addr ipa, uint16_t vmid)
Definition: smmu_v3_caches.cc:710
WALKCACHE_SEED
#define WALKCACHE_SEED
Definition: smmu_v3_caches.cc:53
SMMUTLB::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:146
ARMArchTLB::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:167
ARMArchTLB::ARMArchTLB
ARMArchTLB(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
Definition: smmu_v3_caches.cc:428
ARMArchTLB::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:160
SMMU_CACHE_REPL_RANDOM
@ SMMU_CACHE_REPL_RANDOM
Definition: smmu_v3_caches.hh:56
SMMUv3BaseCache::SMMUv3BaseCacheStats::SMMUv3BaseCacheStats
SMMUv3BaseCacheStats(Stats::Group *parent, const std::string &name)
Definition: smmu_v3_caches.cc:85
SMMUv3BaseCache
Definition: smmu_v3_caches.hh:60
Stats::DataWrapVec2d::ysubname
Derived & ysubname(off_type index, const std::string &subname)
Definition: statistics.hh:471
WalkCache::WalkCacheStats::WalkCacheStats
WalkCacheStats(Stats::Group *parent)
Definition: smmu_v3_caches.cc:1227
ConfigCache::ConfigCache
ConfigCache(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
Definition: smmu_v3_caches.cc:807
SMMUTLB::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:332
ConfigCache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:280
SMMUv3BaseCache::SMMUv3BaseCacheStats::totalUpdates
Stats::Scalar totalUpdates
Definition: smmu_v3_caches.hh:79
WalkCache::WalkCacheStats::insertionsByStageLevel
Stats::Vector2d insertionsByStageLevel
Definition: smmu_v3_caches.hh:341
WalkCache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:1056
WalkCache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:1152
std::vector< Entry >
SMMUTLB::SMMUTLB
SMMUTLB(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent, const std::string &name)
Definition: smmu_v3_caches.cc:147
WalkCache::Entry
Definition: smmu_v3_caches.hh:289
ConfigCache::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:869
SMMUTLB::pickSetIdx
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Definition: smmu_v3_caches.cc:364
WalkCache::WalkCacheStats::totalUpdatesByStageLevel
Stats::Vector2d totalUpdatesByStageLevel
Definition: smmu_v3_caches.hh:337
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:348
SMMUTLB::Entry::va
Addr va
Definition: smmu_v3_caches.hh:112
ARMArchTLB::lookup
const Entry * lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats=true)
Definition: smmu_v3_caches.cc:458
SMMUTLB::invalidateSSID
void invalidateSSID(uint32_t sid, uint32_t ssid)
Definition: smmu_v3_caches.cc:260
SMMU_CACHE_REPL_LRU
@ SMMU_CACHE_REPL_LRU
Definition: smmu_v3_caches.hh:57
WalkCache::Entry::vaMask
Addr vaMask
Definition: smmu_v3_caches.hh:296
WalkCache::Entry::asid
uint16_t asid
Definition: smmu_v3_caches.hh:297
Random::random
std::enable_if_t< std::is_integral< T >::value, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:86
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:339
SMMUTLB::Entry
Definition: smmu_v3_caches.hh:103
Stats::Units::Second
Definition: units.hh:133
SMMUTLB::invalidateVA
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:288
SMMUTLB::ALLOC_ANY_WAY
@ ALLOC_ANY_WAY
Definition: smmu_v3_caches.hh:98
WalkCache::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
Definition: smmu_v3_caches.cc:1104
IPACache::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:210
IPACache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:233
IPACache::Entry
Definition: smmu_v3_caches.hh:202
SMMUTLB::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:347
stats.hh
SMMUTLB::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid)
Definition: smmu_v3_caches.cc:304
SMMUTLB::AllocPolicy
AllocPolicy
Definition: smmu_v3_caches.hh:97
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:1085
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:161
SMMUTLB::ALLOC_ANY_BUT_LAST_WAY
@ ALLOC_ANY_BUT_LAST_WAY
Definition: smmu_v3_caches.hh:99
SMMUTLB::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:107
SMMUTLB::invalidateASID
void invalidateASID(uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:317
WalkCache::Entry::stage
unsigned stage
Definition: smmu_v3_caches.hh:299
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
WalkCache::WalkCache
WalkCache(const std::array< unsigned, 2 *WALK_CACHE_LEVELS > &_sizes, unsigned _associativity, const std::string &policy, Stats::Group *parent)
Definition: smmu_v3_caches.cc:971
ConfigCache::Entry::sid
uint32_t sid
Definition: smmu_v3_caches.hh:248
IPACACHE_SEED
#define IPACACHE_SEED
Definition: smmu_v3_caches.cc:51
IPACache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:753
ConfigCache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:244
SMMUTLB::ALLOC_LAST_WAY
@ ALLOC_LAST_WAY
Definition: smmu_v3_caches.hh:100
WalkCache::WalkCacheStats::totalLookupsByStageLevel
Stats::Vector2d totalLookupsByStageLevel
Definition: smmu_v3_caches.hh:331
ConfigCache::lookup
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
Definition: smmu_v3_caches.cc:837
ARMArchTLB::store
void store(const Entry &incoming)
Definition: smmu_v3_caches.cc:491
ConfigCache::Entry::ssid
uint32_t ssid
Definition: smmu_v3_caches.hh:249
ARMArchTLB::Entry
Definition: smmu_v3_caches.hh:158
IPACache::Entry::ipa
Addr ipa
Definition: smmu_v3_caches.hh:208
ConfigCache::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:934
WalkCache::WalkCacheStats::~WalkCacheStats
~WalkCacheStats()
Definition: smmu_v3_caches.cc:1316
SMMUv3BaseCache::SMMUv3BaseCacheStats::averageMisses
Stats::Formula averageMisses
Definition: smmu_v3_caches.hh:75
IPACache::pickSetIdx
size_t pickSetIdx(Addr ipa, uint16_t vmid) const
Definition: smmu_v3_caches.cc:764
IPACache::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:770
WalkCache::WalkCacheStats::averageUpdatesByStageLevel
std::vector< Stats::Formula * > averageUpdatesByStageLevel
Definition: smmu_v3_caches.hh:336
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
WalkCache::walkCacheStats
WalkCache::WalkCacheStats walkCacheStats
simSeconds
Stats::Formula & simSeconds
Definition: stats.cc:42
name
const std::string & name()
Definition: trace.cc:48
ConfigCache::Entry::lastUsed
uint32_t lastUsed
Definition: smmu_v3_caches.hh:245
SMMUv3BaseCache::SMMUv3BaseCacheStats::insertions
Stats::Scalar insertions
Definition: smmu_v3_caches.hh:83
WalkCache::associativity
size_t associativity
Definition: smmu_v3_caches.hh:347
ARMArchTLB::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set)
Definition: smmu_v3_caches.cc:590
WalkCache::Entry::va
Addr va
Definition: smmu_v3_caches.hh:295
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
IPACache::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:738
UNIT_RATIO
#define UNIT_RATIO
Definition: units.hh:48
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:1191
Stats::Units::Count
Definition: units.hh:258
WalkCache::invalidateASID
void invalidateASID(uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:1122
SMMUv3BaseCache::SMMUv3BaseCacheStats::averageUpdates
Stats::Formula averageUpdates
Definition: smmu_v3_caches.hh:78
ConfigCache::invalidateSID
void invalidateSID(uint32_t sid)
Definition: smmu_v3_caches.cc:902
UNIT_RATE
#define UNIT_RATE(T1, T2)
Definition: units.hh:47
ConfigCache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:278
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:543
ConfigCache::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:917
SMMUTLB::Entry::ssid
uint32_t ssid
Definition: smmu_v3_caches.hh:111
IPACache::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:204
SMMUv3BaseCache::baseCacheStats
SMMUv3BaseCache::SMMUv3BaseCacheStats baseCacheStats
ARMArchTLB::Entry::asid
uint16_t asid
Definition: smmu_v3_caches.hh:166
SMMUv3BaseCache::SMMUv3BaseCacheStats::averageLookups
Stats::Formula averageLookups
Definition: smmu_v3_caches.hh:72
SMMUTLB::store
void store(const Entry &incoming, AllocPolicy alloc)
Definition: smmu_v3_caches.cc:239
SMMUTLB::invalidateSID
void invalidateSID(uint32_t sid)
Definition: smmu_v3_caches.cc:273
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:52
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:71
Stats::Formula
A formula for statistics that is calculated when printed.
Definition: statistics.hh:2538
SMMUv3BaseCache::SMMUv3BaseCacheStats::averageHitRate
Stats::Formula averageHitRate
Definition: smmu_v3_caches.hh:81
Stats::Group
Statistics container.
Definition: group.hh:87
ARMArchTLB::invalidateVAA
void invalidateVAA(Addr va, uint16_t vmid)
Definition: smmu_v3_caches.cc:528
SMMUTLB::pickEntryIdxToReplace
size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc)
Definition: smmu_v3_caches.cc:370
ARMArchTLB::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:191
IPACache::sets
std::vector< Set > sets
Definition: smmu_v3_caches.hh:231
Stats::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1166
ARMArchTLB::Entry::va
Addr va
Definition: smmu_v3_caches.hh:164
logging.hh
SMMUTLB_SEED
#define SMMUTLB_SEED
Definition: smmu_v3_caches.cc:49
SMMUv3BaseCache::SMMUv3BaseCacheStats::totalLookups
Stats::Scalar totalLookups
Definition: smmu_v3_caches.hh:73
ARMArchTLB::associativity
size_t associativity
Definition: smmu_v3_caches.hh:193
SMMUTLB::Entry::valid
bool valid
Definition: smmu_v3_caches.hh:105
ARMArchTLB::invalidateAll
void invalidateAll()
Definition: smmu_v3_caches.cc:573
Stats::DataWrapVec::subname
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Definition: statistics.hh:383
findLsbSet
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Definition: bitfield.hh:276
Stats
Definition: statistics.cc:53
WalkCache::offsets
std::array< unsigned, 2 *WALK_CACHE_LEVELS > offsets
Definition: smmu_v3_caches.hh:349
ARMArchTLB::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:558
WalkCache::WalkCacheStats::averageHitRateByStageLevel
std::vector< Stats::Formula * > averageHitRateByStageLevel
Definition: smmu_v3_caches.hh:339
ARMArchTLB::pickSetIdx
size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
Definition: smmu_v3_caches.cc:584
MipsISA::random
random
Definition: pra_constants.hh:50
WalkCache::WalkCacheStats::averageMissesByStageLevel
std::vector< Stats::Formula * > averageMissesByStageLevel
Definition: smmu_v3_caches.hh:333
WalkCache::Entry::vmid
uint16_t vmid
Definition: smmu_v3_caches.hh:298
SMMUv3BaseCache::SMMUv3BaseCacheStats::totalMisses
Stats::Scalar totalMisses
Definition: smmu_v3_caches.hh:76
ARMArchTLB::invalidateVA
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
Definition: smmu_v3_caches.cc:512
SMMUTLB::Entry::sid
uint32_t sid
Definition: smmu_v3_caches.hh:110
intmath.hh
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
SMMUTLB::associativity
size_t associativity
Definition: smmu_v3_caches.hh:148
ConfigCache::pickSetIdx
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Definition: smmu_v3_caches.cc:928
MipsISA::l
Bitfield< 5 > l
Definition: pra_constants.hh:320
ConfigCache::Entry
Definition: smmu_v3_caches.hh:242
WalkCache::WalkCacheStats::totalMissesByStageLevel
Stats::Vector2d totalMissesByStageLevel
Definition: smmu_v3_caches.hh:334
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
WalkCache::WalkCacheStats::averageLookupsByStageLevel
std::vector< Stats::Formula * > averageLookupsByStageLevel
Definition: smmu_v3_caches.hh:330
SMMU_CACHE_REPL_ROUND_ROBIN
@ SMMU_CACHE_REPL_ROUND_ROBIN
Definition: smmu_v3_caches.hh:55
ArmISA::va
Bitfield< 8 > va
Definition: miscregs_types.hh:272
WalkCache::invalidateVMID
void invalidateVMID(uint16_t vmid)
Definition: smmu_v3_caches.cc:1137
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
SMMUTLB::lookupAnyVA
const Entry * lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats=true)
Definition: smmu_v3_caches.cc:212

Generated on Tue Mar 23 2021 19:41:26 for gem5 by doxygen 1.8.17