eraseLatency(p.erase_lat),
dataDistribution(p.data_distribution),
numPlanes(p.num_planes),
+ stats(this),
pagesPerBlock(0),
pagesPerDisk(0),
blocksPerDisk(0),
return unknownPages[index >> 5] & (0x01 << (index % 32));
}
-void
-FlashDevice::regStats()
+FlashDevice::
+FlashDeviceStats::FlashDeviceStats(Stats::Group *parent)
+ : Stats::Group(parent, "FlashDevice"),
+ ADD_STAT(totalGCActivations, "Number of Garbage collector activations"),
+ ADD_STAT(writeAccess, "Histogram of write addresses"),
+ ADD_STAT(readAccess, "Histogram of read addresses"),
+ ADD_STAT(fileSystemAccess, "Histogram of file system accesses"),
+ ADD_STAT(writeLatency, "Histogram of write latency"),
+ ADD_STAT(readLatency, "Histogram of read latency")
{
- AbstractNVM::regStats();
-
using namespace Stats;
- std::string fd_name = name() + ".FlashDevice";
-
- // Register the stats
/** Amount of GC activations*/
- stats.totalGCActivations
- .name(fd_name + ".totalGCActivations")
- .desc("Number of Garbage collector activations")
+ totalGCActivations
.flags(none);
/** Histogram of address accesses*/
- stats.writeAccess
+ writeAccess
.init(2)
- .name(fd_name + ".writeAccessHist")
- .desc("Histogram of write addresses")
.flags(pdf);
- stats.readAccess
+ readAccess
.init(2)
- .name(fd_name + ".readAccessHist")
- .desc("Histogram of read addresses")
.flags(pdf);
- stats.fileSystemAccess
+ fileSystemAccess
.init(100)
- .name(fd_name + ".fileSystemAccessHist")
- .desc("Histogram of file system accesses")
.flags(pdf);
/** Histogram of access latencies*/
- stats.writeLatency
+ writeLatency
.init(100)
- .name(fd_name + ".writeLatencyHist")
- .desc("Histogram of write latency")
.flags(pdf);
- stats.readLatency
+ readLatency
.init(100)
- .name(fd_name + ".readLatencyHist")
- .desc("Histogram of read latency")
.flags(pdf);
}
std::function<void()> function;
};
- struct FlashDeviceStats {
+ struct FlashDeviceStats : public Stats::Group
+ {
+ FlashDeviceStats(Stats::Group *parent);
+
/** Amount of GC activations*/
Stats::Scalar totalGCActivations;
/** Function to test if a page is known*/
bool getUnknownPages(uint32_t index);
- /**Stats register function*/
- void regStats() override;
-
/** Disk sizes in bytes */
uint64_t diskSize;
const uint32_t blockSize;
virtRefreshEvent([this]{ virtRefresh(); }, name()),
// Other
imgFormat(p.frame_format), pic(NULL), conv(PixelConverter::rgba8888_le),
- pixelPump(*this, *p.pxl_clk, p.pixel_chunk)
+ pixelPump(*this, *p.pxl_clk, p.pixel_chunk),
+ stats(this)
{
if (vnc)
vnc->setFrameBuffer(&pixelPump.fb);
{
}
-void
-HDLcd::regStats()
+HDLcd::
+HDLcdStats::HDLcdStats(Stats::Group *parent)
+ : Stats::Group(parent, "HDLcd"),
+ ADD_STAT(underruns, "Number of buffer underruns")
{
- AmbaDmaDevice::regStats();
-
using namespace Stats;
- stats.underruns
- .name(name() + ".underruns")
- .desc("number of buffer underruns")
- .flags(nozero)
- ;
+ underruns.flags(nozero);
}
void
HDLcd(const HDLcdParams &p);
~HDLcd();
- void regStats() override;
-
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
std::unique_ptr<DmaEngine> dmaEngine;
protected: // Statistics
- struct {
+ struct HDLcdStats: public Stats::Group
+ {
+ HDLcdStats(Stats::Group *parent);
Stats::Scalar underruns;
} stats;
};
requestPort(name() + ".request", *this),
tableWalkPort(name() + ".walker", *this),
controlPort(name() + ".control", *this, params.reg_map),
- tlb(params.tlb_entries, params.tlb_assoc, params.tlb_policy),
- configCache(params.cfg_entries, params.cfg_assoc, params.cfg_policy),
- ipaCache(params.ipa_entries, params.ipa_assoc, params.ipa_policy),
+ tlb(params.tlb_entries, params.tlb_assoc, params.tlb_policy, this),
+ configCache(params.cfg_entries, params.cfg_assoc, params.cfg_policy, this),
+ ipaCache(params.ipa_entries, params.ipa_assoc, params.ipa_policy, this),
walkCache({ { params.walk_S1L0, params.walk_S1L1,
params.walk_S1L2, params.walk_S1L3,
params.walk_S2L0, params.walk_S2L1,
params.walk_S2L2, params.walk_S2L3 } },
- params.walk_assoc, params.walk_policy),
+ params.walk_assoc, params.walk_policy, this),
tlbEnable(params.tlb_enable),
configCacheEnable(params.cfg_enable),
ipaCacheEnable(params.ipa_enable),
configLat(params.cfg_lat),
ipaLat(params.ipa_lat),
walkLat(params.walk_lat),
+ stats(this),
deviceInterfaces(params.device_interfaces),
commandExecutor(name() + ".cmd_exec", *this),
regsMap(params.reg_map),
controlPort.sendRangeChange();
}
-void
-SMMUv3::regStats()
+SMMUv3::SMMUv3Stats::SMMUv3Stats(Stats::Group *parent)
+ : Stats::Group(parent),
+ ADD_STAT(steL1Fetches, "STE L1 fetches"),
+ ADD_STAT(steFetches, "STE fetches"),
+ ADD_STAT(cdL1Fetches, "CD L1 fetches"),
+ ADD_STAT(cdFetches, "CD fetches"),
+ ADD_STAT(translationTimeDist, "Time to translate address"),
+ ADD_STAT(ptwTimeDist, "Time to walk page tables")
{
- ClockedObject::regStats();
-
using namespace Stats;
- for (size_t i = 0; i < deviceInterfaces.size(); i++) {
- deviceInterfaces[i]->microTLB->regStats(
- csprintf("%s.utlb%d", name(), i));
- deviceInterfaces[i]->mainTLB->regStats(
- csprintf("%s.maintlb%d", name(), i));
- }
-
- tlb.regStats(name() + ".tlb");
- configCache.regStats(name() + ".cfg");
- ipaCache.regStats(name() + ".ipa");
- walkCache.regStats(name() + ".walk");
-
steL1Fetches
- .name(name() + ".steL1Fetches")
- .desc("STE L1 fetches")
.flags(pdf);
steFetches
- .name(name() + ".steFetches")
- .desc("STE fetches")
.flags(pdf);
cdL1Fetches
- .name(name() + ".cdL1Fetches")
- .desc("CD L1 fetches")
.flags(pdf);
cdFetches
- .name(name() + ".cdFetches")
- .desc("CD fetches")
.flags(pdf);
translationTimeDist
.init(0, 2000000, 2000)
- .name(name() + ".translationTimeDist")
- .desc("Time to translate address")
.flags(pdf);
ptwTimeDist
.init(0, 2000000, 2000)
- .name(name() + ".ptwTimeDist")
- .desc("Time to walk page tables")
.flags(pdf);
}
const Cycles walkLat;
// Stats
- Stats::Scalar steL1Fetches;
- Stats::Scalar steFetches;
- Stats::Scalar cdL1Fetches;
- Stats::Scalar cdFetches;
- Stats::Distribution translationTimeDist;
- Stats::Distribution ptwTimeDist;
+ struct SMMUv3Stats : public Stats::Group
+ {
+ SMMUv3Stats(Stats::Group *parent);
+ Stats::Scalar steL1Fetches;
+ Stats::Scalar steFetches;
+ Stats::Scalar cdL1Fetches;
+ Stats::Scalar cdFetches;
+ Stats::Distribution translationTimeDist;
+ Stats::Distribution ptwTimeDist;
+ } stats;
std::vector<SMMUv3DeviceInterface *> deviceInterfaces;
virtual ~SMMUv3() {}
virtual void init() override;
- virtual void regStats() override;
Tick recvAtomic(PacketPtr pkt, PortID id);
bool recvTimingReq(PacketPtr pkt, PortID id);
* TODO: move more code into this base class to reduce duplication.
*/
-SMMUv3BaseCache::SMMUv3BaseCache(const std::string &policy_name, uint32_t seed) :
+SMMUv3BaseCache::SMMUv3BaseCache(const std::string &policy_name, uint32_t seed,
+ Stats::Group *parent) :
replacementPolicy(decodePolicyName(policy_name)),
nextToReplace(0),
random(seed),
- useStamp(0)
+ useStamp(0),
+ baseCacheStats(parent)
{}
int
}
}
-void
-SMMUv3BaseCache::regStats(const std::string &name)
+SMMUv3BaseCache::
+SMMUv3BaseCacheStats::SMMUv3BaseCacheStats(Stats::Group *parent)
+ : Stats::Group(parent),
+ ADD_STAT(averageLookups, "Average number lookups per second"),
+ ADD_STAT(totalLookups, "Total number of lookups"),
+ ADD_STAT(averageMisses, "Average number misses per second"),
+ ADD_STAT(totalMisses, "Total number of misses"),
+ ADD_STAT(averageUpdates, "Average number updates per second"),
+ ADD_STAT(totalUpdates, "Total number of updates"),
+ ADD_STAT(averageHitRate, "Average hit rate"),
+ ADD_STAT(insertions, "Number of insertions (not replacements)")
{
using namespace Stats;
averageLookups
- .name(name + ".averageLookups")
- .desc("Average number lookups per second")
.flags(pdf);
totalLookups
- .name(name + ".totalLookups")
- .desc("Total number of lookups")
.flags(pdf);
averageLookups = totalLookups / simSeconds;
averageMisses
- .name(name + ".averageMisses")
- .desc("Average number misses per second")
.flags(pdf);
totalMisses
- .name(name + ".totalMisses")
- .desc("Total number of misses")
.flags(pdf);
averageMisses = totalMisses / simSeconds;
averageUpdates
- .name(name + ".averageUpdates")
- .desc("Average number updates per second")
.flags(pdf);
totalUpdates
- .name(name + ".totalUpdates")
- .desc("Total number of updates")
.flags(pdf);
averageUpdates = totalUpdates / simSeconds;
averageHitRate
- .name(name + ".averageHitRate")
- .desc("Average hit rate")
.flags(pdf);
averageHitRate = (totalLookups - totalMisses) / totalLookups;
insertions
- .name(name + ".insertions")
- .desc("Number of insertions (not replacements)")
.flags(pdf);
}
-
-
/*
* SMMUTLB
*/
SMMUTLB::SMMUTLB(unsigned numEntries, unsigned _associativity,
- const std::string &policy)
+ const std::string &policy, Stats::Group *parent)
:
- SMMUv3BaseCache(policy, SMMUTLB_SEED),
+ SMMUv3BaseCache(policy, SMMUTLB_SEED, parent),
associativity(_associativity)
{
if (associativity == 0)
if (result)
result->lastUsed = useStamp++;
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
}
return result;
}
if (updStats) {
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
}
return result;
set[pickEntryIdxToReplace(set, alloc)] = incoming;
}
- totalUpdates++;
+ baseCacheStats.totalUpdates++;
}
void
for (size_t i = 0; i < max_idx; i++) {
if (!set[i].valid) {
- insertions++;
+ baseCacheStats.insertions++;
return i;
}
*/
ARMArchTLB::ARMArchTLB(unsigned numEntries, unsigned _associativity,
- const std::string &policy)
+ const std::string &policy, Stats::Group *parent)
:
- SMMUv3BaseCache(policy, ARMARCHTLB_SEED),
+ SMMUv3BaseCache(policy, ARMARCHTLB_SEED, parent),
associativity(_associativity)
{
if (associativity == 0)
if (result)
result->lastUsed = useStamp++;
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
}
return result;
set[pickEntryIdxToReplace(set)] = incoming;
}
- totalUpdates++;
+ baseCacheStats.totalUpdates++;
}
void
for (size_t i = 0; i < set.size(); i++) {
if (!set[i].valid) {
- insertions++;
+ baseCacheStats.insertions++;
return i;
}
*/
IPACache::IPACache(unsigned numEntries, unsigned _associativity,
- const std::string &policy)
+ const std::string &policy, Stats::Group *parent)
:
- SMMUv3BaseCache(policy, IPACACHE_SEED),
+ SMMUv3BaseCache(policy, IPACACHE_SEED, parent),
associativity(_associativity)
{
if (associativity == 0)
if (result)
result->lastUsed = useStamp++;
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
}
return result;
set[pickEntryIdxToReplace(set)] = incoming;
}
- totalUpdates++;
+ baseCacheStats.totalUpdates++;
}
void
for (size_t i = 0; i < set.size(); i++) {
if (!set[i].valid) {
- insertions++;
+ baseCacheStats.insertions++;
return i;
}
*/
ConfigCache::ConfigCache(unsigned numEntries, unsigned _associativity,
- const std::string &policy)
+ const std::string &policy, Stats::Group *parent)
:
- SMMUv3BaseCache(policy, CONFIGCACHE_SEED),
+ SMMUv3BaseCache(policy, CONFIGCACHE_SEED, parent),
associativity(_associativity)
{
if (associativity == 0)
if (result)
result->lastUsed = useStamp++;
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
}
return result;
set[pickEntryIdxToReplace(set)] = incoming;
}
- totalUpdates++;
+ baseCacheStats.totalUpdates++;
}
void
for (size_t i = 0; i < set.size(); i++) {
if (!set[i].valid) {
- insertions++;
+ baseCacheStats.insertions++;
return i;
}
*/
WalkCache::WalkCache(const std::array<unsigned, 2*WALK_CACHE_LEVELS> &_sizes,
- unsigned _associativity, const std::string &policy) :
- SMMUv3BaseCache(policy, WALKCACHE_SEED),
+ unsigned _associativity, const std::string &policy,
+ Stats::Group *parent) :
+ SMMUv3BaseCache(policy, WALKCACHE_SEED, parent),
+ walkCacheStats(&(SMMUv3BaseCache::baseCacheStats)),
associativity(_associativity),
sizes()
{
if (result)
result->lastUsed = useStamp++;
- totalLookups++;
+ baseCacheStats.totalLookups++;
if (result == NULL)
- totalMisses++;
+ baseCacheStats.totalMisses++;
- lookupsByStageLevel[stage-1][level]++;
- totalLookupsByStageLevel[stage-1][level]++;
+ walkCacheStats.lookupsByStageLevel[stage-1][level]++;
+ walkCacheStats.totalLookupsByStageLevel[stage-1][level]++;
if (result == NULL) {
- missesByStageLevel[stage-1][level]++;
- totalMissesByStageLevel[stage-1][level]++;
+ walkCacheStats.missesByStageLevel[stage-1][level]++;
+ walkCacheStats.totalMissesByStageLevel[stage-1][level]++;
}
}
incoming;
}
- totalUpdates++;
- updatesByStageLevel[incoming.stage-1][incoming.level]++;
- totalUpdatesByStageLevel[incoming.stage-1][incoming.level]++;
+ baseCacheStats.totalUpdates++;
+ walkCacheStats.updatesByStageLevel[incoming.stage-1][incoming.level]++;
+ walkCacheStats
+ .totalUpdatesByStageLevel[incoming.stage-1][incoming.level]++;
}
void
for (size_t i = 0; i < set.size(); i++) {
if (!set[i].valid) {
- insertions++;
- insertionsByStageLevel[stage-1][level]++;
+ baseCacheStats.insertions++;
+ walkCacheStats.insertionsByStageLevel[stage-1][level]++;
return i;
}
}
-void
-WalkCache::regStats(const std::string &name)
+WalkCache::
+WalkCacheStats::WalkCacheStats(Stats::Group *parent)
+ : Stats::Group(parent, "WalkCache")
{
using namespace Stats;
- SMMUv3BaseCache::regStats(name);
-
for (int s = 0; s < 2; s++) {
for (int l = 0; l < WALK_CACHE_LEVELS; l++) {
averageLookupsByStageLevel[s][l]
- .name(csprintf("%s.averageLookupsS%dL%d", name, s+1, l))
+ .name(csprintf("averageLookupsS%dL%d", s+1, l))
.desc("Average number lookups per second")
.flags(pdf);
totalLookupsByStageLevel[s][l]
- .name(csprintf("%s.totalLookupsS%dL%d", name, s+1, l))
+ .name(csprintf("totalLookupsS%dL%d", s+1, l))
.desc("Total number of lookups")
.flags(pdf);
averageMissesByStageLevel[s][l]
- .name(csprintf("%s.averageMissesS%dL%d", name, s+1, l))
+ .name(csprintf("averageMissesS%dL%d", s+1, l))
.desc("Average number misses per second")
.flags(pdf);
totalMissesByStageLevel[s][l]
- .name(csprintf("%s.totalMissesS%dL%d", name, s+1, l))
+ .name(csprintf("totalMissesS%dL%d", s+1, l))
.desc("Total number of misses")
.flags(pdf);
averageUpdatesByStageLevel[s][l]
- .name(csprintf("%s.averageUpdatesS%dL%d", name, s+1, l))
+ .name(csprintf("averageUpdatesS%dL%d", s+1, l))
.desc("Average number updates per second")
.flags(pdf);
totalUpdatesByStageLevel[s][l]
- .name(csprintf("%s.totalUpdatesS%dL%d", name, s+1, l))
+ .name(csprintf("totalUpdatesS%dL%d", s+1, l))
.desc("Total number of updates")
.flags(pdf);
averageHitRateByStageLevel[s][l]
- .name(csprintf("%s.averageHitRateS%dL%d", name, s+1, l))
+ .name(csprintf("averageHitRateS%dL%d", s+1, l))
.desc("Average hit rate")
.flags(pdf);
/ totalLookupsByStageLevel[s][l];
insertionsByStageLevel[s][l]
- .name(csprintf("%s.insertionsS%dL%d", name, s+1, l))
+ .name(csprintf("insertionsS%dL%d", s+1, l))
.desc("Number of insertions (not replacements)")
.flags(pdf);
}
Random random;
uint32_t useStamp;
- Stats::Formula averageLookups;
- Stats::Scalar totalLookups;
+ struct SMMUv3BaseCacheStats : public Stats::Group
+ {
+ SMMUv3BaseCacheStats(Stats::Group *parent);
+
+ Stats::Formula averageLookups;
+ Stats::Scalar totalLookups;
- Stats::Formula averageMisses;
- Stats::Scalar totalMisses;
+ Stats::Formula averageMisses;
+ Stats::Scalar totalMisses;
- Stats::Formula averageUpdates;
- Stats::Scalar totalUpdates;
+ Stats::Formula averageUpdates;
+ Stats::Scalar totalUpdates;
- Stats::Formula averageHitRate;
+ Stats::Formula averageHitRate;
- Stats::Scalar insertions;
+ Stats::Scalar insertions;
+ } baseCacheStats;
static int decodePolicyName(const std::string &policy_name);
public:
- SMMUv3BaseCache(const std::string &policy_name, uint32_t seed);
+ SMMUv3BaseCache(const std::string &policy_name, uint32_t seed,
+ Stats::Group *parent);
virtual ~SMMUv3BaseCache() {}
-
- virtual void regStats(const std::string &name);
};
class SMMUTLB : public SMMUv3BaseCache
};
SMMUTLB(unsigned numEntries, unsigned _associativity,
- const std::string &policy);
+ const std::string &policy, Stats::Group *parent);
SMMUTLB(const SMMUTLB& tlb) = delete;
virtual ~SMMUTLB() {}
};
ARMArchTLB(unsigned numEntries, unsigned _associativity,
- const std::string &policy);
+ const std::string &policy, Stats::Group *parent);
virtual ~ARMArchTLB() {}
const Entry *lookup(Addr va, uint16_t asid, uint16_t vmid,
};
IPACache(unsigned numEntries, unsigned _associativity,
- const std::string &policy);
+ const std::string &policy, Stats::Group *parent);
virtual ~IPACache() {}
const Entry *lookup(Addr ipa, uint16_t vmid, bool updStats=true);
};
ConfigCache(unsigned numEntries, unsigned _associativity,
- const std::string &policy);
+ const std::string &policy, Stats::Group *parent);
virtual ~ConfigCache() {}
const Entry *lookup(uint32_t sid, uint32_t ssid, bool updStats=true);
};
WalkCache(const std::array<unsigned, 2*WALK_CACHE_LEVELS> &_sizes,
- unsigned _associativity, const std::string &policy);
+ unsigned _associativity, const std::string &policy,
+ Stats::Group *parent);
virtual ~WalkCache() {}
const Entry *lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid,
void invalidateVMID(uint16_t vmid);
void invalidateAll();
- void regStats(const std::string &name) override;
-
protected:
- unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS];
+ struct WalkCacheStats : public Stats::Group
+ {
+ WalkCacheStats(Stats::Group *parent);
- unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS];
+ unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS];
- unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS];
+ unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS];
+ unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS];
- Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS];
+ Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS];
+ } walkCacheStats;
private:
typedef std::vector<Entry> Set;
std::vector<Set> sets;
smmu(nullptr),
microTLB(new SMMUTLB(p.utlb_entries,
p.utlb_assoc,
- p.utlb_policy)),
+ p.utlb_policy,
+ this)),
mainTLB(new SMMUTLB(p.tlb_entries,
p.tlb_assoc,
- p.tlb_policy)),
+ p.tlb_policy,
+ this)),
microTLBEnable(p.utlb_enable),
mainTLBEnable(p.tlb_enable),
devicePortSem(1),
}
if (context.stage1Enable || context.stage2Enable)
- smmu.ptwTimeDist.sample(curTick() - ptwStartTick);
+ smmu.stats.ptwTimeDist.sample(curTick() - ptwStartTick);
// Free PTW slot
doSemaphoreUp(smmu.ptwSem);
doSemaphoreUp(smmu.requestPortSem);
- smmu.translationTimeDist.sample(curTick() - recvTick);
+ smmu.stats.translationTimeDist.sample(curTick() - recvTick);
ifc.xlateSlotsRemaining++;
if (!request.isAtsRequest && request.isWrite)
ifc.wrBufSlotsRemaining +=
ste_addr = (l2_ptr & ST_L2_ADDR_MASK) + index * sizeof(ste);
- smmu.steL1Fetches++;
- } else if ((smmu.regs.strtab_base_cfg & ST_CFG_FMT_MASK) == ST_CFG_FMT_LINEAR) {
+ smmu.stats.steL1Fetches++;
+ } else if ((smmu.regs.strtab_base_cfg & ST_CFG_FMT_MASK)
+ == ST_CFG_FMT_LINEAR) {
ste_addr =
(smmu.regs.strtab_base & VMT_BASE_ADDR_MASK) + sid * sizeof(ste);
} else {
if (!ste.dw0.valid)
panic("STE @ %#x not valid\n", ste_addr);
- smmu.steFetches++;
+ smmu.stats.steFetches++;
}
void
cd_addr = l2_ptr + bits(ssid, split-1, 0) * sizeof(cd);
- smmu.cdL1Fetches++;
+ smmu.stats.cdL1Fetches++;
} else if (ste.dw0.s1fmt == STAGE1_CFG_1L) {
cd_addr = (ste.dw0.s1ctxptr << ST_CD_ADDR_SHIFT) + ssid*sizeof(cd);
}
if (!cd.dw0.valid)
panic("CD @ %#x not valid\n", cd_addr);
- smmu.cdFetches++;
+ smmu.stats.cdFetches++;
}
void
transferTrack(0),
taskCommandTrack(0),
idlePhaseStart(0),
+ stats(this),
SCSIResumeEvent([this]{ SCSIStart(); }, name()),
UTPEvent([this]{ finalUTP(); }, name())
{
setValues();
}
-void
-UFSHostDevice::regStats()
+UFSHostDevice::
+UFSHostDeviceStats::UFSHostDeviceStats(UFSHostDevice *parent)
+ : Stats::Group(parent, "UFSDiskHost"),
+ ADD_STAT(currentSCSIQueue,
+ "Most up to date length of the command queue"),
+ ADD_STAT(currentReadSSDQueue,
+ "Most up to date length of the read SSD queue"),
+ ADD_STAT(currentWriteSSDQueue,
+ "Most up to date length of the write SSD queue"),
+ /** Amount of data read/written */
+ ADD_STAT(totalReadSSD, "Number of bytes read from SSD"),
+ ADD_STAT(totalWrittenSSD, "Number of bytes written to SSD"),
+ ADD_STAT(totalReadDiskTransactions,"Number of transactions from disk"),
+ ADD_STAT(totalWriteDiskTransactions, "Number of transactions to disk"),
+ ADD_STAT(totalReadUFSTransactions, "Number of transactions from device"),
+ ADD_STAT(totalWriteUFSTransactions, "Number of transactions to device"),
+ /** Average bandwidth for reads and writes */
+ ADD_STAT(averageReadSSDBW, "Average read bandwidth (bytes/s)",
+ totalReadSSD / simSeconds),
+ ADD_STAT(averageWriteSSDBW, "Average write bandwidth (bytes/s)",
+ totalWrittenSSD / simSeconds),
+ ADD_STAT(averageSCSIQueue, "Average command queue length"),
+ ADD_STAT(averageReadSSDQueue, "Average read queue length"),
+ ADD_STAT(averageWriteSSDQueue, "Average write queue length"),
+ /** Number of doorbells rung*/
+ ADD_STAT(curDoorbell, "Most up to date number of doorbells used",
+ parent->activeDoorbells),
+ ADD_STAT(maxDoorbell, "Maximum number of doorbells utilized"),
+ ADD_STAT(averageDoorbell, "Average number of Doorbells used"),
+ /** Latency*/
+ ADD_STAT(transactionLatency, "Histogram of transaction times"),
+ ADD_STAT(idleTimes, "Histogram of idle times")
{
- DmaDevice::regStats();
-
using namespace Stats;
- std::string UFSHost_name = name() + ".UFSDiskHost";
-
// Register the stats
/** Queue lengths */
- stats.currentSCSIQueue
- .name(UFSHost_name + ".currentSCSIQueue")
- .desc("Most up to date length of the command queue")
+ currentSCSIQueue
.flags(none);
- stats.currentReadSSDQueue
- .name(UFSHost_name + ".currentReadSSDQueue")
- .desc("Most up to date length of the read SSD queue")
+ currentReadSSDQueue
.flags(none);
- stats.currentWriteSSDQueue
- .name(UFSHost_name + ".currentWriteSSDQueue")
- .desc("Most up to date length of the write SSD queue")
+ currentWriteSSDQueue
.flags(none);
/** Amount of data read/written */
- stats.totalReadSSD
- .name(UFSHost_name + ".totalReadSSD")
- .desc("Number of bytes read from SSD")
+ totalReadSSD
.flags(none);
- stats.totalWrittenSSD
- .name(UFSHost_name + ".totalWrittenSSD")
- .desc("Number of bytes written to SSD")
+ totalWrittenSSD
.flags(none);
- stats.totalReadDiskTransactions
- .name(UFSHost_name + ".totalReadDiskTransactions")
- .desc("Number of transactions from disk")
+ totalReadDiskTransactions
.flags(none);
- stats.totalWriteDiskTransactions
- .name(UFSHost_name + ".totalWriteDiskTransactions")
- .desc("Number of transactions to disk")
+ totalWriteDiskTransactions
.flags(none);
- stats.totalReadUFSTransactions
- .name(UFSHost_name + ".totalReadUFSTransactions")
- .desc("Number of transactions from device")
+ totalReadUFSTransactions
.flags(none);
- stats.totalWriteUFSTransactions
- .name(UFSHost_name + ".totalWriteUFSTransactions")
- .desc("Number of transactions to device")
+ totalWriteUFSTransactions
.flags(none);
/** Average bandwidth for reads and writes */
- stats.averageReadSSDBW
- .name(UFSHost_name + ".averageReadSSDBandwidth")
- .desc("Average read bandwidth (bytes/s)")
+ averageReadSSDBW
.flags(nozero);
- stats.averageReadSSDBW = stats.totalReadSSD / simSeconds;
-
- stats.averageWriteSSDBW
- .name(UFSHost_name + ".averageWriteSSDBandwidth")
- .desc("Average write bandwidth (bytes/s)")
+ averageWriteSSDBW
.flags(nozero);
- stats.averageWriteSSDBW = stats.totalWrittenSSD / simSeconds;
-
- stats.averageSCSIQueue
- .name(UFSHost_name + ".averageSCSIQueueLength")
- .desc("Average command queue length")
+ averageSCSIQueue
.flags(nozero);
- stats.averageReadSSDQueue
- .name(UFSHost_name + ".averageReadSSDQueueLength")
- .desc("Average read queue length")
+ averageReadSSDQueue
.flags(nozero);
- stats.averageWriteSSDQueue
- .name(UFSHost_name + ".averageWriteSSDQueueLength")
- .desc("Average write queue length")
+ averageWriteSSDQueue
.flags(nozero);
/** Number of doorbells rung*/
- stats.curDoorbell
- .name(UFSHost_name + ".curDoorbell")
- .desc("Most up to date number of doorbells used")
+ curDoorbell
.flags(none);
- stats.curDoorbell = activeDoorbells;
-
- stats.maxDoorbell
- .name(UFSHost_name + ".maxDoorbell")
- .desc("Maximum number of doorbells utilized")
+ maxDoorbell
.flags(none);
- stats.averageDoorbell
- .name(UFSHost_name + ".averageDoorbell")
- .desc("Average number of Doorbells used")
+ averageDoorbell
.flags(nozero);
/** Latency*/
- stats.transactionLatency
+ transactionLatency
.init(100)
- .name(UFSHost_name + ".transactionLatency")
- .desc("Histogram of transaction times")
.flags(pdf);
- stats.idleTimes
+ idleTimes
.init(100)
- .name(UFSHost_name + ".idlePeriods")
- .desc("Histogram of idle times")
.flags(pdf);
-
}
/**
/**
* Statistics
*/
- struct UFSHostDeviceStats {
+ struct UFSHostDeviceStats : public Stats::Group
+ {
+ UFSHostDeviceStats(UFSHostDevice *parent);
+
/** Queue lengths */
Stats::Scalar currentSCSIQueue;
Stats::Scalar currentReadSSDQueue;
*/
void readGarbage();
- /**register statistics*/
- void regStats() override;
-
/**
* Host controller information
*/