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;
89 .
name(name +
".averageLookups")
90 .
desc(
"Average number lookups per second")
94 .
name(name +
".totalLookups")
95 .
desc(
"Total number of lookups")
102 .
name(name +
".averageMisses")
103 .
desc(
"Average number misses per second")
107 .
name(name +
".totalMisses")
108 .
desc(
"Total number of misses")
115 .
name(name +
".averageUpdates")
116 .
desc(
"Average number updates per second")
120 .
name(name +
".totalUpdates")
121 .
desc(
"Total number of updates")
128 .
name(name +
".averageHitRate")
129 .
desc(
"Average hit rate")
135 .
name(name +
".insertions")
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++) {
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++) {
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++) {
306 for (
size_t i = 0;
i <
set.size();
i++) {
317 for (
size_t s = 0;
s <
sets.size();
s++) {
320 for (
size_t i = 0;
i <
set.size();
i++) {
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)
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++) {
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++) {
528 for (
size_t s = 0;
s <
sets.size();
s++) {
531 for (
size_t i = 0;
i <
set.size();
i++) {
543 for (
size_t s = 0;
s <
sets.size();
s++) {
546 for (
size_t i = 0;
i <
set.size();
i++) {
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)
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++) {
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++) {
723 for (
size_t s = 0;
s <
sets.size();
s++) {
726 for (
size_t i = 0;
i <
set.size();
i++) {
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)
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++) {
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) :
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++) {
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++) {
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++) {
1122 for (
size_t s = 0;
s <
sets.size();
s++) {
1125 for (
size_t i = 0;
i <
set.size();
i++) {
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 panic(...)
This implements a cprintf based panic() function.
void invalidateSID(uint32_t sid)
const FlagsType pdf
Print the percent of the total that this entry represents.
Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS]
int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
void store(const Entry &incoming, AllocPolicy alloc)
size_t pickSetIdx(Addr ipa, uint16_t vmid) const
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
#define fatal(...)
This implements a cprintf based fatal() function.
const std::string & name()
const Entry * lookup(uint32_t sid, uint32_t ssid, Addr va, bool updStats=true)
void invalidateVMID(uint16_t vmid)
unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS]
const Entry * lookup(Addr ipa, uint16_t vmid, bool updStats=true)
void store(const Entry &incoming)
std::array< unsigned, 2 *WALK_CACHE_LEVELS > offsets
void invalidateVMID(uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set)
void invalidateASID(uint16_t asid, uint16_t vmid)
void invalidateSSID(uint32_t sid, uint32_t ssid)
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid, const bool leaf_only)
size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc)
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS]
Stats::Formula simSeconds
void invalidateVAA(Addr va, uint16_t vmid)
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...
unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS]
Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS]
Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS]
std::array< unsigned, 2 *WALK_CACHE_LEVELS > sizes
std::string csprintf(const char *format, const Args &...args)
void invalidateIPAA(Addr ipa)
Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS]
void invalidateIPA(Addr ipa, uint16_t vmid)
const Entry * lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats=true)
void invalidateSID(uint32_t sid)
const Entry * lookupAnyVA(uint32_t sid, uint32_t ssid, bool updStats=true)
void store(const Entry &incoming)
Stats::Scalar totalUpdates
void invalidateASID(uint16_t asid, uint16_t vmid)
ARMArchTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
ConfigCache(unsigned numEntries, unsigned _associativity, const std::string &policy)
void invalidateSSID(uint32_t sid, uint32_t ssid)
#define WALK_CACHE_LEVELS
void store(const Entry &incoming)
Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS]
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
Stats::Formula averageHitRate
void invalidateVAA(Addr va, uint16_t vmid)
SMMUTLB(unsigned numEntries, unsigned _associativity, const std::string &policy)
Stats::Formula averageLookups
Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS]
size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const
void store(const Entry &incoming)
const Entry * lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid, unsigned stage, unsigned level, bool updStats=true)
static int decodePolicyName(const std::string &policy_name)
size_t pickEntryIdxToReplace(const Set &set, unsigned stage, unsigned level)
Stats::Formula averageMisses
SMMUv3BaseCache(const std::string &policy_name, uint32_t seed)
Stats::Scalar totalLookups
void invalidateVMID(uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set)
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
void regStats(const std::string &name) override
Stats::Formula averageUpdates
virtual void regStats(const std::string &name)
void invalidateVMID(uint16_t vmid)
WalkCache(const std::array< unsigned, 2 *WALK_CACHE_LEVELS > &_sizes, unsigned _associativity, const std::string &policy)
size_t pickSetIdx(Addr va, Addr vaMask, unsigned stage, unsigned level) const
IPACache(unsigned numEntries, unsigned _associativity, const std::string &policy)
size_t pickSetIdx(uint32_t sid, uint32_t ssid) const
Stats::Scalar totalMisses
void invalidateASID(uint16_t asid, uint16_t vmid)
size_t pickEntryIdxToReplace(const Set &set)
unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS]