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} |
|