Go to the documentation of this file.
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
62 replacementPolicy(decodePolicyName(policy_name)),
71 if (policy_name ==
"rr") {
73 }
else if (policy_name ==
"rand") {
75 }
else if (policy_name ==
"lru") {
78 panic(
"Unknown cache replacement policy '%s'\n", policy_name);
85 using namespace Stats;
90 .
desc(
"Average number lookups per second")
95 .
desc(
"Total number of lookups")
103 .
desc(
"Average number misses per second")
108 .
desc(
"Total number of misses")
116 .
desc(
"Average number updates per second")
121 .
desc(
"Total number of updates")
129 .
desc(
"Average hit rate")
136 .
desc(
"Number of insertions (not replacements)")
147 const std::string &policy)
150 associativity(_associativity)
156 fatal(
"SMMUTLB must have at least one entry\n");
159 fatal(
"SMMUTLB associativity cannot be higher than "
160 "its number of entries\n");
165 fatal(
"Number of SMMUTLB entries must be divisible "
166 "by its associativity\n");
172 sets.resize(num_sets, set);
179 const Entry *result = NULL;
183 for (
size_t i = 0;
i < set.size();
i++) {
186 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
187 e.sid==sid &&
e.ssid==ssid)
190 panic(
"SMMUTLB: duplicate entry found!\n");
212 const Entry *result = NULL;
214 for (
size_t s = 0;
s <
sets.size();
s++) {
217 for (
size_t i = 0;
i < set.size();
i++) {
220 if (
e.valid &&
e.sid==sid &&
e.ssid==ssid) {
240 panic(
"Tried to store an invalid entry\n");
244 const Entry *existing =
248 *
const_cast<Entry *
> (existing) = incoming;
262 for (
size_t i = 0;
i < set.size();
i++) {
265 if (
e.sid == sid &&
e.ssid == ssid)
273 for (
size_t s = 0;
s <
sets.size();
s++) {
276 for (
size_t i = 0;
i < set.size();
i++) {
290 for (
size_t i = 0;
i < set.size();
i++) {
293 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
294 e.asid==
asid &&
e.vmid==vmid)
306 for (
size_t i = 0;
i < set.size();
i++) {
309 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
e.vmid==vmid)
317 for (
size_t s = 0;
s <
sets.size();
s++) {
320 for (
size_t i = 0;
i < set.size();
i++) {
323 if (
e.asid==
asid &&
e.vmid==vmid)
332 for (
size_t s = 0;
s <
sets.size();
s++) {
335 for (
size_t i = 0;
i < set.size();
i++) {
347 for (
size_t s = 0;
s <
sets.size();
s++) {
350 for (
size_t i = 0;
i < set.size();
i++)
351 set[
i].valid =
false;
358 return (
va >> 12) %
sets.size();
364 return (sid^ssid) %
sets.size();
373 uint32_t lru_tick = UINT32_MAX;
377 set.size()-1 : set.size();
379 for (
size_t i = 0;
i < max_idx;
i++) {
385 if (set[
i].lastUsed < lru_tick) {
387 lru_tick = set[
i].lastUsed;
399 panic(
"Unknown allocation mode %d\n", alloc);
409 panic(
"Unknown allocation mode %d\n", alloc);
427 const std::string &policy)
430 associativity(_associativity)
436 fatal(
"ARMArchTLB must have at least one entry\n");
439 fatal(
"ARMArchTLB associativity cannot be higher than "
440 "its number of entries\n");
445 fatal(
"Number of ARMArchTLB entries must be divisible "
446 "by its associativity\n");
452 sets.resize(num_sets, set);
458 const Entry *result = NULL;
462 for (
size_t i = 0;
i < set.size();
i++) {
465 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
466 e.asid==
asid &&
e.vmid==vmid)
469 panic(
"ARMArchTLB: duplicate entry found!\n");
492 panic(
"Tried to store an invalid entry\n");
496 const Entry *existing =
500 *
const_cast<Entry *
> (existing) = incoming;
514 for (
size_t i = 0;
i < set.size();
i++) {
517 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
518 e.asid==
asid &&
e.vmid==vmid)
528 for (
size_t s = 0;
s <
sets.size();
s++) {
531 for (
size_t i = 0;
i < set.size();
i++) {
534 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
e.vmid==vmid)
543 for (
size_t s = 0;
s <
sets.size();
s++) {
546 for (
size_t i = 0;
i < set.size();
i++) {
549 if (
e.asid==
asid &&
e.vmid==vmid)
558 for (
size_t s = 0;
s <
sets.size();
s++) {
561 for (
size_t i = 0;
i < set.size();
i++) {
573 for (
size_t s = 0;
s <
sets.size();
s++) {
576 for (
size_t i = 0;
i < set.size();
i++)
577 set[
i].valid =
false;
584 return ((
va >> 12) ^
asid ^ vmid) %
sets.size();
591 uint32_t lru_tick = UINT32_MAX;
593 for (
size_t i = 0;
i < set.size();
i++) {
599 if (set[
i].lastUsed < lru_tick) {
601 lru_tick = set[
i].lastUsed;
626 const std::string &policy)
629 associativity(_associativity)
635 fatal(
"IPACache must have at least one entry\n");
638 fatal(
"IPACache associativity cannot be higher than "
639 "its number of entries\n");
644 fatal(
"Number of IPACache entries must be divisible "
645 "by its associativity\n");
651 sets.resize(num_sets, set);
657 const Entry *result = NULL;
661 for (
size_t i = 0;
i < set.size();
i++) {
664 if (
e.valid && (
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask) &&
668 panic(
"IPACache: duplicate entry found!\n");
691 panic(
"Tried to store an invalid entry\n");
698 *
const_cast<Entry *
> (existing) = incoming;
712 for (
size_t i = 0;
i < set.size();
i++) {
715 if ((
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask) &&
e.vmid==vmid)
723 for (
size_t s = 0;
s <
sets.size();
s++) {
726 for (
size_t i = 0;
i < set.size();
i++) {
729 if ((
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask))
738 for (
size_t s = 0;
s <
sets.size();
s++) {
741 for (
size_t i = 0;
i < set.size();
i++) {
753 for (
size_t s = 0;
s <
sets.size();
s++) {
756 for (
size_t i = 0;
i < set.size();
i++)
757 set[
i].valid =
false;
764 return ((
va >> 12) ^ vmid) %
sets.size();
771 uint32_t lru_tick = UINT32_MAX;
773 for (
size_t i = 0;
i < set.size();
i++) {
779 if (set[
i].lastUsed < lru_tick) {
781 lru_tick = set[
i].lastUsed;
806 const std::string &policy)
809 associativity(_associativity)
815 fatal(
"ConfigCache must have at least one entry\n");
818 fatal(
"ConfigCache associativity cannot be higher than "
819 "its number of entries\n");
824 fatal(
"Number of ConfigCache entries must be divisible "
825 "by its associativity\n");
831 sets.resize(num_sets, set);
837 const Entry *result = NULL;
841 for (
size_t i = 0;
i < set.size();
i++) {
844 if (
e.valid &&
e.sid==sid &&
e.ssid==ssid)
847 panic(
"ConfigCache: duplicate entry found!\n");
870 panic(
"Tried to store an invalid entry\n");
877 *
const_cast<Entry *
> (existing) = incoming;
891 for (
size_t i = 0;
i < set.size();
i++) {
894 if (
e.sid==sid &&
e.ssid==ssid)
902 for (
size_t s = 0;
s <
sets.size();
s++) {
905 for (
size_t i = 0;
i < set.size();
i++) {
917 for (
size_t s = 0;
s <
sets.size();
s++) {
920 for (
size_t i = 0;
i < set.size();
i++)
921 set[
i].valid =
false;
928 return (sid^ssid) %
sets.size();
935 uint32_t lru_tick = UINT32_MAX;
937 for (
size_t i = 0;
i < set.size();
i++) {
943 if (set[
i].lastUsed < lru_tick) {
945 lru_tick = set[
i].lastUsed;
970 unsigned _associativity,
const std::string &policy) :
972 associativity(_associativity),
975 unsigned numEntries = std::accumulate(&_sizes[0],
982 fatal(
"WalkCache must have at least one entry\n");
986 fatal(
"Number of WalkCache entries at each level must be "
987 "divisible by WalkCache associativity\n");
994 fatal(
"WalkCache associativity cannot be higher than "
995 "its number of entries\n");
1000 fatal(
"Number of WalkCache entries must be divisible "
1001 "by its associativity\n");
1007 sets.resize(num_sets, set);
1012 uint16_t
asid, uint16_t vmid,
1013 unsigned stage,
unsigned level,
1016 const Entry *result = NULL;
1020 for (
size_t i = 0;
i < set.size();
i++) {
1023 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
1024 e.asid==
asid &&
e.vmid==vmid &&
e.stage==stage &&
e.level==
level)
1027 panic(
"WalkCache: duplicate entry found!\n");
1044 if (result == NULL) {
1056 if (!incoming.
valid)
1057 panic(
"Tried to store an invalid entry\n");
1059 assert(incoming.
stage==1 || incoming.
stage==2);
1069 *
const_cast<Entry *
> (existing) = incoming;
1084 const bool leaf_only)
1086 for (
size_t s = 0;
s <
sets.size();
s++) {
1089 for (
size_t i = 0;
i < set.size();
i++) {
1092 if ((!leaf_only ||
e.leaf) && (
e.va &
e.vaMask) == (
va &
e.vaMask)
1093 &&
e.asid ==
asid &&
e.vmid == vmid)
1104 for (
size_t s = 0;
s <
sets.size();
s++) {
1107 for (
size_t i = 0;
i < set.size();
i++) {
1110 if ((!leaf_only ||
e.leaf) && (
e.va &
e.vaMask) == (
va &
e.vaMask)
1122 for (
size_t s = 0;
s <
sets.size();
s++) {
1125 for (
size_t i = 0;
i < set.size();
i++) {
1128 if (
e.asid==
asid &&
e.vmid==vmid)
1137 for (
size_t s = 0;
s <
sets.size();
s++) {
1140 for (
size_t i = 0;
i < set.size();
i++) {
1152 for (
size_t s = 0;
s <
sets.size();
s++) {
1155 for (
size_t i = 0;
i < set.size();
i++)
1156 set[
i].valid =
false;
1162 unsigned stage,
unsigned level)
const
1190 unsigned stage,
unsigned level)
1193 uint32_t lru_tick = UINT32_MAX;
1195 for (
size_t i = 0;
i < set.size();
i++) {
1196 if (!set[
i].valid) {
1202 if (set[
i].lastUsed < lru_tick) {
1204 lru_tick = set[
i].lastUsed;
1227 using namespace Stats;
1231 for (
int s = 0;
s < 2;
s++) {
1235 .
desc(
"Average number lookups per second")
1240 .
desc(
"Total number of lookups")
1249 .
desc(
"Average number misses per second")
1254 .
desc(
"Total number of misses")
1263 .
desc(
"Average number updates per second")
1268 .
desc(
"Total number of updates")
1277 .
desc(
"Average hit rate")
1287 .desc(
"Number of insertions (not replacements)")
#define fatal(...)
This implements a cprintf based fatal() function.
void invalidateIPAA(Addr ipa)
const Entry * lookup(uint32_t sid, uint32_t ssid, Addr va, bool updStats=true)
Stats::Scalar totalLookups
@ SMMU_CACHE_REPL_ROUND_ROBIN
Stats::Formula averageLookups
const Entry * lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid, unsigned stage, unsigned level, bool updStats=true)
void invalidateSSID(uint32_t sid, uint32_t ssid)
size_t pickSetIdx(Addr va, Addr vaMask, unsigned stage, unsigned level) const
const Entry * lookup(Addr ipa, uint16_t vmid, bool updStats=true)
void store(const Entry &incoming)
void invalidateIPA(Addr ipa, uint16_t vmid)
Stats::Formula averageMisses
void invalidateVMID(uint16_t vmid)
void store(const Entry &incoming)
unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS]
unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS]
void store(const Entry &incoming)
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
std::array< unsigned, 2 *WALK_CACHE_LEVELS > sizes
const Entry * lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats=true)
void invalidateSSID(uint32_t sid, uint32_t ssid)
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS]
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
void invalidateVAA(Addr va, uint16_t vmid)
#define WALK_CACHE_LEVELS
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid, const bool leaf_only)
IPACache(unsigned numEntries, unsigned _associativity, const std::string &policy)
void invalidateASID(uint16_t asid, uint16_t vmid)
Stats::Formula simSeconds
Stats::Formula averageUpdates
Stats::Scalar totalUpdates
WalkCache(const std::array< unsigned, 2 *WALK_CACHE_LEVELS > &_sizes, unsigned _associativity, const std::string &policy)
Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS]
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
ARMArchTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
void store(const Entry &incoming)
size_t pickEntryIdxToReplace(const Set &set)
size_t pickSetIdx(Addr ipa, uint16_t vmid) const
size_t pickEntryIdxToReplace(const Set &set)
Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS]
SMMUTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS]
const std::string & name()
Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS]
size_t pickEntryIdxToReplace(const Set &set)
void regStats(const std::string &name) override
void invalidateVMID(uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set, unsigned stage, unsigned level)
void invalidateASID(uint16_t asid, uint16_t vmid)
void invalidateSID(uint32_t sid)
void invalidateASID(uint16_t asid, uint16_t vmid)
void store(const Entry &incoming, AllocPolicy alloc)
void invalidateSID(uint32_t sid)
const FlagsType pdf
Print the percent of the total that this entry represents.
static int decodePolicyName(const std::string &policy_name)
void invalidateVAA(Addr va, uint16_t vmid)
Stats::Scalar totalMisses
size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc)
SMMUv3BaseCache(const std::string &policy_name, uint32_t seed)
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...
Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
std::array< unsigned, 2 *WALK_CACHE_LEVELS > offsets
void invalidateVMID(uint16_t vmid)
size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
ConfigCache(unsigned numEntries, unsigned _associativity, const std::string &policy)
int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Stats::Formula averageHitRate
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS]
virtual void regStats(const std::string &name)
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
std::string csprintf(const char *format, const Args &...args)
void invalidateVMID(uint16_t vmid)
#define panic(...)
This implements a cprintf based panic() function.
Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS]
const Entry * lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats=true)
Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17