62a63,64
> pendingReqs(0),
> pendingChangeTick(curTick()),
153a156
> pendingChange();
172a176,177
> ++statWalks;
>
198a204
> ++statSquashedBefore;
201a208
> pendingChange();
202a210
> currState->startTime = curTick();
263a272,273
> statRequestOrigin[REQUESTED][currState->isFetch]++;
>
282a293,296
>
> ++statWalksLongDescriptor;
> } else {
> ++statWalksShortDescriptor;
305a320
> pendingChange();
307a323
> pendingChange();
323a340
> pendingChange();
374a392
> statSquashedBefore++;
385a404
> statWalkServiceTime.sample(curTick() - currState->startTime);
404a424
> pendingChange();
406c426
< // if we've still got pending translations schedule more work
---
> // if we still have pending translations, schedule more work
422a443,444
> statWalkWaitTime.sample(curTick() - currState->startTime);
>
513a536,537
> statWalkWaitTime.sample(curTick() - currState->startTime);
>
702a727,728
> statWalkWaitTime.sample(curTick() - currState->startTime);
>
923,924c949,950
< port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), event,
< (uint8_t*) &currState->longDesc.data,
---
> port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
> event, (uint8_t*) &currState->longDesc.data,
1700a1727
> statWalksShortTerminatedAtLevel[0]++;
1713a1741
> statWalkServiceTime.sample(curTick() - currState->startTime);
1716a1745
> statWalksShortTerminatedAtLevel[0]++;
1751a1781
> statWalksShortTerminatedAtLevel[1]++;
1755a1786
> statWalkServiceTime.sample(curTick() - currState->startTime);
1758a1790
> statWalksShortTerminatedAtLevel[1]++;
1834a1867
> statWalkServiceTime.sample(curTick() - currState->startTime);
1837a1871
> statWalksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
1909c1943
< currState->tc->getCpuPtr()->clockPeriod(), flags);
---
> currState->tc->getCpuPtr()->clockPeriod(),flags);
1958a1993,1995
> statPageSizes[pageSizeNtoStatBin(te.N)]++;
> statRequestOrigin[COMPLETED][currState->isFetch]++;
>
2026a2064,2204
>
> /* this method keeps track of the table walker queue's residency, so
> * needs to be called whenever requests start and complete. */
> void
> TableWalker::pendingChange()
> {
> unsigned n = pendingQueue.size();
> if ((currState != NULL) && (currState != pendingQueue.front())) {
> ++n;
> }
>
> if (n != pendingReqs) {
> Tick now = curTick();
> statPendingWalks.sample(pendingReqs, now - pendingChangeTick);
> pendingReqs = n;
> pendingChangeTick = now;
> }
> }
>
> uint8_t
> TableWalker::pageSizeNtoStatBin(uint8_t N)
> {
> /* for statPageSizes */
> switch(N) {
> case 12: return 0; // 4K
> case 14: return 1; // 16K (using 16K granule in v8-64)
> case 16: return 2; // 64K
> case 20: return 3; // 1M
> case 21: return 4; // 2M-LPAE
> case 24: return 5; // 16M
> case 25: return 6; // 32M (using 16K granule in v8-64)
> case 29: return 7; // 512M (using 64K granule in v8-64)
> case 30: return 8; // 1G-LPAE
> default:
> panic("unknown page size");
> return 255;
> }
> }
>
> void
> TableWalker::regStats()
> {
> statWalks
> .name(name() + ".walks")
> .desc("Table walker walks requested")
> ;
>
> statWalksShortDescriptor
> .name(name() + ".walksShort")
> .desc("Table walker walks initiated with short descriptors")
> .flags(Stats::nozero)
> ;
>
> statWalksLongDescriptor
> .name(name() + ".walksLong")
> .desc("Table walker walks initiated with long descriptors")
> .flags(Stats::nozero)
> ;
>
> statWalksShortTerminatedAtLevel
> .init(2)
> .name(name() + ".walksShortTerminationLevel")
> .desc("Level at which table walker walks "
> "with short descriptors terminate")
> .flags(Stats::nozero)
> ;
> statWalksShortTerminatedAtLevel.subname(0, "Level1");
> statWalksShortTerminatedAtLevel.subname(1, "Level2");
>
> statWalksLongTerminatedAtLevel
> .init(4)
> .name(name() + ".walksLongTerminationLevel")
> .desc("Level at which table walker walks "
> "with long descriptors terminate")
> .flags(Stats::nozero)
> ;
> statWalksLongTerminatedAtLevel.subname(0, "Level0");
> statWalksLongTerminatedAtLevel.subname(1, "Level1");
> statWalksLongTerminatedAtLevel.subname(2, "Level2");
> statWalksLongTerminatedAtLevel.subname(3, "Level3");
>
> statSquashedBefore
> .name(name() + ".walksSquashedBefore")
> .desc("Table walks squashed before starting")
> .flags(Stats::nozero)
> ;
>
> statSquashedAfter
> .name(name() + ".walksSquashedAfter")
> .desc("Table walks squashed after completion")
> .flags(Stats::nozero)
> ;
>
> statWalkWaitTime
> .init(16)
> .name(name() + ".walkWaitTime")
> .desc("Table walker wait (enqueue to first request) latency")
> .flags(Stats::pdf | Stats::nozero | Stats::nonan)
> ;
>
> statWalkServiceTime
> .init(16)
> .name(name() + ".walkCompletionTime")
> .desc("Table walker service (enqueue to completion) latency")
> .flags(Stats::pdf | Stats::nozero | Stats::nonan)
> ;
>
> statPendingWalks
> .init(16)
> .name(name() + ".walksPending")
> .desc("Table walker pending requests distribution")
> .flags(Stats::pdf | Stats::dist | Stats::nozero | Stats::nonan)
> ;
>
> statPageSizes // see DDI 0487A D4-1661
> .init(9)
> .name(name() + ".walkPageSizes")
> .desc("Table walker page sizes translated")
> .flags(Stats::total | Stats::pdf | Stats::dist | Stats::nozero)
> ;
> statPageSizes.subname(0, "4K");
> statPageSizes.subname(1, "16K");
> statPageSizes.subname(2, "64K");
> statPageSizes.subname(3, "1M");
> statPageSizes.subname(4, "2M");
> statPageSizes.subname(5, "16M");
> statPageSizes.subname(6, "32M");
> statPageSizes.subname(7, "512M");
> statPageSizes.subname(8, "1G");
>
> statRequestOrigin
> .init(2,2) // Instruction/Data, requests/completed
> .name(name() + ".walkRequestOrigin")
> .desc("Table walker requests started/completed, data/inst")
> .flags(Stats::total)
> ;
> statRequestOrigin.subname(0,"Requested");
> statRequestOrigin.subname(1,"Completed");
> statRequestOrigin.ysubname(0,"Data");
> statRequestOrigin.ysubname(1,"Inst");
> }