arch-arm: convert tlb to new style stats

Change-Id: I2a3f138b53496be6361a1a2b81fa471a56a4dc10
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/32794
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Emily Brickey
2020-08-12 14:52:10 -07:00
parent eb1ac7a011
commit a65eed883b
2 changed files with 84 additions and 166 deletions

View File

@@ -76,7 +76,7 @@ TLB::TLB(const ArmTLBParams *p)
: BaseTLB(p), table(new TlbEntry[p->size]), size(p->size),
isStage2(p->is_stage2), stage2Req(false), stage2DescReq(false), _attr(0),
directToStage2(false), tableWalker(p->walker), stage2Tlb(NULL),
stage2Mmu(NULL), test(nullptr), rangeMRU(1),
stage2Mmu(NULL), test(nullptr), stats(this), rangeMRU(1),
aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
isHyp(false), asid(0), vmid(0), hcr(0), dacr(0),
miscRegValid(false), miscRegContext(0), curTranType(NormalTran)
@@ -226,7 +226,7 @@ TLB::insert(Addr addr, TlbEntry &entry)
table[i] = table[i-1];
table[0] = entry;
inserts++;
stats.inserts++;
ppRefills->notify(1);
}
@@ -261,12 +261,12 @@ TLB::flushAllSecurity(bool secure_lookup, ExceptionLevel target_el,
DPRINTF(TLB, " - %s\n", te->print());
te->valid = false;
flushedEntries++;
stats.flushedEntries++;
}
++x;
}
flushTlb++;
stats.flushTlb++;
// If there's a second stage TLB (and we're not it) then flush it as well
// if we're currently in hyp mode
@@ -292,13 +292,13 @@ TLB::flushAllNs(ExceptionLevel target_el, bool ignore_el)
if (te->valid && te->nstid && te->isHyp == hyp && el_match) {
DPRINTF(TLB, " - %s\n", te->print());
flushedEntries++;
stats.flushedEntries++;
te->valid = false;
}
++x;
}
flushTlb++;
stats.flushTlb++;
// If there's a second stage TLB (and we're not it) then flush it as well
if (!isStage2 && !hyp) {
@@ -314,7 +314,7 @@ TLB::flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
"(%s lookup)\n", mva, asn, (secure_lookup ?
"secure" : "non-secure"));
_flushMva(mva, asn, secure_lookup, false, target_el, in_host);
flushTlbMvaAsid++;
stats.flushTlbMvaAsid++;
}
void
@@ -335,11 +335,11 @@ TLB::flushAsid(uint64_t asn, bool secure_lookup, ExceptionLevel target_el,
te->valid = false;
DPRINTF(TLB, " - %s\n", te->print());
flushedEntries++;
stats.flushedEntries++;
}
++x;
}
flushTlbAsid++;
stats.flushTlbAsid++;
}
void
@@ -349,7 +349,7 @@ TLB::flushMva(Addr mva, bool secure_lookup, ExceptionLevel target_el,
DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n", mva,
(secure_lookup ? "secure" : "non-secure"));
_flushMva(mva, 0xbeef, secure_lookup, true, target_el, in_host);
flushTlbMva++;
stats.flushTlbMva++;
}
void
@@ -368,7 +368,7 @@ TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup,
if (secure_lookup == !te->nstid) {
DPRINTF(TLB, " - %s\n", te->print());
te->valid = false;
flushedEntries++;
stats.flushedEntries++;
}
te = lookup(mva, asn, vmid, hyp, secure_lookup, false, ignore_asn,
target_el, in_host);
@@ -414,121 +414,37 @@ TLB::takeOverFrom(BaseTLB *_otlb)
}
}
void
TLB::regStats()
TLB::TlbStats::TlbStats(Stats::Group *parent)
: Stats::Group(parent),
ADD_STAT(instHits,"ITB inst hits"),
ADD_STAT(instMisses, "ITB inst misses"),
ADD_STAT(readHits, "DTB read hits"),
ADD_STAT(readMisses, "DTB read misses"),
ADD_STAT(writeHits, "DTB write hits"),
ADD_STAT(writeMisses, "DTB write misses"),
ADD_STAT(inserts, "Number of times an entry is inserted into the TLB"),
ADD_STAT(flushTlb, "Number of times complete TLB was flushed"),
ADD_STAT(flushTlbMva, "Number of times TLB was flushed by MVA"),
ADD_STAT(flushTlbMvaAsid, "Number of times TLB was flushed by MVA & ASID"),
ADD_STAT(flushTlbAsid, "Number of times TLB was flushed by ASID"),
ADD_STAT(flushedEntries, "Number of entries that have been flushed"
" from TLB"),
ADD_STAT(alignFaults, "Number of TLB faults due to alignment"
" restrictions"),
ADD_STAT(prefetchFaults, "Number of TLB faults due to prefetch"),
ADD_STAT(domainFaults, "Number of TLB faults due to domain restrictions"),
ADD_STAT(permsFaults, "Number of TLB faults due to permissions"
" restrictions"),
ADD_STAT(readAccesses, "DTB read accesses", readHits + readMisses),
ADD_STAT(writeAccesses, "DTB write accesses", writeHits + writeMisses),
ADD_STAT(instAccesses, "ITB inst accesses", instHits + instMisses),
ADD_STAT(hits, "Total TLB (inst and data) hits",
readHits + writeHits + instHits),
ADD_STAT(misses, "Total TLB (inst and data) misses",
readMisses + writeMisses + instMisses),
ADD_STAT(accesses, "Total TLB (inst and data) accesses",
readAccesses + writeAccesses + instAccesses)
{
BaseTLB::regStats();
instHits
.name(name() + ".inst_hits")
.desc("ITB inst hits")
;
instMisses
.name(name() + ".inst_misses")
.desc("ITB inst misses")
;
instAccesses
.name(name() + ".inst_accesses")
.desc("ITB inst accesses")
;
readHits
.name(name() + ".read_hits")
.desc("DTB read hits")
;
readMisses
.name(name() + ".read_misses")
.desc("DTB read misses")
;
readAccesses
.name(name() + ".read_accesses")
.desc("DTB read accesses")
;
writeHits
.name(name() + ".write_hits")
.desc("DTB write hits")
;
writeMisses
.name(name() + ".write_misses")
.desc("DTB write misses")
;
writeAccesses
.name(name() + ".write_accesses")
.desc("DTB write accesses")
;
hits
.name(name() + ".hits")
.desc("DTB hits")
;
misses
.name(name() + ".misses")
.desc("DTB misses")
;
accesses
.name(name() + ".accesses")
.desc("DTB accesses")
;
flushTlb
.name(name() + ".flush_tlb")
.desc("Number of times complete TLB was flushed")
;
flushTlbMva
.name(name() + ".flush_tlb_mva")
.desc("Number of times TLB was flushed by MVA")
;
flushTlbMvaAsid
.name(name() + ".flush_tlb_mva_asid")
.desc("Number of times TLB was flushed by MVA & ASID")
;
flushTlbAsid
.name(name() + ".flush_tlb_asid")
.desc("Number of times TLB was flushed by ASID")
;
flushedEntries
.name(name() + ".flush_entries")
.desc("Number of entries that have been flushed from TLB")
;
alignFaults
.name(name() + ".align_faults")
.desc("Number of TLB faults due to alignment restrictions")
;
prefetchFaults
.name(name() + ".prefetch_faults")
.desc("Number of TLB faults due to prefetch")
;
domainFaults
.name(name() + ".domain_faults")
.desc("Number of TLB faults due to domain restrictions")
;
permsFaults
.name(name() + ".perms_faults")
.desc("Number of TLB faults due to permissions restrictions")
;
instAccesses = instHits + instMisses;
readAccesses = readHits + readMisses;
writeAccesses = writeHits + writeMisses;
hits = readHits + writeHits + instHits;
misses = readMisses + writeMisses + instMisses;
accesses = readAccesses + writeAccesses + instAccesses;
}
void
@@ -613,7 +529,7 @@ TLB::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode)
if (!is_fetch) {
if (te->mtype != TlbEntry::MemoryType::Normal) {
if (vaddr & mask(flags & AlignmentMask)) {
alignFaults++;
stats.alignFaults++;
return std::make_shared<DataAbort>(
vaddr, TlbEntry::DomainType::NoAccess, is_write,
ArmFault::AlignmentFault, isStage2,
@@ -636,7 +552,7 @@ TLB::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode)
if (!te->longDescFormat) {
switch ((dacr >> (static_cast<uint8_t>(te->domain) * 2)) & 0x3) {
case 0:
domainFaults++;
stats.domainFaults++;
DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x"
" domain: %#x write:%d\n", dacr,
static_cast<uint8_t>(te->domain), is_write);
@@ -732,7 +648,7 @@ TLB::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode)
if (is_fetch && (abt || xn ||
(te->longDescFormat && te->pxn && is_priv) ||
(isSecure && te->ns && scr.sif))) {
permsFaults++;
stats.permsFaults++;
DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d "
"priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
ap, is_priv, is_write, te->ns, scr.sif,sctlr.afe);
@@ -743,7 +659,7 @@ TLB::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode)
ArmFault::PermissionLL + te->lookupLevel,
isStage2, tranMethod);
} else if (abt | hapAbt) {
permsFaults++;
stats.permsFaults++;
DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
" write:%d\n", ap, is_priv, is_write);
return std::make_shared<DataAbort>(
@@ -800,7 +716,7 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
if (!is_fetch) {
if (te->mtype != TlbEntry::MemoryType::Normal) {
if (vaddr & mask(flags & AlignmentMask)) {
alignFaults++;
stats.alignFaults++;
return std::make_shared<DataAbort>(
vaddr_tainted,
TlbEntry::DomainType::NoAccess,
@@ -971,7 +887,7 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
if (!grant) {
if (is_fetch) {
permsFaults++;
stats.permsFaults++;
DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. "
"AP:%d priv:%d write:%d ns:%d sif:%d "
"sctlr.afe: %d\n",
@@ -983,7 +899,7 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
ArmFault::PermissionLL + te->lookupLevel,
isStage2, ArmFault::LpaeTran);
} else {
permsFaults++;
stats.permsFaults++;
DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d "
"priv:%d write:%d\n", ap, is_priv, is_write);
return std::make_shared<DataAbort>(
@@ -1138,7 +1054,7 @@ TLB::translateMmuOn(ThreadContext* tc, const RequestPtr &req, Mode mode,
(te->mtype != TlbEntry::MemoryType::Normal)) {
// Unaligned accesses to Device memory should always cause an
// abort regardless of sctlr.a
alignFaults++;
stats.alignFaults++;
bool is_write = (mode == Write);
return std::make_shared<DataAbort>(
vaddr_tainted,
@@ -1204,7 +1120,7 @@ TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
if (!is_fetch) {
if (sctlr.a || !(flags & AllowUnaligned)) {
if (vaddr & mask(flags & AlignmentMask)) {
alignFaults++;
stats.alignFaults++;
return std::make_shared<DataAbort>(
vaddr_tainted,
TlbEntry::DomainType::NoAccess, is_write,
@@ -1572,17 +1488,17 @@ TLB::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
// if the request is a prefetch don't attempt to fill the TLB or go
// any further with the memory access (here we can safely use the
// fault status for the short desc. format in all cases)
prefetchFaults++;
stats.prefetchFaults++;
return std::make_shared<PrefetchAbort>(
vaddr_tainted, ArmFault::PrefetchTLBMiss, isStage2);
}
if (is_fetch)
instMisses++;
stats.instMisses++;
else if (is_write)
writeMisses++;
stats.writeMisses++;
else
readMisses++;
stats.readMisses++;
// start translation table walk, pass variables rather than
// re-retreaving in table walker for speed
@@ -1604,11 +1520,11 @@ TLB::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
assert(*te);
} else {
if (is_fetch)
instHits++;
stats.instHits++;
else if (is_write)
writeHits++;
stats.writeHits++;
else
readHits++;
stats.readHits++;
}
return NoFault;
}

View File

@@ -160,30 +160,34 @@ class TLB : public BaseTLB
TlbTestInterface *test;
// Access Stats
mutable Stats::Scalar instHits;
mutable Stats::Scalar instMisses;
mutable Stats::Scalar readHits;
mutable Stats::Scalar readMisses;
mutable Stats::Scalar writeHits;
mutable Stats::Scalar writeMisses;
mutable Stats::Scalar inserts;
mutable Stats::Scalar flushTlb;
mutable Stats::Scalar flushTlbMva;
mutable Stats::Scalar flushTlbMvaAsid;
mutable Stats::Scalar flushTlbAsid;
mutable Stats::Scalar flushedEntries;
mutable Stats::Scalar alignFaults;
mutable Stats::Scalar prefetchFaults;
mutable Stats::Scalar domainFaults;
mutable Stats::Scalar permsFaults;
struct TlbStats : public Stats::Group
{
TlbStats(Stats::Group *parent);
// Access Stats
mutable Stats::Scalar instHits;
mutable Stats::Scalar instMisses;
mutable Stats::Scalar readHits;
mutable Stats::Scalar readMisses;
mutable Stats::Scalar writeHits;
mutable Stats::Scalar writeMisses;
mutable Stats::Scalar inserts;
mutable Stats::Scalar flushTlb;
mutable Stats::Scalar flushTlbMva;
mutable Stats::Scalar flushTlbMvaAsid;
mutable Stats::Scalar flushTlbAsid;
mutable Stats::Scalar flushedEntries;
mutable Stats::Scalar alignFaults;
mutable Stats::Scalar prefetchFaults;
mutable Stats::Scalar domainFaults;
mutable Stats::Scalar permsFaults;
Stats::Formula readAccesses;
Stats::Formula writeAccesses;
Stats::Formula instAccesses;
Stats::Formula hits;
Stats::Formula misses;
Stats::Formula accesses;
Stats::Formula readAccesses;
Stats::Formula writeAccesses;
Stats::Formula instAccesses;
Stats::Formula hits;
Stats::Formula misses;
Stats::Formula accesses;
} stats;
/** PMU probe for TLB refills */
ProbePoints::PMUUPtr ppRefills;
@@ -385,8 +389,6 @@ class TLB : public BaseTLB
void drainResume() override;
void regStats() override;
void regProbePoints() override;
/**