52 #define SMMUTLB_SEED 0xEA752DFE 53 #define ARMARCHTLB_SEED 0x8B021FA1 54 #define IPACACHE_SEED 0xE5A0CC0F 55 #define CONFIGCACHE_SEED 0xB56F74E8 56 #define WALKCACHE_SEED 0x18ACF3D6 65 replacementPolicy(decodePolicyName(policy_name)),
74 if (policy_name ==
"rr") {
76 }
else if (policy_name ==
"rand") {
78 }
else if (policy_name ==
"lru") {
81 panic(
"Unknown cache replacement policy '%s'\n", policy_name);
88 using namespace Stats;
92 .
name(name +
".averageLookups")
93 .
desc(
"Average number lookups per second")
97 .
name(name +
".totalLookups")
98 .
desc(
"Total number of lookups")
105 .
name(name +
".averageMisses")
106 .
desc(
"Average number misses per second")
110 .
name(name +
".totalMisses")
111 .
desc(
"Total number of misses")
118 .
name(name +
".averageUpdates")
119 .
desc(
"Average number updates per second")
123 .
name(name +
".totalUpdates")
124 .
desc(
"Total number of updates")
131 .
name(name +
".averageHitRate")
132 .
desc(
"Average hit rate")
138 .
name(name +
".insertions")
139 .
desc(
"Number of insertions (not replacements)")
150 const std::string &policy)
153 associativity(_associativity)
159 fatal(
"SMMUTLB must have at least one entry\n");
162 fatal(
"SMMUTLB associativity cannot be higher than " 163 "its number of entries\n");
168 fatal(
"Number of SMMUTLB entries must be divisible " 169 "by its associativity\n");
175 sets.resize(num_sets,
set);
182 const Entry *result = NULL;
186 for (
size_t i = 0;
i <
set.size();
i++) {
193 panic(
"SMMUTLB: duplicate entry found!\n");
215 const Entry *result = NULL;
217 for (
size_t s = 0;
s <
sets.size();
s++) {
220 for (
size_t i = 0;
i <
set.size();
i++) {
243 panic(
"Tried to store an invalid entry\n");
247 const Entry *existing =
251 *
const_cast<Entry *
> (existing) = incoming;
265 for (
size_t i = 0;
i <
set.size();
i++) {
268 if (e.
sid == sid && e.
ssid == ssid)
276 for (
size_t s = 0;
s <
sets.size();
s++) {
279 for (
size_t i = 0;
i <
set.size();
i++) {
293 for (
size_t i = 0;
i <
set.size();
i++) {
309 for (
size_t i = 0;
i <
set.size();
i++) {
320 for (
size_t s = 0;
s <
sets.size();
s++) {
323 for (
size_t i = 0;
i <
set.size();
i++) {
335 for (
size_t s = 0;
s <
sets.size();
s++) {
338 for (
size_t i = 0;
i <
set.size();
i++) {
350 for (
size_t s = 0;
s <
sets.size();
s++) {
353 for (
size_t i = 0;
i <
set.size();
i++)
354 set[
i].valid =
false;
361 return (va >> 12) %
sets.size();
367 return (sid^ssid) %
sets.size();
376 uint32_t lru_tick = UINT32_MAX;
380 set.size()-1 :
set.size();
382 for (
size_t i = 0;
i < max_idx;
i++) {
388 if (
set[
i].lastUsed < lru_tick) {
390 lru_tick =
set[
i].lastUsed;
402 panic(
"Unknown allocation mode %d\n", alloc);
412 panic(
"Unknown allocation mode %d\n", alloc);
430 const std::string &policy)
439 fatal(
"ARMArchTLB must have at least one entry\n");
442 fatal(
"ARMArchTLB associativity cannot be higher than " 443 "its number of entries\n");
448 fatal(
"Number of ARMArchTLB entries must be divisible " 449 "by its associativity\n");
455 sets.resize(num_sets,
set);
461 const Entry *result = NULL;
465 for (
size_t i = 0;
i <
set.size();
i++) {
472 panic(
"ARMArchTLB: duplicate entry found!\n");
495 panic(
"Tried to store an invalid entry\n");
499 const Entry *existing =
503 *
const_cast<Entry *
> (existing) = incoming;
517 for (
size_t i = 0;
i <
set.size();
i++) {
531 for (
size_t s = 0;
s <
sets.size();
s++) {
534 for (
size_t i = 0;
i <
set.size();
i++) {
546 for (
size_t s = 0;
s <
sets.size();
s++) {
549 for (
size_t i = 0;
i <
set.size();
i++) {
561 for (
size_t s = 0;
s <
sets.size();
s++) {
564 for (
size_t i = 0;
i <
set.size();
i++) {
576 for (
size_t s = 0;
s <
sets.size();
s++) {
579 for (
size_t i = 0;
i <
set.size();
i++)
580 set[
i].valid =
false;
587 return ((va >> 12) ^ asid ^ vmid) %
sets.size();
594 uint32_t lru_tick = UINT32_MAX;
596 for (
size_t i = 0;
i <
set.size();
i++) {
602 if (
set[
i].lastUsed < lru_tick) {
604 lru_tick =
set[
i].lastUsed;
629 const std::string &policy)
638 fatal(
"IPACache must have at least one entry\n");
641 fatal(
"IPACache associativity cannot be higher than " 642 "its number of entries\n");
647 fatal(
"Number of IPACache entries must be divisible " 648 "by its associativity\n");
654 sets.resize(num_sets,
set);
660 const Entry *result = NULL;
664 for (
size_t i = 0;
i <
set.size();
i++) {
671 panic(
"IPACache: duplicate entry found!\n");
694 panic(
"Tried to store an invalid entry\n");
701 *
const_cast<Entry *
> (existing) = incoming;
715 for (
size_t i = 0;
i <
set.size();
i++) {
726 for (
size_t s = 0;
s <
sets.size();
s++) {
729 for (
size_t i = 0;
i <
set.size();
i++) {
741 for (
size_t s = 0;
s <
sets.size();
s++) {
744 for (
size_t i = 0;
i <
set.size();
i++) {
756 for (
size_t s = 0;
s <
sets.size();
s++) {
759 for (
size_t i = 0;
i <
set.size();
i++)
760 set[
i].valid =
false;
767 return ((va >> 12) ^ vmid) %
sets.size();
774 uint32_t lru_tick = UINT32_MAX;
776 for (
size_t i = 0;
i <
set.size();
i++) {
782 if (
set[
i].lastUsed < lru_tick) {
784 lru_tick =
set[
i].lastUsed;
809 const std::string &policy)
818 fatal(
"ConfigCache must have at least one entry\n");
821 fatal(
"ConfigCache associativity cannot be higher than " 822 "its number of entries\n");
827 fatal(
"Number of ConfigCache entries must be divisible " 828 "by its associativity\n");
834 sets.resize(num_sets,
set);
840 const Entry *result = NULL;
844 for (
size_t i = 0;
i <
set.size();
i++) {
850 panic(
"ConfigCache: duplicate entry found!\n");
873 panic(
"Tried to store an invalid entry\n");
880 *
const_cast<Entry *
> (existing) = incoming;
894 for (
size_t i = 0;
i <
set.size();
i++) {
897 if (e.
sid==sid && e.
ssid==ssid)
905 for (
size_t s = 0;
s <
sets.size();
s++) {
908 for (
size_t i = 0;
i <
set.size();
i++) {
920 for (
size_t s = 0;
s <
sets.size();
s++) {
923 for (
size_t i = 0;
i <
set.size();
i++)
924 set[
i].valid =
false;
931 return (sid^ssid) %
sets.size();
938 uint32_t lru_tick = UINT32_MAX;
940 for (
size_t i = 0;
i <
set.size();
i++) {
946 if (
set[
i].lastUsed < lru_tick) {
948 lru_tick =
set[
i].lastUsed;
973 unsigned _associativity,
const std::string &policy) :
978 unsigned numEntries = std::accumulate(&_sizes[0],
985 fatal(
"WalkCache must have at least one entry\n");
989 fatal(
"Number of WalkCache entries at each level must be " 990 "divisible by WalkCache associativity\n");
997 fatal(
"WalkCache associativity cannot be higher than " 998 "its number of entries\n");
1003 fatal(
"Number of WalkCache entries must be divisible " 1004 "by its associativity\n");
1010 sets.resize(num_sets,
set);
1015 uint16_t
asid, uint16_t vmid,
1016 unsigned stage,
unsigned level,
1019 const Entry *result = NULL;
1023 for (
size_t i = 0;
i <
set.size();
i++) {
1030 panic(
"WalkCache: duplicate entry found!\n");
1047 if (result == NULL) {
1059 if (!incoming.
valid)
1060 panic(
"Tried to store an invalid entry\n");
1062 assert(incoming.
stage==1 || incoming.
stage==2);
1072 *
const_cast<Entry *
> (existing) = incoming;
1087 const bool leaf_only)
1089 for (
size_t s = 0;
s <
sets.size();
s++) {
1092 for (
size_t i = 0;
i <
set.size();
i++) {
1096 && e.
asid == asid && e.
vmid == vmid)
1107 for (
size_t s = 0;
s <
sets.size();
s++) {
1110 for (
size_t i = 0;
i <
set.size();
i++) {
1125 for (
size_t s = 0;
s <
sets.size();
s++) {
1128 for (
size_t i = 0;
i <
set.size();
i++) {
1140 for (
size_t s = 0;
s <
sets.size();
s++) {
1143 for (
size_t i = 0;
i <
set.size();
i++) {
1155 for (
size_t s = 0;
s <
sets.size();
s++) {
1158 for (
size_t i = 0;
i <
set.size();
i++)
1159 set[
i].valid =
false;
1165 unsigned stage,
unsigned level)
const 1193 unsigned stage,
unsigned level)
1196 uint32_t lru_tick = UINT32_MAX;
1198 for (
size_t i = 0;
i <
set.size();
i++) {
1199 if (!
set[
i].valid) {
1205 if (
set[
i].lastUsed < lru_tick) {
1207 lru_tick =
set[
i].lastUsed;
1230 using namespace Stats;
1234 for (
int s = 0;
s < 2;
s++) {
1238 .
desc(
"Average number lookups per second")
1243 .
desc(
"Total number of lookups")
1252 .
desc(
"Average number misses per second")
1257 .
desc(
"Total number of misses")
1266 .
desc(
"Average number updates per second")
1271 .
desc(
"Total number of updates")
1280 .
desc(
"Average hit rate")
1290 .
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]