table_walker.cc (10579:e622a3e2ed14) table_walker.cc (10621:b7bc5b1084a4)
1/*
2 * Copyright (c) 2010, 2012-2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 46 unchanged lines hidden (view full) ---

55
56using namespace ArmISA;
57
58TableWalker::TableWalker(const Params *p)
59 : MemObject(p), port(this, p->sys), drainManager(NULL),
60 stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
61 currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
62 numSquashable(p->num_squash_per_cycle),
1/*
2 * Copyright (c) 2010, 2012-2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 46 unchanged lines hidden (view full) ---

55
56using namespace ArmISA;
57
58TableWalker::TableWalker(const Params *p)
59 : MemObject(p), port(this, p->sys), drainManager(NULL),
60 stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
61 currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
62 numSquashable(p->num_squash_per_cycle),
63 pendingReqs(0),
64 pendingChangeTick(curTick()),
63 doL1DescEvent(this), doL2DescEvent(this),
64 doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
65 doL3LongDescEvent(this),
66 doProcessEvent(this)
67{
68 sctlr = 0;
69
70 // Cache system-level properties

--- 75 unchanged lines hidden (view full) ---

146
147void
148TableWalker::drainResume()
149{
150 Drainable::drainResume();
151 if (params()->sys->isTimingMode() && currState) {
152 delete currState;
153 currState = NULL;
65 doL1DescEvent(this), doL2DescEvent(this),
66 doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
67 doL3LongDescEvent(this),
68 doProcessEvent(this)
69{
70 sctlr = 0;
71
72 // Cache system-level properties

--- 75 unchanged lines hidden (view full) ---

148
149void
150TableWalker::drainResume()
151{
152 Drainable::drainResume();
153 if (params()->sys->isTimingMode() && currState) {
154 delete currState;
155 currState = NULL;
156 pendingChange();
154 }
155}
156
157BaseMasterPort&
158TableWalker::getMasterPort(const std::string &if_name, PortID idx)
159{
160 if (if_name == "port") {
161 return port;
162 }
163 return MemObject::getMasterPort(if_name, idx);
164}
165
166Fault
167TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
168 uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
169 TLB::Translation *_trans, bool _timing, bool _functional,
170 bool secure, TLB::ArmTranslationType tranType)
171{
172 assert(!(_functional && _timing));
157 }
158}
159
160BaseMasterPort&
161TableWalker::getMasterPort(const std::string &if_name, PortID idx)
162{
163 if (if_name == "port") {
164 return port;
165 }
166 return MemObject::getMasterPort(if_name, idx);
167}
168
169Fault
170TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
171 uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
172 TLB::Translation *_trans, bool _timing, bool _functional,
173 bool secure, TLB::ArmTranslationType tranType)
174{
175 assert(!(_functional && _timing));
176 ++statWalks;
177
173 WalkerState *savedCurrState = NULL;
174
175 if (!currState && !_functional) {
176 // For atomic mode, a new WalkerState instance should be only created
177 // once per TLB. For timing mode, a new instance is generated for every
178 // TLB miss.
179 DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");
180

--- 10 unchanged lines hidden (view full) ---

191 } else if (_timing) {
192 // This is a translation that was completed and then faulted again
193 // because some underlying parameters that affect the translation
194 // changed out from under us (e.g. asid). It will either be a
195 // misprediction, in which case nothing will happen or we'll use
196 // this fault to re-execute the faulting instruction which should clean
197 // up everything.
198 if (currState->vaddr_tainted == _req->getVaddr()) {
178 WalkerState *savedCurrState = NULL;
179
180 if (!currState && !_functional) {
181 // For atomic mode, a new WalkerState instance should be only created
182 // once per TLB. For timing mode, a new instance is generated for every
183 // TLB miss.
184 DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");
185

--- 10 unchanged lines hidden (view full) ---

196 } else if (_timing) {
197 // This is a translation that was completed and then faulted again
198 // because some underlying parameters that affect the translation
199 // changed out from under us (e.g. asid). It will either be a
200 // misprediction, in which case nothing will happen or we'll use
201 // this fault to re-execute the faulting instruction which should clean
202 // up everything.
203 if (currState->vaddr_tainted == _req->getVaddr()) {
204 ++statSquashedBefore;
199 return std::make_shared<ReExec>();
200 }
201 }
205 return std::make_shared<ReExec>();
206 }
207 }
208 pendingChange();
202
209
210 currState->startTime = curTick();
203 currState->tc = _tc;
204 currState->aarch64 = opModeIs64(currOpMode(_tc));
205 currState->el = currEL(_tc);
206 currState->transState = _trans;
207 currState->req = _req;
208 currState->fault = NoFault;
209 currState->asid = _asid;
210 currState->vmid = _vmid;

--- 45 unchanged lines hidden (view full) ---

256 currState->hcr = currState->tc->readMiscReg(MISCREG_HCR);
257 currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR);
258 }
259 sctlr = currState->sctlr;
260
261 currState->isFetch = (currState->mode == TLB::Execute);
262 currState->isWrite = (currState->mode == TLB::Write);
263
211 currState->tc = _tc;
212 currState->aarch64 = opModeIs64(currOpMode(_tc));
213 currState->el = currEL(_tc);
214 currState->transState = _trans;
215 currState->req = _req;
216 currState->fault = NoFault;
217 currState->asid = _asid;
218 currState->vmid = _vmid;

--- 45 unchanged lines hidden (view full) ---

264 currState->hcr = currState->tc->readMiscReg(MISCREG_HCR);
265 currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR);
266 }
267 sctlr = currState->sctlr;
268
269 currState->isFetch = (currState->mode == TLB::Execute);
270 currState->isWrite = (currState->mode == TLB::Write);
271
272 statRequestOrigin[REQUESTED][currState->isFetch]++;
273
264 // We only do a second stage of translation if we're not secure, or in
265 // hyp mode, the second stage MMU is enabled, and this table walker
266 // instance is the first stage.
267 currState->doingStage2 = false;
268 // @todo: for now disable this in AArch64 (HCR is not set)
269 currState->stage2Req = !currState->aarch64 && currState->hcr.vm &&
270 !isStage2 && !currState->isSecure && !currState->isHyp;
271
272 bool long_desc_format = currState->aarch64 ||
273 (_haveLPAE && currState->ttbcr.eae) ||
274 _isHyp || isStage2;
275
276 if (long_desc_format) {
277 // Helper variables used for hierarchical permissions
278 currState->secureLookup = currState->isSecure;
279 currState->rwTable = true;
280 currState->userTable = true;
281 currState->xnTable = false;
282 currState->pxnTable = false;
274 // We only do a second stage of translation if we're not secure, or in
275 // hyp mode, the second stage MMU is enabled, and this table walker
276 // instance is the first stage.
277 currState->doingStage2 = false;
278 // @todo: for now disable this in AArch64 (HCR is not set)
279 currState->stage2Req = !currState->aarch64 && currState->hcr.vm &&
280 !isStage2 && !currState->isSecure && !currState->isHyp;
281
282 bool long_desc_format = currState->aarch64 ||
283 (_haveLPAE && currState->ttbcr.eae) ||
284 _isHyp || isStage2;
285
286 if (long_desc_format) {
287 // Helper variables used for hierarchical permissions
288 currState->secureLookup = currState->isSecure;
289 currState->rwTable = true;
290 currState->userTable = true;
291 currState->xnTable = false;
292 currState->pxnTable = false;
293
294 ++statWalksLongDescriptor;
295 } else {
296 ++statWalksShortDescriptor;
283 }
284
285 if (!currState->timing) {
286 Fault fault = NoFault;
287 if (currState->aarch64)
288 fault = processWalkAArch64();
289 else if (long_desc_format)
290 fault = processWalkLPAE();

--- 7 unchanged lines hidden (view full) ---

298 currState = savedCurrState;
299 }
300 return fault;
301 }
302
303 if (pending || pendingQueue.size()) {
304 pendingQueue.push_back(currState);
305 currState = NULL;
297 }
298
299 if (!currState->timing) {
300 Fault fault = NoFault;
301 if (currState->aarch64)
302 fault = processWalkAArch64();
303 else if (long_desc_format)
304 fault = processWalkLPAE();

--- 7 unchanged lines hidden (view full) ---

312 currState = savedCurrState;
313 }
314 return fault;
315 }
316
317 if (pending || pendingQueue.size()) {
318 pendingQueue.push_back(currState);
319 currState = NULL;
320 pendingChange();
306 } else {
307 pending = true;
321 } else {
322 pending = true;
323 pendingChange();
308 if (currState->aarch64)
309 return processWalkAArch64();
310 else if (long_desc_format)
311 return processWalkLPAE();
312 else
313 return processWalk();
314 }
315
316 return NoFault;
317}
318
319void
320TableWalker::processWalkWrapper()
321{
322 assert(!currState);
323 assert(pendingQueue.size());
324 if (currState->aarch64)
325 return processWalkAArch64();
326 else if (long_desc_format)
327 return processWalkLPAE();
328 else
329 return processWalk();
330 }
331
332 return NoFault;
333}
334
335void
336TableWalker::processWalkWrapper()
337{
338 assert(!currState);
339 assert(pendingQueue.size());
340 pendingChange();
324 currState = pendingQueue.front();
325
326 ExceptionLevel target_el = EL0;
327 if (currState->aarch64)
328 target_el = currEL(currState->tc);
329 else
330 target_el = EL1;
331

--- 35 unchanged lines hidden (view full) ---

367 // If the instruction that we were translating for has been
368 // squashed we shouldn't bother.
369 unsigned num_squashed = 0;
370 ThreadContext *tc = currState->tc;
371 while ((num_squashed < numSquashable) && currState &&
372 (currState->transState->squashed() || te)) {
373 pendingQueue.pop_front();
374 num_squashed++;
341 currState = pendingQueue.front();
342
343 ExceptionLevel target_el = EL0;
344 if (currState->aarch64)
345 target_el = currEL(currState->tc);
346 else
347 target_el = EL1;
348

--- 35 unchanged lines hidden (view full) ---

384 // If the instruction that we were translating for has been
385 // squashed we shouldn't bother.
386 unsigned num_squashed = 0;
387 ThreadContext *tc = currState->tc;
388 while ((num_squashed < numSquashable) && currState &&
389 (currState->transState->squashed() || te)) {
390 pendingQueue.pop_front();
391 num_squashed++;
392 statSquashedBefore++;
375
376 DPRINTF(TLB, "Squashing table walk for address %#x\n",
377 currState->vaddr_tainted);
378
379 if (currState->transState->squashed()) {
380 // finish the translation which will delete the translation object
381 currState->transState->finish(
382 std::make_shared<UnimpFault>("Squashed Inst"),
383 currState->req, currState->tc, currState->mode);
384 } else {
385 // translate the request now that we know it will work
393
394 DPRINTF(TLB, "Squashing table walk for address %#x\n",
395 currState->vaddr_tainted);
396
397 if (currState->transState->squashed()) {
398 // finish the translation which will delete the translation object
399 currState->transState->finish(
400 std::make_shared<UnimpFault>("Squashed Inst"),
401 currState->req, currState->tc, currState->mode);
402 } else {
403 // translate the request now that we know it will work
404 statWalkServiceTime.sample(curTick() - currState->startTime);
386 tlb->translateTiming(currState->req, currState->tc,
387 currState->transState, currState->mode);
388
389 }
390
391 // delete the current request
392 delete currState;
393
394 // peak at the next one
395 if (pendingQueue.size()) {
396 currState = pendingQueue.front();
397 te = tlb->lookup(currState->vaddr, currState->asid,
398 currState->vmid, currState->isHyp, currState->isSecure, true,
399 false, target_el);
400 } else {
401 // Terminate the loop, nothing more to do
402 currState = NULL;
403 }
404 }
405 tlb->translateTiming(currState->req, currState->tc,
406 currState->transState, currState->mode);
407
408 }
409
410 // delete the current request
411 delete currState;
412
413 // peak at the next one
414 if (pendingQueue.size()) {
415 currState = pendingQueue.front();
416 te = tlb->lookup(currState->vaddr, currState->asid,
417 currState->vmid, currState->isHyp, currState->isSecure, true,
418 false, target_el);
419 } else {
420 // Terminate the loop, nothing more to do
421 currState = NULL;
422 }
423 }
424 pendingChange();
405
425
406 // if we've still got pending translations schedule more work
426 // if we still have pending translations, schedule more work
407 nextWalk(tc);
408 currState = NULL;
409}
410
411Fault
412TableWalker::processWalk()
413{
414 Addr ttbr = 0;
415
416 // If translation isn't enabled, we shouldn't be here
417 assert(currState->sctlr.m || isStage2);
418
419 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
420 currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31,
421 32 - currState->ttbcr.n));
422
427 nextWalk(tc);
428 currState = NULL;
429}
430
431Fault
432TableWalker::processWalk()
433{
434 Addr ttbr = 0;
435
436 // If translation isn't enabled, we shouldn't be here
437 assert(currState->sctlr.m || isStage2);
438
439 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
440 currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31,
441 32 - currState->ttbcr.n));
442
443 statWalkWaitTime.sample(curTick() - currState->startTime);
444
423 if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
424 32 - currState->ttbcr.n)) {
425 DPRINTF(TLB, " - Selecting TTBR0\n");
426 // Check if table walk is allowed when Security Extensions are enabled
427 if (haveSecurity && currState->ttbcr.pd0) {
428 if (currState->isFetch)
429 return std::make_shared<PrefetchAbort>(
430 currState->vaddr_tainted,

--- 75 unchanged lines hidden (view full) ---

506{
507 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
508 int tsz, n;
509 LookupLevel start_lookup_level = L1;
510
511 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
512 currState->vaddr_tainted, currState->ttbcr);
513
445 if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
446 32 - currState->ttbcr.n)) {
447 DPRINTF(TLB, " - Selecting TTBR0\n");
448 // Check if table walk is allowed when Security Extensions are enabled
449 if (haveSecurity && currState->ttbcr.pd0) {
450 if (currState->isFetch)
451 return std::make_shared<PrefetchAbort>(
452 currState->vaddr_tainted,

--- 75 unchanged lines hidden (view full) ---

528{
529 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
530 int tsz, n;
531 LookupLevel start_lookup_level = L1;
532
533 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
534 currState->vaddr_tainted, currState->ttbcr);
535
536 statWalkWaitTime.sample(curTick() - currState->startTime);
537
514 Request::Flags flag = 0;
515 if (currState->isSecure)
516 flag.set(Request::SECURE);
517
518 // work out which base address register to use, if in hyp mode we always
519 // use HTTBR
520 if (isStage2) {
521 DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");

--- 173 unchanged lines hidden (view full) ---

695 DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
696 currState->vaddr_tainted, currState->tcr);
697
698 static const GrainSize GrainMapDefault[] =
699 { Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
700 static const GrainSize GrainMap_EL1_tg1[] =
701 { ReservedGrain, Grain16KB, Grain4KB, Grain64KB };
702
538 Request::Flags flag = 0;
539 if (currState->isSecure)
540 flag.set(Request::SECURE);
541
542 // work out which base address register to use, if in hyp mode we always
543 // use HTTBR
544 if (isStage2) {
545 DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");

--- 173 unchanged lines hidden (view full) ---

719 DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
720 currState->vaddr_tainted, currState->tcr);
721
722 static const GrainSize GrainMapDefault[] =
723 { Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
724 static const GrainSize GrainMap_EL1_tg1[] =
725 { ReservedGrain, Grain16KB, Grain4KB, Grain64KB };
726
727 statWalkWaitTime.sample(curTick() - currState->startTime);
728
703 // Determine TTBR, table size, granule size and phys. address range
704 Addr ttbr = 0;
705 int tsz = 0, ps = 0;
706 GrainSize tg = Grain4KB; // grain size computed from tg* field
707 bool fault = false;
708 switch (currState->el) {
709 case EL0:
710 case EL1:

--- 204 unchanged lines hidden (view full) ---

915 break;
916 case L3:
917 event = (Event *) &doL3LongDescEvent;
918 break;
919 default:
920 panic("Invalid table lookup level");
921 break;
922 }
729 // Determine TTBR, table size, granule size and phys. address range
730 Addr ttbr = 0;
731 int tsz = 0, ps = 0;
732 GrainSize tg = Grain4KB; // grain size computed from tg* field
733 bool fault = false;
734 switch (currState->el) {
735 case EL0:
736 case EL1:

--- 204 unchanged lines hidden (view full) ---

941 break;
942 case L3:
943 event = (Event *) &doL3LongDescEvent;
944 break;
945 default:
946 panic("Invalid table lookup level");
947 break;
948 }
923 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), event,
924 (uint8_t*) &currState->longDesc.data,
949 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
950 event, (uint8_t*) &currState->longDesc.data,
925 currState->tc->getCpuPtr()->clockPeriod(), flag);
926 DPRINTF(TLBVerbose,
927 "Adding to walker fifo: queue size before adding: %d\n",
928 stateQueues[start_lookup_level].size());
929 stateQueues[start_lookup_level].push_back(currState);
930 currState = NULL;
931 } else if (!currState->functional) {
932 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),

--- 760 unchanged lines hidden (view full) ---

1693 DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1694 doL1Descriptor();
1695
1696 stateQueues[L1].pop_front();
1697 // Check if fault was generated
1698 if (currState->fault != NoFault) {
1699 currState->transState->finish(currState->fault, currState->req,
1700 currState->tc, currState->mode);
951 currState->tc->getCpuPtr()->clockPeriod(), flag);
952 DPRINTF(TLBVerbose,
953 "Adding to walker fifo: queue size before adding: %d\n",
954 stateQueues[start_lookup_level].size());
955 stateQueues[start_lookup_level].push_back(currState);
956 currState = NULL;
957 } else if (!currState->functional) {
958 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),

--- 760 unchanged lines hidden (view full) ---

1719 DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1720 doL1Descriptor();
1721
1722 stateQueues[L1].pop_front();
1723 // Check if fault was generated
1724 if (currState->fault != NoFault) {
1725 currState->transState->finish(currState->fault, currState->req,
1726 currState->tc, currState->mode);
1727 statWalksShortTerminatedAtLevel[0]++;
1701
1702 pending = false;
1703 nextWalk(currState->tc);
1704
1705 currState->req = NULL;
1706 currState->tc = NULL;
1707 currState->delayed = false;
1708 delete currState;
1709 }
1710 else if (!currState->delayed) {
1711 // delay is not set so there is no L2 to do
1712 // Don't finish the translation if a stage 2 look up is underway
1713 if (!currState->doingStage2) {
1728
1729 pending = false;
1730 nextWalk(currState->tc);
1731
1732 currState->req = NULL;
1733 currState->tc = NULL;
1734 currState->delayed = false;
1735 delete currState;
1736 }
1737 else if (!currState->delayed) {
1738 // delay is not set so there is no L2 to do
1739 // Don't finish the translation if a stage 2 look up is underway
1740 if (!currState->doingStage2) {
1741 statWalkServiceTime.sample(curTick() - currState->startTime);
1714 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1715 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1716 currState->transState, currState->mode);
1742 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1743 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1744 currState->transState, currState->mode);
1745 statWalksShortTerminatedAtLevel[0]++;
1717 }
1718
1719 pending = false;
1720 nextWalk(currState->tc);
1721
1722 currState->req = NULL;
1723 currState->tc = NULL;
1724 currState->delayed = false;

--- 19 unchanged lines hidden (view full) ---

1744 DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1745 currState->vaddr_tainted);
1746 doL2Descriptor();
1747
1748 // Check if fault was generated
1749 if (currState->fault != NoFault) {
1750 currState->transState->finish(currState->fault, currState->req,
1751 currState->tc, currState->mode);
1746 }
1747
1748 pending = false;
1749 nextWalk(currState->tc);
1750
1751 currState->req = NULL;
1752 currState->tc = NULL;
1753 currState->delayed = false;

--- 19 unchanged lines hidden (view full) ---

1773 DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1774 currState->vaddr_tainted);
1775 doL2Descriptor();
1776
1777 // Check if fault was generated
1778 if (currState->fault != NoFault) {
1779 currState->transState->finish(currState->fault, currState->req,
1780 currState->tc, currState->mode);
1781 statWalksShortTerminatedAtLevel[1]++;
1752 }
1753 else {
1754 // Don't finish the translation if a stage 2 look up is underway
1755 if (!currState->doingStage2) {
1782 }
1783 else {
1784 // Don't finish the translation if a stage 2 look up is underway
1785 if (!currState->doingStage2) {
1786 statWalkServiceTime.sample(curTick() - currState->startTime);
1756 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1757 currState->fault = tlb->translateTiming(currState->req,
1758 currState->tc, currState->transState, currState->mode);
1787 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1788 currState->fault = tlb->translateTiming(currState->req,
1789 currState->tc, currState->transState, currState->mode);
1790 statWalksShortTerminatedAtLevel[1]++;
1759 }
1760 }
1761
1762
1763 stateQueues[L2].pop_front();
1764 pending = false;
1765 nextWalk(currState->tc);
1766

--- 60 unchanged lines hidden (view full) ---

1827 currState->tc = NULL;
1828 currState->delayed = false;
1829 delete currState;
1830 } else if (!currState->delayed) {
1831 // No additional lookups required
1832 // Don't finish the translation if a stage 2 look up is underway
1833 if (!currState->doingStage2) {
1834 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1791 }
1792 }
1793
1794
1795 stateQueues[L2].pop_front();
1796 pending = false;
1797 nextWalk(currState->tc);
1798

--- 60 unchanged lines hidden (view full) ---

1859 currState->tc = NULL;
1860 currState->delayed = false;
1861 delete currState;
1862 } else if (!currState->delayed) {
1863 // No additional lookups required
1864 // Don't finish the translation if a stage 2 look up is underway
1865 if (!currState->doingStage2) {
1866 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1867 statWalkServiceTime.sample(curTick() - currState->startTime);
1835 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1836 currState->transState,
1837 currState->mode);
1868 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1869 currState->transState,
1870 currState->mode);
1871 statWalksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
1838 }
1839
1840 pending = false;
1841 nextWalk(currState->tc);
1842
1843 currState->req = NULL;
1844 currState->tc = NULL;
1845 currState->delayed = false;

--- 55 unchanged lines hidden (view full) ---

1901 currState = NULL;
1902 }
1903 } else {
1904 (this->*doDescriptor)();
1905 }
1906 } else {
1907 if (isTiming) {
1908 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1872 }
1873
1874 pending = false;
1875 nextWalk(currState->tc);
1876
1877 currState->req = NULL;
1878 currState->tc = NULL;
1879 currState->delayed = false;

--- 55 unchanged lines hidden (view full) ---

1935 currState = NULL;
1936 }
1937 } else {
1938 (this->*doDescriptor)();
1939 }
1940 } else {
1941 if (isTiming) {
1942 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1909 currState->tc->getCpuPtr()->clockPeriod(), flags);
1943 currState->tc->getCpuPtr()->clockPeriod(),flags);
1910 if (queueIndex >= 0) {
1911 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1912 stateQueues[queueIndex].size());
1913 stateQueues[queueIndex].push_back(currState);
1914 currState = NULL;
1915 }
1916 } else if (!currState->functional) {
1917 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,

--- 33 unchanged lines hidden (view full) ---

1951 te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
1952 te.nstid = !currState->isSecure;
1953 te.xn = descriptor.xn();
1954 if (currState->aarch64)
1955 te.el = currState->el;
1956 else
1957 te.el = 1;
1958
1944 if (queueIndex >= 0) {
1945 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1946 stateQueues[queueIndex].size());
1947 stateQueues[queueIndex].push_back(currState);
1948 currState = NULL;
1949 }
1950 } else if (!currState->functional) {
1951 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,

--- 33 unchanged lines hidden (view full) ---

1985 te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
1986 te.nstid = !currState->isSecure;
1987 te.xn = descriptor.xn();
1988 if (currState->aarch64)
1989 te.el = currState->el;
1990 else
1991 te.el = 1;
1992
1993 statPageSizes[pageSizeNtoStatBin(te.N)]++;
1994 statRequestOrigin[COMPLETED][currState->isFetch]++;
1995
1959 // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
1960 // as global
1961 te.global = descriptor.global(currState) || isStage2;
1962 if (longDescriptor) {
1963 LongDescriptor lDescriptor =
1964 dynamic_cast<LongDescriptor &>(descriptor);
1965
1966 te.xn |= currState->xnTable;

--- 52 unchanged lines hidden (view full) ---

2019 case L2:
2020 return L2;
2021 case L3:
2022 return L3;
2023 default:
2024 panic("Invalid lookup level conversion");
2025 }
2026}
1996 // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
1997 // as global
1998 te.global = descriptor.global(currState) || isStage2;
1999 if (longDescriptor) {
2000 LongDescriptor lDescriptor =
2001 dynamic_cast<LongDescriptor &>(descriptor);
2002
2003 te.xn |= currState->xnTable;

--- 52 unchanged lines hidden (view full) ---

2056 case L2:
2057 return L2;
2058 case L3:
2059 return L3;
2060 default:
2061 panic("Invalid lookup level conversion");
2062 }
2063}
2064
2065/* this method keeps track of the table walker queue's residency, so
2066 * needs to be called whenever requests start and complete. */
2067void
2068TableWalker::pendingChange()
2069{
2070 unsigned n = pendingQueue.size();
2071 if ((currState != NULL) && (currState != pendingQueue.front())) {
2072 ++n;
2073 }
2074
2075 if (n != pendingReqs) {
2076 Tick now = curTick();
2077 statPendingWalks.sample(pendingReqs, now - pendingChangeTick);
2078 pendingReqs = n;
2079 pendingChangeTick = now;
2080 }
2081}
2082
2083uint8_t
2084TableWalker::pageSizeNtoStatBin(uint8_t N)
2085{
2086 /* for statPageSizes */
2087 switch(N) {
2088 case 12: return 0; // 4K
2089 case 14: return 1; // 16K (using 16K granule in v8-64)
2090 case 16: return 2; // 64K
2091 case 20: return 3; // 1M
2092 case 21: return 4; // 2M-LPAE
2093 case 24: return 5; // 16M
2094 case 25: return 6; // 32M (using 16K granule in v8-64)
2095 case 29: return 7; // 512M (using 64K granule in v8-64)
2096 case 30: return 8; // 1G-LPAE
2097 default:
2098 panic("unknown page size");
2099 return 255;
2100 }
2101}
2102
2103void
2104TableWalker::regStats()
2105{
2106 statWalks
2107 .name(name() + ".walks")
2108 .desc("Table walker walks requested")
2109 ;
2110
2111 statWalksShortDescriptor
2112 .name(name() + ".walksShort")
2113 .desc("Table walker walks initiated with short descriptors")
2114 .flags(Stats::nozero)
2115 ;
2116
2117 statWalksLongDescriptor
2118 .name(name() + ".walksLong")
2119 .desc("Table walker walks initiated with long descriptors")
2120 .flags(Stats::nozero)
2121 ;
2122
2123 statWalksShortTerminatedAtLevel
2124 .init(2)
2125 .name(name() + ".walksShortTerminationLevel")
2126 .desc("Level at which table walker walks "
2127 "with short descriptors terminate")
2128 .flags(Stats::nozero)
2129 ;
2130 statWalksShortTerminatedAtLevel.subname(0, "Level1");
2131 statWalksShortTerminatedAtLevel.subname(1, "Level2");
2132
2133 statWalksLongTerminatedAtLevel
2134 .init(4)
2135 .name(name() + ".walksLongTerminationLevel")
2136 .desc("Level at which table walker walks "
2137 "with long descriptors terminate")
2138 .flags(Stats::nozero)
2139 ;
2140 statWalksLongTerminatedAtLevel.subname(0, "Level0");
2141 statWalksLongTerminatedAtLevel.subname(1, "Level1");
2142 statWalksLongTerminatedAtLevel.subname(2, "Level2");
2143 statWalksLongTerminatedAtLevel.subname(3, "Level3");
2144
2145 statSquashedBefore
2146 .name(name() + ".walksSquashedBefore")
2147 .desc("Table walks squashed before starting")
2148 .flags(Stats::nozero)
2149 ;
2150
2151 statSquashedAfter
2152 .name(name() + ".walksSquashedAfter")
2153 .desc("Table walks squashed after completion")
2154 .flags(Stats::nozero)
2155 ;
2156
2157 statWalkWaitTime
2158 .init(16)
2159 .name(name() + ".walkWaitTime")
2160 .desc("Table walker wait (enqueue to first request) latency")
2161 .flags(Stats::pdf | Stats::nozero | Stats::nonan)
2162 ;
2163
2164 statWalkServiceTime
2165 .init(16)
2166 .name(name() + ".walkCompletionTime")
2167 .desc("Table walker service (enqueue to completion) latency")
2168 .flags(Stats::pdf | Stats::nozero | Stats::nonan)
2169 ;
2170
2171 statPendingWalks
2172 .init(16)
2173 .name(name() + ".walksPending")
2174 .desc("Table walker pending requests distribution")
2175 .flags(Stats::pdf | Stats::dist | Stats::nozero | Stats::nonan)
2176 ;
2177
2178 statPageSizes // see DDI 0487A D4-1661
2179 .init(9)
2180 .name(name() + ".walkPageSizes")
2181 .desc("Table walker page sizes translated")
2182 .flags(Stats::total | Stats::pdf | Stats::dist | Stats::nozero)
2183 ;
2184 statPageSizes.subname(0, "4K");
2185 statPageSizes.subname(1, "16K");
2186 statPageSizes.subname(2, "64K");
2187 statPageSizes.subname(3, "1M");
2188 statPageSizes.subname(4, "2M");
2189 statPageSizes.subname(5, "16M");
2190 statPageSizes.subname(6, "32M");
2191 statPageSizes.subname(7, "512M");
2192 statPageSizes.subname(8, "1G");
2193
2194 statRequestOrigin
2195 .init(2,2) // Instruction/Data, requests/completed
2196 .name(name() + ".walkRequestOrigin")
2197 .desc("Table walker requests started/completed, data/inst")
2198 .flags(Stats::total)
2199 ;
2200 statRequestOrigin.subname(0,"Requested");
2201 statRequestOrigin.subname(1,"Completed");
2202 statRequestOrigin.ysubname(0,"Data");
2203 statRequestOrigin.ysubname(1,"Inst");
2204}