table_walker.cc revision 10509:d5554f97c451
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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Ali Saidi 38 * Giacomo Gabrielli 39 */ 40 41#include <memory> 42 43#include "arch/arm/faults.hh" 44#include "arch/arm/stage2_mmu.hh" 45#include "arch/arm/system.hh" 46#include "arch/arm/table_walker.hh" 47#include "arch/arm/tlb.hh" 48#include "cpu/base.hh" 49#include "cpu/thread_context.hh" 50#include "debug/Checkpoint.hh" 51#include "debug/Drain.hh" 52#include "debug/TLB.hh" 53#include "debug/TLBVerbose.hh" 54#include "sim/system.hh" 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 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 71 if (FullSystem) { 72 armSys = dynamic_cast<ArmSystem *>(p->sys); 73 assert(armSys); 74 haveSecurity = armSys->haveSecurity(); 75 _haveLPAE = armSys->haveLPAE(); 76 _haveVirtualization = armSys->haveVirtualization(); 77 physAddrRange = armSys->physAddrRange(); 78 _haveLargeAsid64 = armSys->haveLargeAsid64(); 79 } else { 80 armSys = NULL; 81 haveSecurity = _haveLPAE = _haveVirtualization = false; 82 _haveLargeAsid64 = false; 83 physAddrRange = 32; 84 } 85 86} 87 88TableWalker::~TableWalker() 89{ 90 ; 91} 92 93TableWalker::WalkerState::WalkerState() : stage2Tran(NULL), l2Desc(l1Desc) 94{ 95} 96 97void 98TableWalker::completeDrain() 99{ 100 if (drainManager && stateQueues[L1].empty() && stateQueues[L2].empty() && 101 pendingQueue.empty()) { 102 setDrainState(Drainable::Drained); 103 DPRINTF(Drain, "TableWalker done draining, processing drain event\n"); 104 drainManager->signalDrainDone(); 105 drainManager = NULL; 106 } 107} 108 109unsigned int 110TableWalker::drain(DrainManager *dm) 111{ 112 unsigned int count = port.drain(dm); 113 114 bool state_queues_not_empty = false; 115 116 for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) { 117 if (!stateQueues[i].empty()) { 118 state_queues_not_empty = true; 119 break; 120 } 121 } 122 123 if (state_queues_not_empty || pendingQueue.size()) { 124 drainManager = dm; 125 setDrainState(Drainable::Draining); 126 DPRINTF(Drain, "TableWalker not drained\n"); 127 128 // return port drain count plus the table walker itself needs to drain 129 return count + 1; 130 } else { 131 setDrainState(Drainable::Drained); 132 DPRINTF(Drain, "TableWalker free, no need to drain\n"); 133 134 // table walker is drained, but its ports may still need to be drained 135 return count; 136 } 137} 138 139void 140TableWalker::drainResume() 141{ 142 Drainable::drainResume(); 143 if (params()->sys->isTimingMode() && currState) { 144 delete currState; 145 currState = NULL; 146 } 147} 148 149BaseMasterPort& 150TableWalker::getMasterPort(const std::string &if_name, PortID idx) 151{ 152 if (if_name == "port") { 153 return port; 154 } 155 return MemObject::getMasterPort(if_name, idx); 156} 157 158Fault 159TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid, 160 uint8_t _vmid, bool _isHyp, TLB::Mode _mode, 161 TLB::Translation *_trans, bool _timing, bool _functional, 162 bool secure, TLB::ArmTranslationType tranType) 163{ 164 assert(!(_functional && _timing)); 165 WalkerState *savedCurrState = NULL; 166 167 if (!currState && !_functional) { 168 // For atomic mode, a new WalkerState instance should be only created 169 // once per TLB. For timing mode, a new instance is generated for every 170 // TLB miss. 171 DPRINTF(TLBVerbose, "creating new instance of WalkerState\n"); 172 173 currState = new WalkerState(); 174 currState->tableWalker = this; 175 } else if (_functional) { 176 // If we are mixing functional mode with timing (or even 177 // atomic), we need to to be careful and clean up after 178 // ourselves to not risk getting into an inconsistent state. 179 DPRINTF(TLBVerbose, "creating functional instance of WalkerState\n"); 180 savedCurrState = currState; 181 currState = new WalkerState(); 182 currState->tableWalker = this; 183 } else if (_timing) { 184 // This is a translation that was completed and then faulted again 185 // because some underlying parameters that affect the translation 186 // changed out from under us (e.g. asid). It will either be a 187 // misprediction, in which case nothing will happen or we'll use 188 // this fault to re-execute the faulting instruction which should clean 189 // up everything. 190 if (currState->vaddr_tainted == _req->getVaddr()) { 191 return std::make_shared<ReExec>(); 192 } 193 } 194 195 currState->tc = _tc; 196 currState->aarch64 = opModeIs64(currOpMode(_tc)); 197 currState->el = currEL(_tc); 198 currState->transState = _trans; 199 currState->req = _req; 200 currState->fault = NoFault; 201 currState->asid = _asid; 202 currState->vmid = _vmid; 203 currState->isHyp = _isHyp; 204 currState->timing = _timing; 205 currState->functional = _functional; 206 currState->mode = _mode; 207 currState->tranType = tranType; 208 currState->isSecure = secure; 209 currState->physAddrRange = physAddrRange; 210 211 /** @todo These should be cached or grabbed from cached copies in 212 the TLB, all these miscreg reads are expensive */ 213 currState->vaddr_tainted = currState->req->getVaddr(); 214 if (currState->aarch64) 215 currState->vaddr = purifyTaggedAddr(currState->vaddr_tainted, 216 currState->tc, currState->el); 217 else 218 currState->vaddr = currState->vaddr_tainted; 219 220 if (currState->aarch64) { 221 switch (currState->el) { 222 case EL0: 223 case EL1: 224 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1); 225 currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1); 226 break; 227 // @todo: uncomment this to enable Virtualization 228 // case EL2: 229 // assert(haveVirtualization); 230 // currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2); 231 // currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2); 232 // break; 233 case EL3: 234 assert(haveSecurity); 235 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL3); 236 currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL3); 237 break; 238 default: 239 panic("Invalid exception level"); 240 break; 241 } 242 } else { 243 currState->sctlr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 244 MISCREG_SCTLR, currState->tc, !currState->isSecure)); 245 currState->ttbcr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 246 MISCREG_TTBCR, currState->tc, !currState->isSecure)); 247 currState->htcr = currState->tc->readMiscReg(MISCREG_HTCR); 248 currState->hcr = currState->tc->readMiscReg(MISCREG_HCR); 249 currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR); 250 } 251 sctlr = currState->sctlr; 252 253 currState->isFetch = (currState->mode == TLB::Execute); 254 currState->isWrite = (currState->mode == TLB::Write); 255 256 // We only do a second stage of translation if we're not secure, or in 257 // hyp mode, the second stage MMU is enabled, and this table walker 258 // instance is the first stage. 259 currState->doingStage2 = false; 260 // @todo: for now disable this in AArch64 (HCR is not set) 261 currState->stage2Req = !currState->aarch64 && currState->hcr.vm && 262 !isStage2 && !currState->isSecure && !currState->isHyp; 263 264 bool long_desc_format = currState->aarch64 || 265 (_haveLPAE && currState->ttbcr.eae) || 266 _isHyp || isStage2; 267 268 if (long_desc_format) { 269 // Helper variables used for hierarchical permissions 270 currState->secureLookup = currState->isSecure; 271 currState->rwTable = true; 272 currState->userTable = true; 273 currState->xnTable = false; 274 currState->pxnTable = false; 275 } 276 277 if (!currState->timing) { 278 Fault fault = NoFault; 279 if (currState->aarch64) 280 fault = processWalkAArch64(); 281 else if (long_desc_format) 282 fault = processWalkLPAE(); 283 else 284 fault = processWalk(); 285 286 // If this was a functional non-timing access restore state to 287 // how we found it. 288 if (currState->functional) { 289 delete currState; 290 currState = savedCurrState; 291 } 292 return fault; 293 } 294 295 if (pending || pendingQueue.size()) { 296 pendingQueue.push_back(currState); 297 currState = NULL; 298 } else { 299 pending = true; 300 if (currState->aarch64) 301 return processWalkAArch64(); 302 else if (long_desc_format) 303 return processWalkLPAE(); 304 else 305 return processWalk(); 306 } 307 308 return NoFault; 309} 310 311void 312TableWalker::processWalkWrapper() 313{ 314 assert(!currState); 315 assert(pendingQueue.size()); 316 currState = pendingQueue.front(); 317 318 ExceptionLevel target_el = EL0; 319 if (currState->aarch64) 320 target_el = currEL(currState->tc); 321 else 322 target_el = EL1; 323 324 // Check if a previous walk filled this request already 325 // @TODO Should this always be the TLB or should we look in the stage2 TLB? 326 TlbEntry* te = tlb->lookup(currState->vaddr, currState->asid, 327 currState->vmid, currState->isHyp, currState->isSecure, true, false, 328 target_el); 329 330 // Check if we still need to have a walk for this request. If the requesting 331 // instruction has been squashed, or a previous walk has filled the TLB with 332 // a match, we just want to get rid of the walk. The latter could happen 333 // when there are multiple outstanding misses to a single page and a 334 // previous request has been successfully translated. 335 if (!currState->transState->squashed() && !te) { 336 // We've got a valid request, lets process it 337 pending = true; 338 pendingQueue.pop_front(); 339 if (currState->aarch64) 340 processWalkAArch64(); 341 else if ((_haveLPAE && currState->ttbcr.eae) || currState->isHyp || isStage2) 342 processWalkLPAE(); 343 else 344 processWalk(); 345 return; 346 } 347 348 349 // If the instruction that we were translating for has been 350 // squashed we shouldn't bother. 351 unsigned num_squashed = 0; 352 ThreadContext *tc = currState->tc; 353 while ((num_squashed < numSquashable) && currState && 354 (currState->transState->squashed() || te)) { 355 pendingQueue.pop_front(); 356 num_squashed++; 357 358 DPRINTF(TLB, "Squashing table walk for address %#x\n", 359 currState->vaddr_tainted); 360 361 if (currState->transState->squashed()) { 362 // finish the translation which will delete the translation object 363 currState->transState->finish( 364 std::make_shared<UnimpFault>("Squashed Inst"), 365 currState->req, currState->tc, currState->mode); 366 } else { 367 // translate the request now that we know it will work 368 tlb->translateTiming(currState->req, currState->tc, 369 currState->transState, currState->mode); 370 371 } 372 373 // delete the current request 374 delete currState; 375 376 // peak at the next one 377 if (pendingQueue.size()) { 378 currState = pendingQueue.front(); 379 te = tlb->lookup(currState->vaddr, currState->asid, 380 currState->vmid, currState->isHyp, currState->isSecure, true, 381 false, target_el); 382 } else { 383 // Terminate the loop, nothing more to do 384 currState = NULL; 385 } 386 } 387 388 // if we've still got pending translations schedule more work 389 nextWalk(tc); 390 currState = NULL; 391} 392 393Fault 394TableWalker::processWalk() 395{ 396 Addr ttbr = 0; 397 398 // If translation isn't enabled, we shouldn't be here 399 assert(currState->sctlr.m || isStage2); 400 401 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n", 402 currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31, 403 32 - currState->ttbcr.n)); 404 405 if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31, 406 32 - currState->ttbcr.n)) { 407 DPRINTF(TLB, " - Selecting TTBR0\n"); 408 // Check if table walk is allowed when Security Extensions are enabled 409 if (haveSecurity && currState->ttbcr.pd0) { 410 if (currState->isFetch) 411 return std::make_shared<PrefetchAbort>( 412 currState->vaddr_tainted, 413 ArmFault::TranslationLL + L1, 414 isStage2, 415 ArmFault::VmsaTran); 416 else 417 return std::make_shared<DataAbort>( 418 currState->vaddr_tainted, 419 TlbEntry::DomainType::NoAccess, currState->isWrite, 420 ArmFault::TranslationLL + L1, isStage2, 421 ArmFault::VmsaTran); 422 } 423 ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 424 MISCREG_TTBR0, currState->tc, !currState->isSecure)); 425 } else { 426 DPRINTF(TLB, " - Selecting TTBR1\n"); 427 // Check if table walk is allowed when Security Extensions are enabled 428 if (haveSecurity && currState->ttbcr.pd1) { 429 if (currState->isFetch) 430 return std::make_shared<PrefetchAbort>( 431 currState->vaddr_tainted, 432 ArmFault::TranslationLL + L1, 433 isStage2, 434 ArmFault::VmsaTran); 435 else 436 return std::make_shared<DataAbort>( 437 currState->vaddr_tainted, 438 TlbEntry::DomainType::NoAccess, currState->isWrite, 439 ArmFault::TranslationLL + L1, isStage2, 440 ArmFault::VmsaTran); 441 } 442 ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 443 MISCREG_TTBR1, currState->tc, !currState->isSecure)); 444 currState->ttbcr.n = 0; 445 } 446 447 Addr l1desc_addr = mbits(ttbr, 31, 14 - currState->ttbcr.n) | 448 (bits(currState->vaddr, 31 - currState->ttbcr.n, 20) << 2); 449 DPRINTF(TLB, " - Descriptor at address %#x (%s)\n", l1desc_addr, 450 currState->isSecure ? "s" : "ns"); 451 452 // Trickbox address check 453 Fault f; 454 f = tlb->walkTrickBoxCheck(l1desc_addr, currState->isSecure, 455 currState->vaddr, sizeof(uint32_t), currState->isFetch, 456 currState->isWrite, TlbEntry::DomainType::NoAccess, L1); 457 if (f) { 458 DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted); 459 if (currState->timing) { 460 pending = false; 461 nextWalk(currState->tc); 462 currState = NULL; 463 } else { 464 currState->tc = NULL; 465 currState->req = NULL; 466 } 467 return f; 468 } 469 470 Request::Flags flag = 0; 471 if (currState->sctlr.c == 0) { 472 flag = Request::UNCACHEABLE; 473 } 474 475 bool delayed; 476 delayed = fetchDescriptor(l1desc_addr, (uint8_t*)&currState->l1Desc.data, 477 sizeof(uint32_t), flag, L1, &doL1DescEvent, 478 &TableWalker::doL1Descriptor); 479 if (!delayed) { 480 f = currState->fault; 481 } 482 483 return f; 484} 485 486Fault 487TableWalker::processWalkLPAE() 488{ 489 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr; 490 int tsz, n; 491 LookupLevel start_lookup_level = L1; 492 493 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n", 494 currState->vaddr_tainted, currState->ttbcr); 495 496 Request::Flags flag = 0; 497 if (currState->isSecure) 498 flag.set(Request::SECURE); 499 500 // work out which base address register to use, if in hyp mode we always 501 // use HTTBR 502 if (isStage2) { 503 DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n"); 504 ttbr = currState->tc->readMiscReg(MISCREG_VTTBR); 505 tsz = sext<4>(currState->vtcr.t0sz); 506 start_lookup_level = currState->vtcr.sl0 ? L1 : L2; 507 } else if (currState->isHyp) { 508 DPRINTF(TLB, " - Selecting HTTBR (long-desc.)\n"); 509 ttbr = currState->tc->readMiscReg(MISCREG_HTTBR); 510 tsz = currState->htcr.t0sz; 511 } else { 512 assert(_haveLPAE && currState->ttbcr.eae); 513 514 // Determine boundaries of TTBR0/1 regions 515 if (currState->ttbcr.t0sz) 516 ttbr0_max = (1ULL << (32 - currState->ttbcr.t0sz)) - 1; 517 else if (currState->ttbcr.t1sz) 518 ttbr0_max = (1ULL << 32) - 519 (1ULL << (32 - currState->ttbcr.t1sz)) - 1; 520 else 521 ttbr0_max = (1ULL << 32) - 1; 522 if (currState->ttbcr.t1sz) 523 ttbr1_min = (1ULL << 32) - (1ULL << (32 - currState->ttbcr.t1sz)); 524 else 525 ttbr1_min = (1ULL << (32 - currState->ttbcr.t0sz)); 526 527 // The following code snippet selects the appropriate translation table base 528 // address (TTBR0 or TTBR1) and the appropriate starting lookup level 529 // depending on the address range supported by the translation table (ARM 530 // ARM issue C B3.6.4) 531 if (currState->vaddr <= ttbr0_max) { 532 DPRINTF(TLB, " - Selecting TTBR0 (long-desc.)\n"); 533 // Check if table walk is allowed 534 if (currState->ttbcr.epd0) { 535 if (currState->isFetch) 536 return std::make_shared<PrefetchAbort>( 537 currState->vaddr_tainted, 538 ArmFault::TranslationLL + L1, 539 isStage2, 540 ArmFault::LpaeTran); 541 else 542 return std::make_shared<DataAbort>( 543 currState->vaddr_tainted, 544 TlbEntry::DomainType::NoAccess, 545 currState->isWrite, 546 ArmFault::TranslationLL + L1, 547 isStage2, 548 ArmFault::LpaeTran); 549 } 550 ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 551 MISCREG_TTBR0, currState->tc, !currState->isSecure)); 552 tsz = currState->ttbcr.t0sz; 553 if (ttbr0_max < (1ULL << 30)) // Upper limit < 1 GB 554 start_lookup_level = L2; 555 } else if (currState->vaddr >= ttbr1_min) { 556 DPRINTF(TLB, " - Selecting TTBR1 (long-desc.)\n"); 557 // Check if table walk is allowed 558 if (currState->ttbcr.epd1) { 559 if (currState->isFetch) 560 return std::make_shared<PrefetchAbort>( 561 currState->vaddr_tainted, 562 ArmFault::TranslationLL + L1, 563 isStage2, 564 ArmFault::LpaeTran); 565 else 566 return std::make_shared<DataAbort>( 567 currState->vaddr_tainted, 568 TlbEntry::DomainType::NoAccess, 569 currState->isWrite, 570 ArmFault::TranslationLL + L1, 571 isStage2, 572 ArmFault::LpaeTran); 573 } 574 ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 575 MISCREG_TTBR1, currState->tc, !currState->isSecure)); 576 tsz = currState->ttbcr.t1sz; 577 if (ttbr1_min >= (1ULL << 31) + (1ULL << 30)) // Lower limit >= 3 GB 578 start_lookup_level = L2; 579 } else { 580 // Out of boundaries -> translation fault 581 if (currState->isFetch) 582 return std::make_shared<PrefetchAbort>( 583 currState->vaddr_tainted, 584 ArmFault::TranslationLL + L1, 585 isStage2, 586 ArmFault::LpaeTran); 587 else 588 return std::make_shared<DataAbort>( 589 currState->vaddr_tainted, 590 TlbEntry::DomainType::NoAccess, 591 currState->isWrite, ArmFault::TranslationLL + L1, 592 isStage2, ArmFault::LpaeTran); 593 } 594 595 } 596 597 // Perform lookup (ARM ARM issue C B3.6.6) 598 if (start_lookup_level == L1) { 599 n = 5 - tsz; 600 desc_addr = mbits(ttbr, 39, n) | 601 (bits(currState->vaddr, n + 26, 30) << 3); 602 DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n", 603 desc_addr, currState->isSecure ? "s" : "ns"); 604 } else { 605 // Skip first-level lookup 606 n = (tsz >= 2 ? 14 - tsz : 12); 607 desc_addr = mbits(ttbr, 39, n) | 608 (bits(currState->vaddr, n + 17, 21) << 3); 609 DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n", 610 desc_addr, currState->isSecure ? "s" : "ns"); 611 } 612 613 // Trickbox address check 614 Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure, 615 currState->vaddr, sizeof(uint64_t), currState->isFetch, 616 currState->isWrite, TlbEntry::DomainType::NoAccess, 617 start_lookup_level); 618 if (f) { 619 DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted); 620 if (currState->timing) { 621 pending = false; 622 nextWalk(currState->tc); 623 currState = NULL; 624 } else { 625 currState->tc = NULL; 626 currState->req = NULL; 627 } 628 return f; 629 } 630 631 if (currState->sctlr.c == 0) { 632 flag = Request::UNCACHEABLE; 633 } 634 635 if (currState->isSecure) 636 flag.set(Request::SECURE); 637 638 currState->longDesc.lookupLevel = start_lookup_level; 639 currState->longDesc.aarch64 = false; 640 currState->longDesc.grainSize = Grain4KB; 641 642 Event *event = start_lookup_level == L1 ? (Event *) &doL1LongDescEvent 643 : (Event *) &doL2LongDescEvent; 644 645 bool delayed = fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data, 646 sizeof(uint64_t), flag, start_lookup_level, 647 event, &TableWalker::doLongDescriptor); 648 if (!delayed) { 649 f = currState->fault; 650 } 651 652 return f; 653} 654 655unsigned 656TableWalker::adjustTableSizeAArch64(unsigned tsz) 657{ 658 if (tsz < 25) 659 return 25; 660 if (tsz > 48) 661 return 48; 662 return tsz; 663} 664 665bool 666TableWalker::checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange) 667{ 668 return (currPhysAddrRange != MaxPhysAddrRange && 669 bits(addr, MaxPhysAddrRange - 1, currPhysAddrRange)); 670} 671 672Fault 673TableWalker::processWalkAArch64() 674{ 675 assert(currState->aarch64); 676 677 DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n", 678 currState->vaddr_tainted, currState->tcr); 679 680 static const GrainSize GrainMapDefault[] = 681 { Grain4KB, Grain64KB, Grain16KB, ReservedGrain }; 682 static const GrainSize GrainMap_EL1_tg1[] = 683 { ReservedGrain, Grain16KB, Grain4KB, Grain64KB }; 684 685 // Determine TTBR, table size, granule size and phys. address range 686 Addr ttbr = 0; 687 int tsz = 0, ps = 0; 688 GrainSize tg = Grain4KB; // grain size computed from tg* field 689 bool fault = false; 690 switch (currState->el) { 691 case EL0: 692 case EL1: 693 switch (bits(currState->vaddr, 63,48)) { 694 case 0: 695 DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); 696 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1); 697 tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); 698 tg = GrainMapDefault[currState->tcr.tg0]; 699 if (bits(currState->vaddr, 63, tsz) != 0x0 || 700 currState->tcr.epd0) 701 fault = true; 702 break; 703 case 0xffff: 704 DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n"); 705 ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1); 706 tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz); 707 tg = GrainMap_EL1_tg1[currState->tcr.tg1]; 708 if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) || 709 currState->tcr.epd1) 710 fault = true; 711 break; 712 default: 713 // top two bytes must be all 0s or all 1s, else invalid addr 714 fault = true; 715 } 716 ps = currState->tcr.ips; 717 break; 718 case EL2: 719 case EL3: 720 switch(bits(currState->vaddr, 63,48)) { 721 case 0: 722 DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); 723 if (currState->el == EL2) 724 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2); 725 else 726 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3); 727 tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); 728 tg = GrainMapDefault[currState->tcr.tg0]; 729 break; 730 default: 731 // invalid addr if top two bytes are not all 0s 732 fault = true; 733 } 734 ps = currState->tcr.ips; 735 break; 736 } 737 738 if (fault) { 739 Fault f; 740 if (currState->isFetch) 741 f = std::make_shared<PrefetchAbort>( 742 currState->vaddr_tainted, 743 ArmFault::TranslationLL + L0, isStage2, 744 ArmFault::LpaeTran); 745 else 746 f = std::make_shared<DataAbort>( 747 currState->vaddr_tainted, 748 TlbEntry::DomainType::NoAccess, 749 currState->isWrite, 750 ArmFault::TranslationLL + L0, 751 isStage2, ArmFault::LpaeTran); 752 753 if (currState->timing) { 754 pending = false; 755 nextWalk(currState->tc); 756 currState = NULL; 757 } else { 758 currState->tc = NULL; 759 currState->req = NULL; 760 } 761 return f; 762 763 } 764 765 if (tg == ReservedGrain) { 766 warn_once("Reserved granule size requested; gem5's IMPLEMENTATION " 767 "DEFINED behavior takes this to mean 4KB granules\n"); 768 tg = Grain4KB; 769 } 770 771 int stride = tg - 3; 772 LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; 773 774 // Determine starting lookup level 775 // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library 776 // in ARM DDI 0487A. These table values correspond to the cascading tests 777 // to compute the lookup level and are of the form 778 // (grain_size + N*stride), for N = {1, 2, 3}. 779 // A value of 64 will never succeed and a value of 0 will always succeed. 780 { 781 struct GrainMap { 782 GrainSize grain_size; 783 unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS]; 784 }; 785 static const GrainMap GM[] = { 786 { Grain4KB, { 39, 30, 0, 0 } }, 787 { Grain16KB, { 47, 36, 25, 0 } }, 788 { Grain64KB, { 64, 42, 29, 0 } } 789 }; 790 791 const unsigned *lookup = NULL; // points to a lookup_level_cutoff 792 793 for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[] 794 if (tg == GM[i].grain_size) { 795 lookup = GM[i].lookup_level_cutoff; 796 break; 797 } 798 } 799 assert(lookup); 800 801 for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) { 802 if (tsz > lookup[L]) { 803 start_lookup_level = (LookupLevel) L; 804 break; 805 } 806 } 807 panic_if(start_lookup_level == MAX_LOOKUP_LEVELS, 808 "Table walker couldn't find lookup level\n"); 809 } 810 811 // Determine table base address 812 int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg; 813 Addr base_addr = mbits(ttbr, 47, base_addr_lo); 814 815 // Determine physical address size and raise an Address Size Fault if 816 // necessary 817 int pa_range = decodePhysAddrRange64(ps); 818 // Clamp to lower limit 819 if (pa_range > physAddrRange) 820 currState->physAddrRange = physAddrRange; 821 else 822 currState->physAddrRange = pa_range; 823 if (checkAddrSizeFaultAArch64(base_addr, currState->physAddrRange)) { 824 DPRINTF(TLB, "Address size fault before any lookup\n"); 825 Fault f; 826 if (currState->isFetch) 827 f = std::make_shared<PrefetchAbort>( 828 currState->vaddr_tainted, 829 ArmFault::AddressSizeLL + start_lookup_level, 830 isStage2, 831 ArmFault::LpaeTran); 832 else 833 f = std::make_shared<DataAbort>( 834 currState->vaddr_tainted, 835 TlbEntry::DomainType::NoAccess, 836 currState->isWrite, 837 ArmFault::AddressSizeLL + start_lookup_level, 838 isStage2, 839 ArmFault::LpaeTran); 840 841 842 if (currState->timing) { 843 pending = false; 844 nextWalk(currState->tc); 845 currState = NULL; 846 } else { 847 currState->tc = NULL; 848 currState->req = NULL; 849 } 850 return f; 851 852 } 853 854 // Determine descriptor address 855 Addr desc_addr = base_addr | 856 (bits(currState->vaddr, tsz - 1, 857 stride * (3 - start_lookup_level) + tg) << 3); 858 859 // Trickbox address check 860 Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure, 861 currState->vaddr, sizeof(uint64_t), currState->isFetch, 862 currState->isWrite, TlbEntry::DomainType::NoAccess, 863 start_lookup_level); 864 if (f) { 865 DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted); 866 if (currState->timing) { 867 pending = false; 868 nextWalk(currState->tc); 869 currState = NULL; 870 } else { 871 currState->tc = NULL; 872 currState->req = NULL; 873 } 874 return f; 875 } 876 877 Request::Flags flag = 0; 878 if (currState->sctlr.c == 0) { 879 flag = Request::UNCACHEABLE; 880 } 881 882 currState->longDesc.lookupLevel = start_lookup_level; 883 currState->longDesc.aarch64 = true; 884 currState->longDesc.grainSize = tg; 885 886 if (currState->timing) { 887 Event *event; 888 switch (start_lookup_level) { 889 case L0: 890 event = (Event *) &doL0LongDescEvent; 891 break; 892 case L1: 893 event = (Event *) &doL1LongDescEvent; 894 break; 895 case L2: 896 event = (Event *) &doL2LongDescEvent; 897 break; 898 case L3: 899 event = (Event *) &doL3LongDescEvent; 900 break; 901 default: 902 panic("Invalid table lookup level"); 903 break; 904 } 905 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), event, 906 (uint8_t*) &currState->longDesc.data, 907 currState->tc->getCpuPtr()->clockPeriod(), flag); 908 DPRINTF(TLBVerbose, 909 "Adding to walker fifo: queue size before adding: %d\n", 910 stateQueues[start_lookup_level].size()); 911 stateQueues[start_lookup_level].push_back(currState); 912 currState = NULL; 913 } else if (!currState->functional) { 914 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), 915 NULL, (uint8_t*) &currState->longDesc.data, 916 currState->tc->getCpuPtr()->clockPeriod(), flag); 917 doLongDescriptor(); 918 f = currState->fault; 919 } else { 920 RequestPtr req = new Request(desc_addr, sizeof(uint64_t), flag, 921 masterId); 922 PacketPtr pkt = new Packet(req, MemCmd::ReadReq); 923 pkt->dataStatic((uint8_t*) &currState->longDesc.data); 924 port.sendFunctional(pkt); 925 doLongDescriptor(); 926 delete req; 927 delete pkt; 928 f = currState->fault; 929 } 930 931 return f; 932} 933 934void 935TableWalker::memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, 936 uint8_t texcb, bool s) 937{ 938 // Note: tc and sctlr local variables are hiding tc and sctrl class 939 // variables 940 DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s); 941 te.shareable = false; // default value 942 te.nonCacheable = false; 943 te.outerShareable = false; 944 if (sctlr.tre == 0 || ((sctlr.tre == 1) && (sctlr.m == 0))) { 945 switch(texcb) { 946 case 0: // Stongly-ordered 947 te.nonCacheable = true; 948 te.mtype = TlbEntry::MemoryType::StronglyOrdered; 949 te.shareable = true; 950 te.innerAttrs = 1; 951 te.outerAttrs = 0; 952 break; 953 case 1: // Shareable Device 954 te.nonCacheable = true; 955 te.mtype = TlbEntry::MemoryType::Device; 956 te.shareable = true; 957 te.innerAttrs = 3; 958 te.outerAttrs = 0; 959 break; 960 case 2: // Outer and Inner Write-Through, no Write-Allocate 961 te.mtype = TlbEntry::MemoryType::Normal; 962 te.shareable = s; 963 te.innerAttrs = 6; 964 te.outerAttrs = bits(texcb, 1, 0); 965 break; 966 case 3: // Outer and Inner Write-Back, no Write-Allocate 967 te.mtype = TlbEntry::MemoryType::Normal; 968 te.shareable = s; 969 te.innerAttrs = 7; 970 te.outerAttrs = bits(texcb, 1, 0); 971 break; 972 case 4: // Outer and Inner Non-cacheable 973 te.nonCacheable = true; 974 te.mtype = TlbEntry::MemoryType::Normal; 975 te.shareable = s; 976 te.innerAttrs = 0; 977 te.outerAttrs = bits(texcb, 1, 0); 978 break; 979 case 5: // Reserved 980 panic("Reserved texcb value!\n"); 981 break; 982 case 6: // Implementation Defined 983 panic("Implementation-defined texcb value!\n"); 984 break; 985 case 7: // Outer and Inner Write-Back, Write-Allocate 986 te.mtype = TlbEntry::MemoryType::Normal; 987 te.shareable = s; 988 te.innerAttrs = 5; 989 te.outerAttrs = 1; 990 break; 991 case 8: // Non-shareable Device 992 te.nonCacheable = true; 993 te.mtype = TlbEntry::MemoryType::Device; 994 te.shareable = false; 995 te.innerAttrs = 3; 996 te.outerAttrs = 0; 997 break; 998 case 9 ... 15: // Reserved 999 panic("Reserved texcb value!\n"); 1000 break; 1001 case 16 ... 31: // Cacheable Memory 1002 te.mtype = TlbEntry::MemoryType::Normal; 1003 te.shareable = s; 1004 if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0) 1005 te.nonCacheable = true; 1006 te.innerAttrs = bits(texcb, 1, 0); 1007 te.outerAttrs = bits(texcb, 3, 2); 1008 break; 1009 default: 1010 panic("More than 32 states for 5 bits?\n"); 1011 } 1012 } else { 1013 assert(tc); 1014 PRRR prrr = tc->readMiscReg(flattenMiscRegNsBanked(MISCREG_PRRR, 1015 currState->tc, !currState->isSecure)); 1016 NMRR nmrr = tc->readMiscReg(flattenMiscRegNsBanked(MISCREG_NMRR, 1017 currState->tc, !currState->isSecure)); 1018 DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr); 1019 uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0; 1020 switch(bits(texcb, 2,0)) { 1021 case 0: 1022 curr_tr = prrr.tr0; 1023 curr_ir = nmrr.ir0; 1024 curr_or = nmrr.or0; 1025 te.outerShareable = (prrr.nos0 == 0); 1026 break; 1027 case 1: 1028 curr_tr = prrr.tr1; 1029 curr_ir = nmrr.ir1; 1030 curr_or = nmrr.or1; 1031 te.outerShareable = (prrr.nos1 == 0); 1032 break; 1033 case 2: 1034 curr_tr = prrr.tr2; 1035 curr_ir = nmrr.ir2; 1036 curr_or = nmrr.or2; 1037 te.outerShareable = (prrr.nos2 == 0); 1038 break; 1039 case 3: 1040 curr_tr = prrr.tr3; 1041 curr_ir = nmrr.ir3; 1042 curr_or = nmrr.or3; 1043 te.outerShareable = (prrr.nos3 == 0); 1044 break; 1045 case 4: 1046 curr_tr = prrr.tr4; 1047 curr_ir = nmrr.ir4; 1048 curr_or = nmrr.or4; 1049 te.outerShareable = (prrr.nos4 == 0); 1050 break; 1051 case 5: 1052 curr_tr = prrr.tr5; 1053 curr_ir = nmrr.ir5; 1054 curr_or = nmrr.or5; 1055 te.outerShareable = (prrr.nos5 == 0); 1056 break; 1057 case 6: 1058 panic("Imp defined type\n"); 1059 case 7: 1060 curr_tr = prrr.tr7; 1061 curr_ir = nmrr.ir7; 1062 curr_or = nmrr.or7; 1063 te.outerShareable = (prrr.nos7 == 0); 1064 break; 1065 } 1066 1067 switch(curr_tr) { 1068 case 0: 1069 DPRINTF(TLBVerbose, "StronglyOrdered\n"); 1070 te.mtype = TlbEntry::MemoryType::StronglyOrdered; 1071 te.nonCacheable = true; 1072 te.innerAttrs = 1; 1073 te.outerAttrs = 0; 1074 te.shareable = true; 1075 break; 1076 case 1: 1077 DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n", 1078 prrr.ds1, prrr.ds0, s); 1079 te.mtype = TlbEntry::MemoryType::Device; 1080 te.nonCacheable = true; 1081 te.innerAttrs = 3; 1082 te.outerAttrs = 0; 1083 if (prrr.ds1 && s) 1084 te.shareable = true; 1085 if (prrr.ds0 && !s) 1086 te.shareable = true; 1087 break; 1088 case 2: 1089 DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n", 1090 prrr.ns1, prrr.ns0, s); 1091 te.mtype = TlbEntry::MemoryType::Normal; 1092 if (prrr.ns1 && s) 1093 te.shareable = true; 1094 if (prrr.ns0 && !s) 1095 te.shareable = true; 1096 break; 1097 case 3: 1098 panic("Reserved type"); 1099 } 1100 1101 if (te.mtype == TlbEntry::MemoryType::Normal){ 1102 switch(curr_ir) { 1103 case 0: 1104 te.nonCacheable = true; 1105 te.innerAttrs = 0; 1106 break; 1107 case 1: 1108 te.innerAttrs = 5; 1109 break; 1110 case 2: 1111 te.innerAttrs = 6; 1112 break; 1113 case 3: 1114 te.innerAttrs = 7; 1115 break; 1116 } 1117 1118 switch(curr_or) { 1119 case 0: 1120 te.nonCacheable = true; 1121 te.outerAttrs = 0; 1122 break; 1123 case 1: 1124 te.outerAttrs = 1; 1125 break; 1126 case 2: 1127 te.outerAttrs = 2; 1128 break; 1129 case 3: 1130 te.outerAttrs = 3; 1131 break; 1132 } 1133 } 1134 } 1135 DPRINTF(TLBVerbose, "memAttrs: shareable: %d, innerAttrs: %d, " 1136 "outerAttrs: %d\n", 1137 te.shareable, te.innerAttrs, te.outerAttrs); 1138 te.setAttributes(false); 1139} 1140 1141void 1142TableWalker::memAttrsLPAE(ThreadContext *tc, TlbEntry &te, 1143 LongDescriptor &lDescriptor) 1144{ 1145 assert(_haveLPAE); 1146 1147 uint8_t attr; 1148 uint8_t sh = lDescriptor.sh(); 1149 // Different format and source of attributes if this is a stage 2 1150 // translation 1151 if (isStage2) { 1152 attr = lDescriptor.memAttr(); 1153 uint8_t attr_3_2 = (attr >> 2) & 0x3; 1154 uint8_t attr_1_0 = attr & 0x3; 1155 1156 DPRINTF(TLBVerbose, "memAttrsLPAE MemAttr:%#x sh:%#x\n", attr, sh); 1157 1158 if (attr_3_2 == 0) { 1159 te.mtype = attr_1_0 == 0 ? TlbEntry::MemoryType::StronglyOrdered 1160 : TlbEntry::MemoryType::Device; 1161 te.outerAttrs = 0; 1162 te.innerAttrs = attr_1_0 == 0 ? 1 : 3; 1163 te.nonCacheable = true; 1164 } else { 1165 te.mtype = TlbEntry::MemoryType::Normal; 1166 te.outerAttrs = attr_3_2 == 1 ? 0 : 1167 attr_3_2 == 2 ? 2 : 1; 1168 te.innerAttrs = attr_1_0 == 1 ? 0 : 1169 attr_1_0 == 2 ? 6 : 5; 1170 te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1); 1171 } 1172 } else { 1173 uint8_t attrIndx = lDescriptor.attrIndx(); 1174 1175 // LPAE always uses remapping of memory attributes, irrespective of the 1176 // value of SCTLR.TRE 1177 MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0; 1178 int reg_as_int = flattenMiscRegNsBanked(reg, currState->tc, 1179 !currState->isSecure); 1180 uint32_t mair = currState->tc->readMiscReg(reg_as_int); 1181 attr = (mair >> (8 * (attrIndx % 4))) & 0xff; 1182 uint8_t attr_7_4 = bits(attr, 7, 4); 1183 uint8_t attr_3_0 = bits(attr, 3, 0); 1184 DPRINTF(TLBVerbose, "memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx, sh, attr); 1185 1186 // Note: the memory subsystem only cares about the 'cacheable' memory 1187 // attribute. The other attributes are only used to fill the PAR register 1188 // accordingly to provide the illusion of full support 1189 te.nonCacheable = false; 1190 1191 switch (attr_7_4) { 1192 case 0x0: 1193 // Strongly-ordered or Device memory 1194 if (attr_3_0 == 0x0) 1195 te.mtype = TlbEntry::MemoryType::StronglyOrdered; 1196 else if (attr_3_0 == 0x4) 1197 te.mtype = TlbEntry::MemoryType::Device; 1198 else 1199 panic("Unpredictable behavior\n"); 1200 te.nonCacheable = true; 1201 te.outerAttrs = 0; 1202 break; 1203 case 0x4: 1204 // Normal memory, Outer Non-cacheable 1205 te.mtype = TlbEntry::MemoryType::Normal; 1206 te.outerAttrs = 0; 1207 if (attr_3_0 == 0x4) 1208 // Inner Non-cacheable 1209 te.nonCacheable = true; 1210 else if (attr_3_0 < 0x8) 1211 panic("Unpredictable behavior\n"); 1212 break; 1213 case 0x8: 1214 case 0x9: 1215 case 0xa: 1216 case 0xb: 1217 case 0xc: 1218 case 0xd: 1219 case 0xe: 1220 case 0xf: 1221 if (attr_7_4 & 0x4) { 1222 te.outerAttrs = (attr_7_4 & 1) ? 1 : 3; 1223 } else { 1224 te.outerAttrs = 0x2; 1225 } 1226 // Normal memory, Outer Cacheable 1227 te.mtype = TlbEntry::MemoryType::Normal; 1228 if (attr_3_0 != 0x4 && attr_3_0 < 0x8) 1229 panic("Unpredictable behavior\n"); 1230 break; 1231 default: 1232 panic("Unpredictable behavior\n"); 1233 break; 1234 } 1235 1236 switch (attr_3_0) { 1237 case 0x0: 1238 te.innerAttrs = 0x1; 1239 break; 1240 case 0x4: 1241 te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0; 1242 break; 1243 case 0x8: 1244 case 0x9: 1245 case 0xA: 1246 case 0xB: 1247 te.innerAttrs = 6; 1248 break; 1249 case 0xC: 1250 case 0xD: 1251 case 0xE: 1252 case 0xF: 1253 te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7; 1254 break; 1255 default: 1256 panic("Unpredictable behavior\n"); 1257 break; 1258 } 1259 } 1260 1261 te.outerShareable = sh == 2; 1262 te.shareable = (sh & 0x2) ? true : false; 1263 te.setAttributes(true); 1264 te.attributes |= (uint64_t) attr << 56; 1265} 1266 1267void 1268TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx, 1269 uint8_t sh) 1270{ 1271 DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh); 1272 1273 // Select MAIR 1274 uint64_t mair; 1275 switch (currState->el) { 1276 case EL0: 1277 case EL1: 1278 mair = tc->readMiscReg(MISCREG_MAIR_EL1); 1279 break; 1280 case EL2: 1281 mair = tc->readMiscReg(MISCREG_MAIR_EL2); 1282 break; 1283 case EL3: 1284 mair = tc->readMiscReg(MISCREG_MAIR_EL3); 1285 break; 1286 default: 1287 panic("Invalid exception level"); 1288 break; 1289 } 1290 1291 // Select attributes 1292 uint8_t attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx); 1293 uint8_t attr_lo = bits(attr, 3, 0); 1294 uint8_t attr_hi = bits(attr, 7, 4); 1295 1296 // Memory type 1297 te.mtype = attr_hi == 0 ? TlbEntry::MemoryType::Device : TlbEntry::MemoryType::Normal; 1298 1299 // Cacheability 1300 te.nonCacheable = false; 1301 if (te.mtype == TlbEntry::MemoryType::Device || // Device memory 1302 attr_hi == 0x8 || // Normal memory, Outer Non-cacheable 1303 attr_lo == 0x8) { // Normal memory, Inner Non-cacheable 1304 te.nonCacheable = true; 1305 } 1306 1307 te.shareable = sh == 2; 1308 te.outerShareable = (sh & 0x2) ? true : false; 1309 // Attributes formatted according to the 64-bit PAR 1310 te.attributes = ((uint64_t) attr << 56) | 1311 (1 << 11) | // LPAE bit 1312 (te.ns << 9) | // NS bit 1313 (sh << 7); 1314} 1315 1316void 1317TableWalker::doL1Descriptor() 1318{ 1319 if (currState->fault != NoFault) { 1320 return; 1321 } 1322 1323 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", 1324 currState->vaddr_tainted, currState->l1Desc.data); 1325 TlbEntry te; 1326 1327 switch (currState->l1Desc.type()) { 1328 case L1Descriptor::Ignore: 1329 case L1Descriptor::Reserved: 1330 if (!currState->timing) { 1331 currState->tc = NULL; 1332 currState->req = NULL; 1333 } 1334 DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n"); 1335 if (currState->isFetch) 1336 currState->fault = 1337 std::make_shared<PrefetchAbort>( 1338 currState->vaddr_tainted, 1339 ArmFault::TranslationLL + L1, 1340 isStage2, 1341 ArmFault::VmsaTran); 1342 else 1343 currState->fault = 1344 std::make_shared<DataAbort>( 1345 currState->vaddr_tainted, 1346 TlbEntry::DomainType::NoAccess, 1347 currState->isWrite, 1348 ArmFault::TranslationLL + L1, isStage2, 1349 ArmFault::VmsaTran); 1350 return; 1351 case L1Descriptor::Section: 1352 if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) { 1353 /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is 1354 * enabled if set, do l1.Desc.setAp0() instead of generating 1355 * AccessFlag0 1356 */ 1357 1358 currState->fault = std::make_shared<DataAbort>( 1359 currState->vaddr_tainted, 1360 currState->l1Desc.domain(), 1361 currState->isWrite, 1362 ArmFault::AccessFlagLL + L1, 1363 isStage2, 1364 ArmFault::VmsaTran); 1365 } 1366 if (currState->l1Desc.supersection()) { 1367 panic("Haven't implemented supersections\n"); 1368 } 1369 insertTableEntry(currState->l1Desc, false); 1370 return; 1371 case L1Descriptor::PageTable: 1372 { 1373 Addr l2desc_addr; 1374 l2desc_addr = currState->l1Desc.l2Addr() | 1375 (bits(currState->vaddr, 19, 12) << 2); 1376 DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n", 1377 l2desc_addr, currState->isSecure ? "s" : "ns"); 1378 1379 // Trickbox address check 1380 currState->fault = tlb->walkTrickBoxCheck( 1381 l2desc_addr, currState->isSecure, currState->vaddr, 1382 sizeof(uint32_t), currState->isFetch, currState->isWrite, 1383 currState->l1Desc.domain(), L2); 1384 1385 if (currState->fault) { 1386 if (!currState->timing) { 1387 currState->tc = NULL; 1388 currState->req = NULL; 1389 } 1390 return; 1391 } 1392 1393 Request::Flags flag = 0; 1394 if (currState->isSecure) 1395 flag.set(Request::SECURE); 1396 1397 bool delayed; 1398 delayed = fetchDescriptor(l2desc_addr, 1399 (uint8_t*)&currState->l2Desc.data, 1400 sizeof(uint32_t), flag, -1, &doL2DescEvent, 1401 &TableWalker::doL2Descriptor); 1402 if (delayed) { 1403 currState->delayed = true; 1404 } 1405 1406 return; 1407 } 1408 default: 1409 panic("A new type in a 2 bit field?\n"); 1410 } 1411} 1412 1413void 1414TableWalker::doLongDescriptor() 1415{ 1416 if (currState->fault != NoFault) { 1417 return; 1418 } 1419 1420 DPRINTF(TLB, "L%d descriptor for %#llx is %#llx (%s)\n", 1421 currState->longDesc.lookupLevel, currState->vaddr_tainted, 1422 currState->longDesc.data, 1423 currState->aarch64 ? "AArch64" : "long-desc."); 1424 1425 if ((currState->longDesc.type() == LongDescriptor::Block) || 1426 (currState->longDesc.type() == LongDescriptor::Page)) { 1427 DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, pxn: %d, " 1428 "xn: %d, ap: %d, af: %d, type: %d\n", 1429 currState->longDesc.lookupLevel, 1430 currState->longDesc.data, 1431 currState->longDesc.pxn(), 1432 currState->longDesc.xn(), 1433 currState->longDesc.ap(), 1434 currState->longDesc.af(), 1435 currState->longDesc.type()); 1436 } else { 1437 DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, type: %d\n", 1438 currState->longDesc.lookupLevel, 1439 currState->longDesc.data, 1440 currState->longDesc.type()); 1441 } 1442 1443 TlbEntry te; 1444 1445 switch (currState->longDesc.type()) { 1446 case LongDescriptor::Invalid: 1447 if (!currState->timing) { 1448 currState->tc = NULL; 1449 currState->req = NULL; 1450 } 1451 1452 DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n", 1453 currState->longDesc.lookupLevel, 1454 ArmFault::TranslationLL + currState->longDesc.lookupLevel); 1455 if (currState->isFetch) 1456 currState->fault = std::make_shared<PrefetchAbort>( 1457 currState->vaddr_tainted, 1458 ArmFault::TranslationLL + currState->longDesc.lookupLevel, 1459 isStage2, 1460 ArmFault::LpaeTran); 1461 else 1462 currState->fault = std::make_shared<DataAbort>( 1463 currState->vaddr_tainted, 1464 TlbEntry::DomainType::NoAccess, 1465 currState->isWrite, 1466 ArmFault::TranslationLL + currState->longDesc.lookupLevel, 1467 isStage2, 1468 ArmFault::LpaeTran); 1469 return; 1470 case LongDescriptor::Block: 1471 case LongDescriptor::Page: 1472 { 1473 bool fault = false; 1474 bool aff = false; 1475 // Check for address size fault 1476 if (checkAddrSizeFaultAArch64( 1477 mbits(currState->longDesc.data, MaxPhysAddrRange - 1, 1478 currState->longDesc.offsetBits()), 1479 currState->physAddrRange)) { 1480 fault = true; 1481 DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n", 1482 currState->longDesc.lookupLevel); 1483 // Check for access fault 1484 } else if (currState->longDesc.af() == 0) { 1485 fault = true; 1486 DPRINTF(TLB, "L%d descriptor causing Access Fault\n", 1487 currState->longDesc.lookupLevel); 1488 aff = true; 1489 } 1490 if (fault) { 1491 if (currState->isFetch) 1492 currState->fault = std::make_shared<PrefetchAbort>( 1493 currState->vaddr_tainted, 1494 (aff ? ArmFault::AccessFlagLL : ArmFault::AddressSizeLL) + 1495 currState->longDesc.lookupLevel, 1496 isStage2, 1497 ArmFault::LpaeTran); 1498 else 1499 currState->fault = std::make_shared<DataAbort>( 1500 currState->vaddr_tainted, 1501 TlbEntry::DomainType::NoAccess, currState->isWrite, 1502 (aff ? ArmFault::AccessFlagLL : ArmFault::AddressSizeLL) + 1503 currState->longDesc.lookupLevel, 1504 isStage2, 1505 ArmFault::LpaeTran); 1506 } else { 1507 insertTableEntry(currState->longDesc, true); 1508 } 1509 } 1510 return; 1511 case LongDescriptor::Table: 1512 { 1513 // Set hierarchical permission flags 1514 currState->secureLookup = currState->secureLookup && 1515 currState->longDesc.secureTable(); 1516 currState->rwTable = currState->rwTable && 1517 currState->longDesc.rwTable(); 1518 currState->userTable = currState->userTable && 1519 currState->longDesc.userTable(); 1520 currState->xnTable = currState->xnTable || 1521 currState->longDesc.xnTable(); 1522 currState->pxnTable = currState->pxnTable || 1523 currState->longDesc.pxnTable(); 1524 1525 // Set up next level lookup 1526 Addr next_desc_addr = currState->longDesc.nextDescAddr( 1527 currState->vaddr); 1528 1529 DPRINTF(TLB, "L%d descriptor points to L%d descriptor at: %#x (%s)\n", 1530 currState->longDesc.lookupLevel, 1531 currState->longDesc.lookupLevel + 1, 1532 next_desc_addr, 1533 currState->secureLookup ? "s" : "ns"); 1534 1535 // Check for address size fault 1536 if (currState->aarch64 && checkAddrSizeFaultAArch64( 1537 next_desc_addr, currState->physAddrRange)) { 1538 DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n", 1539 currState->longDesc.lookupLevel); 1540 if (currState->isFetch) 1541 currState->fault = std::make_shared<PrefetchAbort>( 1542 currState->vaddr_tainted, 1543 ArmFault::AddressSizeLL 1544 + currState->longDesc.lookupLevel, 1545 isStage2, 1546 ArmFault::LpaeTran); 1547 else 1548 currState->fault = std::make_shared<DataAbort>( 1549 currState->vaddr_tainted, 1550 TlbEntry::DomainType::NoAccess, currState->isWrite, 1551 ArmFault::AddressSizeLL 1552 + currState->longDesc.lookupLevel, 1553 isStage2, 1554 ArmFault::LpaeTran); 1555 return; 1556 } 1557 1558 // Trickbox address check 1559 currState->fault = tlb->walkTrickBoxCheck( 1560 next_desc_addr, currState->vaddr, 1561 currState->vaddr, sizeof(uint64_t), 1562 currState->isFetch, currState->isWrite, 1563 TlbEntry::DomainType::Client, 1564 toLookupLevel(currState->longDesc.lookupLevel +1)); 1565 1566 if (currState->fault) { 1567 if (!currState->timing) { 1568 currState->tc = NULL; 1569 currState->req = NULL; 1570 } 1571 return; 1572 } 1573 1574 Request::Flags flag = 0; 1575 if (currState->secureLookup) 1576 flag.set(Request::SECURE); 1577 1578 currState->longDesc.lookupLevel = 1579 (LookupLevel) (currState->longDesc.lookupLevel + 1); 1580 Event *event = NULL; 1581 switch (currState->longDesc.lookupLevel) { 1582 case L1: 1583 assert(currState->aarch64); 1584 event = &doL1LongDescEvent; 1585 break; 1586 case L2: 1587 event = &doL2LongDescEvent; 1588 break; 1589 case L3: 1590 event = &doL3LongDescEvent; 1591 break; 1592 default: 1593 panic("Wrong lookup level in table walk\n"); 1594 break; 1595 } 1596 1597 bool delayed; 1598 delayed = fetchDescriptor(next_desc_addr, (uint8_t*)&currState->longDesc.data, 1599 sizeof(uint64_t), flag, -1, event, 1600 &TableWalker::doLongDescriptor); 1601 if (delayed) { 1602 currState->delayed = true; 1603 } 1604 } 1605 return; 1606 default: 1607 panic("A new type in a 2 bit field?\n"); 1608 } 1609} 1610 1611void 1612TableWalker::doL2Descriptor() 1613{ 1614 if (currState->fault != NoFault) { 1615 return; 1616 } 1617 1618 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", 1619 currState->vaddr_tainted, currState->l2Desc.data); 1620 TlbEntry te; 1621 1622 if (currState->l2Desc.invalid()) { 1623 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n"); 1624 if (!currState->timing) { 1625 currState->tc = NULL; 1626 currState->req = NULL; 1627 } 1628 if (currState->isFetch) 1629 currState->fault = std::make_shared<PrefetchAbort>( 1630 currState->vaddr_tainted, 1631 ArmFault::TranslationLL + L2, 1632 isStage2, 1633 ArmFault::VmsaTran); 1634 else 1635 currState->fault = std::make_shared<DataAbort>( 1636 currState->vaddr_tainted, currState->l1Desc.domain(), 1637 currState->isWrite, ArmFault::TranslationLL + L2, 1638 isStage2, 1639 ArmFault::VmsaTran); 1640 return; 1641 } 1642 1643 if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) { 1644 /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is enabled 1645 * if set, do l2.Desc.setAp0() instead of generating AccessFlag0 1646 */ 1647 DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n", 1648 currState->sctlr.afe, currState->l2Desc.ap()); 1649 1650 currState->fault = std::make_shared<DataAbort>( 1651 currState->vaddr_tainted, 1652 TlbEntry::DomainType::NoAccess, currState->isWrite, 1653 ArmFault::AccessFlagLL + L2, isStage2, 1654 ArmFault::VmsaTran); 1655 } 1656 1657 insertTableEntry(currState->l2Desc, false); 1658} 1659 1660void 1661TableWalker::doL1DescriptorWrapper() 1662{ 1663 currState = stateQueues[L1].front(); 1664 currState->delayed = false; 1665 // if there's a stage2 translation object we don't need it any more 1666 if (currState->stage2Tran) { 1667 delete currState->stage2Tran; 1668 currState->stage2Tran = NULL; 1669 } 1670 1671 1672 DPRINTF(TLBVerbose, "L1 Desc object host addr: %p\n",&currState->l1Desc.data); 1673 DPRINTF(TLBVerbose, "L1 Desc object data: %08x\n",currState->l1Desc.data); 1674 1675 DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted); 1676 doL1Descriptor(); 1677 1678 stateQueues[L1].pop_front(); 1679 // Check if fault was generated 1680 if (currState->fault != NoFault) { 1681 currState->transState->finish(currState->fault, currState->req, 1682 currState->tc, currState->mode); 1683 1684 pending = false; 1685 nextWalk(currState->tc); 1686 1687 currState->req = NULL; 1688 currState->tc = NULL; 1689 currState->delayed = false; 1690 delete currState; 1691 } 1692 else if (!currState->delayed) { 1693 // delay is not set so there is no L2 to do 1694 // Don't finish the translation if a stage 2 look up is underway 1695 if (!currState->doingStage2) { 1696 DPRINTF(TLBVerbose, "calling translateTiming again\n"); 1697 currState->fault = tlb->translateTiming(currState->req, currState->tc, 1698 currState->transState, currState->mode); 1699 } 1700 1701 pending = false; 1702 nextWalk(currState->tc); 1703 1704 currState->req = NULL; 1705 currState->tc = NULL; 1706 currState->delayed = false; 1707 delete currState; 1708 } else { 1709 // need to do L2 descriptor 1710 stateQueues[L2].push_back(currState); 1711 } 1712 currState = NULL; 1713} 1714 1715void 1716TableWalker::doL2DescriptorWrapper() 1717{ 1718 currState = stateQueues[L2].front(); 1719 assert(currState->delayed); 1720 // if there's a stage2 translation object we don't need it any more 1721 if (currState->stage2Tran) { 1722 delete currState->stage2Tran; 1723 currState->stage2Tran = NULL; 1724 } 1725 1726 DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n", 1727 currState->vaddr_tainted); 1728 doL2Descriptor(); 1729 1730 // Check if fault was generated 1731 if (currState->fault != NoFault) { 1732 currState->transState->finish(currState->fault, currState->req, 1733 currState->tc, currState->mode); 1734 } 1735 else { 1736 // Don't finish the translation if a stage 2 look up is underway 1737 if (!currState->doingStage2) { 1738 DPRINTF(TLBVerbose, "calling translateTiming again\n"); 1739 currState->fault = tlb->translateTiming(currState->req, 1740 currState->tc, currState->transState, currState->mode); 1741 } 1742 } 1743 1744 1745 stateQueues[L2].pop_front(); 1746 pending = false; 1747 nextWalk(currState->tc); 1748 1749 currState->req = NULL; 1750 currState->tc = NULL; 1751 currState->delayed = false; 1752 1753 delete currState; 1754 currState = NULL; 1755} 1756 1757void 1758TableWalker::doL0LongDescriptorWrapper() 1759{ 1760 doLongDescriptorWrapper(L0); 1761} 1762 1763void 1764TableWalker::doL1LongDescriptorWrapper() 1765{ 1766 doLongDescriptorWrapper(L1); 1767} 1768 1769void 1770TableWalker::doL2LongDescriptorWrapper() 1771{ 1772 doLongDescriptorWrapper(L2); 1773} 1774 1775void 1776TableWalker::doL3LongDescriptorWrapper() 1777{ 1778 doLongDescriptorWrapper(L3); 1779} 1780 1781void 1782TableWalker::doLongDescriptorWrapper(LookupLevel curr_lookup_level) 1783{ 1784 currState = stateQueues[curr_lookup_level].front(); 1785 assert(curr_lookup_level == currState->longDesc.lookupLevel); 1786 currState->delayed = false; 1787 1788 // if there's a stage2 translation object we don't need it any more 1789 if (currState->stage2Tran) { 1790 delete currState->stage2Tran; 1791 currState->stage2Tran = NULL; 1792 } 1793 1794 DPRINTF(TLBVerbose, "calling doLongDescriptor for vaddr:%#x\n", 1795 currState->vaddr_tainted); 1796 doLongDescriptor(); 1797 1798 stateQueues[curr_lookup_level].pop_front(); 1799 1800 if (currState->fault != NoFault) { 1801 // A fault was generated 1802 currState->transState->finish(currState->fault, currState->req, 1803 currState->tc, currState->mode); 1804 1805 pending = false; 1806 nextWalk(currState->tc); 1807 1808 currState->req = NULL; 1809 currState->tc = NULL; 1810 currState->delayed = false; 1811 delete currState; 1812 } else if (!currState->delayed) { 1813 // No additional lookups required 1814 // Don't finish the translation if a stage 2 look up is underway 1815 if (!currState->doingStage2) { 1816 DPRINTF(TLBVerbose, "calling translateTiming again\n"); 1817 currState->fault = tlb->translateTiming(currState->req, currState->tc, 1818 currState->transState, 1819 currState->mode); 1820 } 1821 1822 pending = false; 1823 nextWalk(currState->tc); 1824 1825 currState->req = NULL; 1826 currState->tc = NULL; 1827 currState->delayed = false; 1828 delete currState; 1829 } else { 1830 if (curr_lookup_level >= MAX_LOOKUP_LEVELS - 1) 1831 panic("Max. number of lookups already reached in table walk\n"); 1832 // Need to perform additional lookups 1833 stateQueues[currState->longDesc.lookupLevel].push_back(currState); 1834 } 1835 currState = NULL; 1836} 1837 1838 1839void 1840TableWalker::nextWalk(ThreadContext *tc) 1841{ 1842 if (pendingQueue.size()) 1843 schedule(doProcessEvent, clockEdge(Cycles(1))); 1844 else 1845 completeDrain(); 1846} 1847 1848bool 1849TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, 1850 Request::Flags flags, int queueIndex, Event *event, 1851 void (TableWalker::*doDescriptor)()) 1852{ 1853 bool isTiming = currState->timing; 1854 1855 // do the requests for the page table descriptors have to go through the 1856 // second stage MMU 1857 if (currState->stage2Req) { 1858 Fault fault; 1859 flags = flags | TLB::MustBeOne; 1860 1861 if (isTiming) { 1862 Stage2MMU::Stage2Translation *tran = new 1863 Stage2MMU::Stage2Translation(*stage2Mmu, data, event, 1864 currState->vaddr); 1865 currState->stage2Tran = tran; 1866 stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes, 1867 flags, masterId); 1868 fault = tran->fault; 1869 } else { 1870 fault = stage2Mmu->readDataUntimed(currState->tc, 1871 currState->vaddr, descAddr, data, numBytes, flags, masterId, 1872 currState->functional); 1873 } 1874 1875 if (fault != NoFault) { 1876 currState->fault = fault; 1877 } 1878 if (isTiming) { 1879 if (queueIndex >= 0) { 1880 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n", 1881 stateQueues[queueIndex].size()); 1882 stateQueues[queueIndex].push_back(currState); 1883 currState = NULL; 1884 } 1885 } else { 1886 (this->*doDescriptor)(); 1887 } 1888 } else { 1889 if (isTiming) { 1890 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data, 1891 currState->tc->getCpuPtr()->clockPeriod(), flags); 1892 if (queueIndex >= 0) { 1893 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n", 1894 stateQueues[queueIndex].size()); 1895 stateQueues[queueIndex].push_back(currState); 1896 currState = NULL; 1897 } 1898 } else if (!currState->functional) { 1899 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data, 1900 currState->tc->getCpuPtr()->clockPeriod(), flags); 1901 (this->*doDescriptor)(); 1902 } else { 1903 RequestPtr req = new Request(descAddr, numBytes, flags, masterId); 1904 req->taskId(ContextSwitchTaskId::DMA); 1905 PacketPtr pkt = new Packet(req, MemCmd::ReadReq); 1906 pkt->dataStatic(data); 1907 port.sendFunctional(pkt); 1908 (this->*doDescriptor)(); 1909 delete req; 1910 delete pkt; 1911 } 1912 } 1913 return (isTiming); 1914} 1915 1916void 1917TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor) 1918{ 1919 TlbEntry te; 1920 1921 // Create and fill a new page table entry 1922 te.valid = true; 1923 te.longDescFormat = longDescriptor; 1924 te.isHyp = currState->isHyp; 1925 te.asid = currState->asid; 1926 te.vmid = currState->vmid; 1927 te.N = descriptor.offsetBits(); 1928 te.vpn = currState->vaddr >> te.N; 1929 te.size = (1<<te.N) - 1; 1930 te.pfn = descriptor.pfn(); 1931 te.domain = descriptor.domain(); 1932 te.lookupLevel = descriptor.lookupLevel; 1933 te.ns = !descriptor.secure(haveSecurity, currState) || isStage2; 1934 te.nstid = !currState->isSecure; 1935 te.xn = descriptor.xn(); 1936 if (currState->aarch64) 1937 te.el = currState->el; 1938 else 1939 te.el = 1; 1940 1941 // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries 1942 // as global 1943 te.global = descriptor.global(currState) || isStage2; 1944 if (longDescriptor) { 1945 LongDescriptor lDescriptor = 1946 dynamic_cast<LongDescriptor &>(descriptor); 1947 1948 te.xn |= currState->xnTable; 1949 te.pxn = currState->pxnTable || lDescriptor.pxn(); 1950 if (isStage2) { 1951 // this is actually the HAP field, but its stored in the same bit 1952 // possitions as the AP field in a stage 1 translation. 1953 te.hap = lDescriptor.ap(); 1954 } else { 1955 te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) | 1956 (currState->userTable && (descriptor.ap() & 0x1)); 1957 } 1958 if (currState->aarch64) 1959 memAttrsAArch64(currState->tc, te, currState->longDesc.attrIndx(), 1960 currState->longDesc.sh()); 1961 else 1962 memAttrsLPAE(currState->tc, te, lDescriptor); 1963 } else { 1964 te.ap = descriptor.ap(); 1965 memAttrs(currState->tc, te, currState->sctlr, descriptor.texcb(), 1966 descriptor.shareable()); 1967 } 1968 1969 // Debug output 1970 DPRINTF(TLB, descriptor.dbgHeader().c_str()); 1971 DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n", 1972 te.N, te.pfn, te.size, te.global, te.valid); 1973 DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d " 1974 "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn, 1975 te.ap, static_cast<uint8_t>(te.domain), te.asid, te.vmid, te.isHyp, 1976 te.nonCacheable, te.ns); 1977 DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n", 1978 descriptor.lookupLevel, static_cast<uint8_t>(descriptor.domain()), 1979 descriptor.getRawData()); 1980 1981 // Insert the entry into the TLB 1982 tlb->insert(currState->vaddr, te); 1983 if (!currState->timing) { 1984 currState->tc = NULL; 1985 currState->req = NULL; 1986 } 1987} 1988 1989ArmISA::TableWalker * 1990ArmTableWalkerParams::create() 1991{ 1992 return new ArmISA::TableWalker(this); 1993} 1994 1995LookupLevel 1996TableWalker::toLookupLevel(uint8_t lookup_level_as_int) 1997{ 1998 switch (lookup_level_as_int) { 1999 case L1: 2000 return L1; 2001 case L2: 2002 return L2; 2003 case L3: 2004 return L3; 2005 default: 2006 panic("Invalid lookup level conversion"); 2007 } 2008} 2009