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
63 : replacementPolicy(decodePolicyName(policy_name)),
67 baseCacheStats(parent,
name)
73 if (policy_name ==
"rr") {
75 }
else if (policy_name ==
"rand") {
77 }
else if (policy_name ==
"lru") {
80 panic(
"Unknown cache replacement policy '%s'\n", policy_name);
90 "Average number lookups per second"),
94 "Average number misses per second"),
98 "Average number updates per second"),
102 "Number of insertions (not replacements)")
104 using namespace Stats;
149 const std::string &
name)
152 associativity(_associativity)
158 fatal(
"SMMUTLB must have at least one entry\n");
161 fatal(
"SMMUTLB associativity cannot be higher than "
162 "its number of entries\n");
167 fatal(
"Number of SMMUTLB entries must be divisible "
168 "by its associativity\n");
174 sets.resize(num_sets, set);
181 const Entry *result = NULL;
185 for (
size_t i = 0;
i < set.size();
i++) {
188 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
189 e.sid==sid &&
e.ssid==ssid)
192 panic(
"SMMUTLB: duplicate entry found!\n");
214 const Entry *result = NULL;
216 for (
size_t s = 0;
s <
sets.size();
s++) {
219 for (
size_t i = 0;
i < set.size();
i++) {
222 if (
e.valid &&
e.sid==sid &&
e.ssid==ssid) {
242 panic(
"Tried to store an invalid entry\n");
246 const Entry *existing =
250 *
const_cast<Entry *
> (existing) = incoming;
264 for (
size_t i = 0;
i < set.size();
i++) {
267 if (
e.sid == sid &&
e.ssid == ssid)
275 for (
size_t s = 0;
s <
sets.size();
s++) {
278 for (
size_t i = 0;
i < set.size();
i++) {
292 for (
size_t i = 0;
i < set.size();
i++) {
295 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
296 e.asid==
asid &&
e.vmid==vmid)
308 for (
size_t i = 0;
i < set.size();
i++) {
311 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
e.vmid==vmid)
319 for (
size_t s = 0;
s <
sets.size();
s++) {
322 for (
size_t i = 0;
i < set.size();
i++) {
325 if (
e.asid==
asid &&
e.vmid==vmid)
334 for (
size_t s = 0;
s <
sets.size();
s++) {
337 for (
size_t i = 0;
i < set.size();
i++) {
349 for (
size_t s = 0;
s <
sets.size();
s++) {
352 for (
size_t i = 0;
i < set.size();
i++)
353 set[
i].valid =
false;
360 return (
va >> 12) %
sets.size();
366 return (sid^ssid) %
sets.size();
375 uint32_t lru_tick = UINT32_MAX;
379 set.size()-1 : set.size();
381 for (
size_t i = 0;
i < max_idx;
i++) {
387 if (set[
i].lastUsed < lru_tick) {
389 lru_tick = set[
i].lastUsed;
401 panic(
"Unknown allocation mode %d\n", alloc);
411 panic(
"Unknown allocation mode %d\n", alloc);
432 associativity(_associativity)
438 fatal(
"ARMArchTLB must have at least one entry\n");
441 fatal(
"ARMArchTLB associativity cannot be higher than "
442 "its number of entries\n");
447 fatal(
"Number of ARMArchTLB entries must be divisible "
448 "by its associativity\n");
454 sets.resize(num_sets, set);
460 const Entry *result = NULL;
464 for (
size_t i = 0;
i < set.size();
i++) {
467 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
468 e.asid==
asid &&
e.vmid==vmid)
471 panic(
"ARMArchTLB: duplicate entry found!\n");
494 panic(
"Tried to store an invalid entry\n");
498 const Entry *existing =
502 *
const_cast<Entry *
> (existing) = incoming;
516 for (
size_t i = 0;
i < set.size();
i++) {
519 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
520 e.asid==
asid &&
e.vmid==vmid)
530 for (
size_t s = 0;
s <
sets.size();
s++) {
533 for (
size_t i = 0;
i < set.size();
i++) {
536 if ((
e.va &
e.vaMask) == (
va &
e.vaMask) &&
e.vmid==vmid)
545 for (
size_t s = 0;
s <
sets.size();
s++) {
548 for (
size_t i = 0;
i < set.size();
i++) {
551 if (
e.asid==
asid &&
e.vmid==vmid)
560 for (
size_t s = 0;
s <
sets.size();
s++) {
563 for (
size_t i = 0;
i < set.size();
i++) {
575 for (
size_t s = 0;
s <
sets.size();
s++) {
578 for (
size_t i = 0;
i < set.size();
i++)
579 set[
i].valid =
false;
586 return ((
va >> 12) ^
asid ^ vmid) %
sets.size();
593 uint32_t lru_tick = UINT32_MAX;
595 for (
size_t i = 0;
i < set.size();
i++) {
601 if (set[
i].lastUsed < lru_tick) {
603 lru_tick = set[
i].lastUsed;
631 associativity(_associativity)
637 fatal(
"IPACache must have at least one entry\n");
640 fatal(
"IPACache associativity cannot be higher than "
641 "its number of entries\n");
646 fatal(
"Number of IPACache entries must be divisible "
647 "by its associativity\n");
653 sets.resize(num_sets, set);
659 const Entry *result = NULL;
663 for (
size_t i = 0;
i < set.size();
i++) {
666 if (
e.valid && (
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask) &&
670 panic(
"IPACache: duplicate entry found!\n");
693 panic(
"Tried to store an invalid entry\n");
700 *
const_cast<Entry *
> (existing) = incoming;
714 for (
size_t i = 0;
i < set.size();
i++) {
717 if ((
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask) &&
e.vmid==vmid)
725 for (
size_t s = 0;
s <
sets.size();
s++) {
728 for (
size_t i = 0;
i < set.size();
i++) {
731 if ((
e.ipa &
e.ipaMask) == (ipa &
e.ipaMask))
740 for (
size_t s = 0;
s <
sets.size();
s++) {
743 for (
size_t i = 0;
i < set.size();
i++) {
755 for (
size_t s = 0;
s <
sets.size();
s++) {
758 for (
size_t i = 0;
i < set.size();
i++)
759 set[
i].valid =
false;
766 return ((
va >> 12) ^ vmid) %
sets.size();
773 uint32_t lru_tick = UINT32_MAX;
775 for (
size_t i = 0;
i < set.size();
i++) {
781 if (set[
i].lastUsed < lru_tick) {
783 lru_tick = set[
i].lastUsed;
811 associativity(_associativity)
817 fatal(
"ConfigCache must have at least one entry\n");
820 fatal(
"ConfigCache associativity cannot be higher than "
821 "its number of entries\n");
826 fatal(
"Number of ConfigCache entries must be divisible "
827 "by its associativity\n");
833 sets.resize(num_sets, set);
839 const Entry *result = NULL;
843 for (
size_t i = 0;
i < set.size();
i++) {
846 if (
e.valid &&
e.sid==sid &&
e.ssid==ssid)
849 panic(
"ConfigCache: duplicate entry found!\n");
872 panic(
"Tried to store an invalid entry\n");
879 *
const_cast<Entry *
> (existing) = incoming;
893 for (
size_t i = 0;
i < set.size();
i++) {
896 if (
e.sid==sid &&
e.ssid==ssid)
904 for (
size_t s = 0;
s <
sets.size();
s++) {
907 for (
size_t i = 0;
i < set.size();
i++) {
919 for (
size_t s = 0;
s <
sets.size();
s++) {
922 for (
size_t i = 0;
i < set.size();
i++)
923 set[
i].valid =
false;
930 return (sid^ssid) %
sets.size();
937 uint32_t lru_tick = UINT32_MAX;
939 for (
size_t i = 0;
i < set.size();
i++) {
945 if (set[
i].lastUsed < lru_tick) {
947 lru_tick = set[
i].lastUsed;
972 unsigned _associativity,
const std::string &policy,
976 associativity(_associativity),
979 unsigned numEntries = std::accumulate(&_sizes[0],
986 fatal(
"WalkCache must have at least one entry\n");
990 fatal(
"Number of WalkCache entries at each level must be "
991 "divisible by WalkCache associativity\n");
998 fatal(
"WalkCache associativity cannot be higher than "
999 "its number of entries\n");
1004 fatal(
"Number of WalkCache entries must be divisible "
1005 "by its associativity\n");
1011 sets.resize(num_sets, set);
1016 uint16_t
asid, uint16_t vmid,
1017 unsigned stage,
unsigned level,
1020 const Entry *result = NULL;
1024 for (
size_t i = 0;
i < set.size();
i++) {
1027 if (
e.valid && (
e.va &
e.vaMask) == (
va &
e.vaMask) &&
1028 e.asid==
asid &&
e.vmid==vmid &&
e.stage==stage &&
e.level==
level)
1031 panic(
"WalkCache: duplicate entry found!\n");
1047 if (result == NULL) {
1058 if (!incoming.
valid)
1059 panic(
"Tried to store an invalid entry\n");
1061 assert(incoming.
stage==1 || incoming.
stage==2);
1071 *
const_cast<Entry *
> (existing) = incoming;
1086 const bool leaf_only)
1088 for (
size_t s = 0;
s <
sets.size();
s++) {
1091 for (
size_t i = 0;
i < set.size();
i++) {
1094 if ((!leaf_only ||
e.leaf) && (
e.va &
e.vaMask) == (
va &
e.vaMask)
1095 &&
e.asid ==
asid &&
e.vmid == vmid)
1106 for (
size_t s = 0;
s <
sets.size();
s++) {
1109 for (
size_t i = 0;
i < set.size();
i++) {
1112 if ((!leaf_only ||
e.leaf) && (
e.va &
e.vaMask) == (
va &
e.vaMask)
1124 for (
size_t s = 0;
s <
sets.size();
s++) {
1127 for (
size_t i = 0;
i < set.size();
i++) {
1130 if (
e.asid==
asid &&
e.vmid==vmid)
1139 for (
size_t s = 0;
s <
sets.size();
s++) {
1142 for (
size_t i = 0;
i < set.size();
i++) {
1154 for (
size_t s = 0;
s <
sets.size();
s++) {
1157 for (
size_t i = 0;
i < set.size();
i++)
1158 set[
i].valid =
false;
1164 unsigned stage,
unsigned level)
const
1192 unsigned stage,
unsigned level)
1195 uint32_t lru_tick = UINT32_MAX;
1197 for (
size_t i = 0;
i < set.size();
i++) {
1198 if (!set[
i].valid) {
1204 if (set[
i].lastUsed < lru_tick) {
1206 lru_tick = set[
i].lastUsed;
1230 "Total number of lookups"),
1232 "Total number of misses"),
1234 "Total number of updates"),
1236 "Number of insertions (not replacements)")
1238 using namespace Stats;
1253 for (
int s = 0;
s < 2;
s++) {
1267 csprintf(
"averageLookups_S%dL%d",
s+1,
l).c_str(),
1269 "Average number lookups per second");
1270 avg_lookup->flags(
pdf);
1278 csprintf(
"averageMisses_S%dL%d",
s+1,
l).c_str(),
1280 "Average number misses per second");
1281 avg_misses->flags(
pdf);
1289 csprintf(
"averageUpdates_S%dL%d",
s+1,
l).c_str(),
1291 "Average number updates per second");
1292 avg_updates->flags(
pdf);
1300 csprintf(
"averageHitRate_S%dL%d",
s+1,
l).c_str(),
1302 "Average hit rate");
1303 avg_hitrate->flags(
pdf);
#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)
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)
SMMUv3BaseCache(const std::string &policy_name, uint32_t seed, Stats::Group *parent, const std::string &name)
IPACache(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
void store(const Entry &incoming)
void invalidateIPA(Addr ipa, uint16_t vmid)
ARMArchTLB(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
SMMUv3BaseCacheStats(Stats::Group *parent, const std::string &name)
Derived & ysubname(off_type index, const std::string &subname)
WalkCacheStats(Stats::Group *parent)
ConfigCache(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent)
void invalidateVMID(uint16_t vmid)
Stats::Scalar totalUpdates
Stats::Vector2d insertionsByStageLevel
void store(const Entry &incoming)
SMMUTLB(unsigned numEntries, unsigned _associativity, const std::string &policy, Stats::Group *parent, const std::string &name)
void store(const Entry &incoming)
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Stats::Vector2d totalUpdatesByStageLevel
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)
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...
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
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)
void invalidateASID(uint16_t asid, uint16_t vmid)
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
WalkCache(const std::array< unsigned, 2 *WALK_CACHE_LEVELS > &_sizes, unsigned _associativity, const std::string &policy, Stats::Group *parent)
Stats::Vector2d totalLookupsByStageLevel
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
void store(const Entry &incoming)
size_t pickEntryIdxToReplace(const Set &set)
Stats::Formula averageMisses
size_t pickSetIdx(Addr ipa, uint16_t vmid) const
size_t pickEntryIdxToReplace(const Set &set)
std::vector< Stats::Formula * > averageUpdatesByStageLevel
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
WalkCache::WalkCacheStats walkCacheStats
Stats::Formula & simSeconds
const std::string & name()
size_t pickEntryIdxToReplace(const Set &set)
void invalidateVMID(uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set, unsigned stage, unsigned level)
void invalidateASID(uint16_t asid, uint16_t vmid)
Stats::Formula averageUpdates
void invalidateSID(uint32_t sid)
#define UNIT_RATE(T1, T2)
void invalidateASID(uint16_t asid, uint16_t vmid)
SMMUv3BaseCache::SMMUv3BaseCacheStats baseCacheStats
Stats::Formula averageLookups
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)
Stats::Formula averageHitRate
void invalidateVAA(Addr va, uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc)
Derived & init(size_type _x, size_type _y)
Stats::Scalar totalLookups
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.
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
std::array< unsigned, 2 *WALK_CACHE_LEVELS > offsets
void invalidateVMID(uint16_t vmid)
std::vector< Stats::Formula * > averageHitRateByStageLevel
size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
std::vector< Stats::Formula * > averageMissesByStageLevel
Stats::Scalar totalMisses
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Stats::Vector2d totalMissesByStageLevel
std::string csprintf(const char *format, const Args &...args)
std::vector< Stats::Formula * > averageLookupsByStageLevel
@ SMMU_CACHE_REPL_ROUND_ROBIN
void invalidateVMID(uint16_t vmid)
#define panic(...)
This implements a cprintf based panic() function.
const Entry * lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats=true)
Generated on Tue Mar 23 2021 19:41:26 for gem5 by doxygen 1.8.17