1/* 2 * Copyright (c) 2010, 2012-2019 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 --- 443 unchanged lines hidden (view full) --- 452 453Fault 454TableWalker::processWalk() 455{ 456 Addr ttbr = 0; 457 458 // If translation isn't enabled, we shouldn't be here 459 assert(currState->sctlr.m || isStage2); |
460 const bool is_atomic = currState->req->isAtomic(); |
461 462 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n", 463 currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31, 464 32 - currState->ttbcr.n)); 465 466 statWalkWaitTime.sample(curTick() - currState->startTime); 467 468 if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31, --- 5 unchanged lines hidden (view full) --- 474 return std::make_shared<PrefetchAbort>( 475 currState->vaddr_tainted, 476 ArmFault::TranslationLL + L1, 477 isStage2, 478 ArmFault::VmsaTran); 479 else 480 return std::make_shared<DataAbort>( 481 currState->vaddr_tainted, |
482 TlbEntry::DomainType::NoAccess, 483 is_atomic ? false : currState->isWrite, |
484 ArmFault::TranslationLL + L1, isStage2, 485 ArmFault::VmsaTran); 486 } 487 ttbr = currState->tc->readMiscReg(snsBankedIndex( 488 MISCREG_TTBR0, currState->tc, !currState->isSecure)); 489 } else { 490 DPRINTF(TLB, " - Selecting TTBR1\n"); 491 // Check if table walk is allowed when Security Extensions are enabled 492 if (haveSecurity && currState->ttbcr.pd1) { 493 if (currState->isFetch) 494 return std::make_shared<PrefetchAbort>( 495 currState->vaddr_tainted, 496 ArmFault::TranslationLL + L1, 497 isStage2, 498 ArmFault::VmsaTran); 499 else 500 return std::make_shared<DataAbort>( 501 currState->vaddr_tainted, |
502 TlbEntry::DomainType::NoAccess, 503 is_atomic ? false : currState->isWrite, |
504 ArmFault::TranslationLL + L1, isStage2, 505 ArmFault::VmsaTran); 506 } 507 ttbr = currState->tc->readMiscReg(snsBankedIndex( 508 MISCREG_TTBR1, currState->tc, !currState->isSecure)); 509 currState->ttbcr.n = 0; 510 } 511 --- 77 unchanged lines hidden (view full) --- 589 (1ULL << (32 - currState->ttbcr.t1sz)) - 1; 590 else 591 ttbr0_max = (1ULL << 32) - 1; 592 if (currState->ttbcr.t1sz) 593 ttbr1_min = (1ULL << 32) - (1ULL << (32 - currState->ttbcr.t1sz)); 594 else 595 ttbr1_min = (1ULL << (32 - currState->ttbcr.t0sz)); 596 |
597 const bool is_atomic = currState->req->isAtomic(); 598 |
599 // The following code snippet selects the appropriate translation table base 600 // address (TTBR0 or TTBR1) and the appropriate starting lookup level 601 // depending on the address range supported by the translation table (ARM 602 // ARM issue C B3.6.4) 603 if (currState->vaddr <= ttbr0_max) { 604 DPRINTF(TLB, " - Selecting TTBR0 (long-desc.)\n"); 605 // Check if table walk is allowed 606 if (currState->ttbcr.epd0) { 607 if (currState->isFetch) 608 return std::make_shared<PrefetchAbort>( 609 currState->vaddr_tainted, 610 ArmFault::TranslationLL + L1, 611 isStage2, 612 ArmFault::LpaeTran); 613 else 614 return std::make_shared<DataAbort>( 615 currState->vaddr_tainted, 616 TlbEntry::DomainType::NoAccess, |
617 is_atomic ? false : currState->isWrite, |
618 ArmFault::TranslationLL + L1, 619 isStage2, 620 ArmFault::LpaeTran); 621 } 622 ttbr = currState->tc->readMiscReg(snsBankedIndex( 623 MISCREG_TTBR0, currState->tc, !currState->isSecure)); 624 tsz = currState->ttbcr.t0sz; 625 if (ttbr0_max < (1ULL << 30)) // Upper limit < 1 GB --- 7 unchanged lines hidden (view full) --- 633 currState->vaddr_tainted, 634 ArmFault::TranslationLL + L1, 635 isStage2, 636 ArmFault::LpaeTran); 637 else 638 return std::make_shared<DataAbort>( 639 currState->vaddr_tainted, 640 TlbEntry::DomainType::NoAccess, |
641 is_atomic ? false : currState->isWrite, |
642 ArmFault::TranslationLL + L1, 643 isStage2, 644 ArmFault::LpaeTran); 645 } 646 ttbr = currState->tc->readMiscReg(snsBankedIndex( 647 MISCREG_TTBR1, currState->tc, !currState->isSecure)); 648 tsz = currState->ttbcr.t1sz; 649 if (ttbr1_min >= (1ULL << 31) + (1ULL << 30)) // Lower limit >= 3 GB --- 5 unchanged lines hidden (view full) --- 655 currState->vaddr_tainted, 656 ArmFault::TranslationLL + L1, 657 isStage2, 658 ArmFault::LpaeTran); 659 else 660 return std::make_shared<DataAbort>( 661 currState->vaddr_tainted, 662 TlbEntry::DomainType::NoAccess, |
663 is_atomic ? false : currState->isWrite, 664 ArmFault::TranslationLL + L1, |
665 isStage2, ArmFault::LpaeTran); 666 } 667 668 } 669 670 // Perform lookup (ARM ARM issue C B3.6.6) 671 if (start_lookup_level == L1) { 672 n = 5 - tsz; --- 177 unchanged lines hidden (view full) --- 850 default: 851 // invalid addr if top two bytes are not all 0s 852 fault = true; 853 } 854 ps = currState->tcr.ps; 855 break; 856 } 857 |
858 const bool is_atomic = currState->req->isAtomic(); 859 |
860 if (fault) { 861 Fault f; 862 if (currState->isFetch) 863 f = std::make_shared<PrefetchAbort>( 864 currState->vaddr_tainted, 865 ArmFault::TranslationLL + L0, isStage2, 866 ArmFault::LpaeTran); 867 else 868 f = std::make_shared<DataAbort>( 869 currState->vaddr_tainted, 870 TlbEntry::DomainType::NoAccess, |
871 is_atomic ? false : currState->isWrite, |
872 ArmFault::TranslationLL + L0, 873 isStage2, ArmFault::LpaeTran); 874 875 if (currState->timing) { 876 pending = false; 877 nextWalk(currState->tc); 878 currState = NULL; 879 } else { --- 69 unchanged lines hidden (view full) --- 949 currState->vaddr_tainted, 950 ArmFault::AddressSizeLL + start_lookup_level, 951 isStage2, 952 ArmFault::LpaeTran); 953 else 954 f = std::make_shared<DataAbort>( 955 currState->vaddr_tainted, 956 TlbEntry::DomainType::NoAccess, |
957 is_atomic ? false : currState->isWrite, |
958 ArmFault::AddressSizeLL + start_lookup_level, 959 isStage2, 960 ArmFault::LpaeTran); 961 962 963 if (currState->timing) { 964 pending = false; 965 nextWalk(currState->tc); --- 495 unchanged lines hidden (view full) --- 1461 1462 currState->l1Desc.data = htog(currState->l1Desc.data, 1463 byteOrder(currState->tc)); 1464 1465 DPRINTF(TLB, "L1 descriptor for %#x is %#x\n", 1466 currState->vaddr_tainted, currState->l1Desc.data); 1467 TlbEntry te; 1468 |
1469 const bool is_atomic = currState->req->isAtomic(); 1470 |
1471 switch (currState->l1Desc.type()) { 1472 case L1Descriptor::Ignore: 1473 case L1Descriptor::Reserved: 1474 if (!currState->timing) { 1475 currState->tc = NULL; 1476 currState->req = NULL; 1477 } 1478 DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n"); --- 4 unchanged lines hidden (view full) --- 1483 ArmFault::TranslationLL + L1, 1484 isStage2, 1485 ArmFault::VmsaTran); 1486 else 1487 currState->fault = 1488 std::make_shared<DataAbort>( 1489 currState->vaddr_tainted, 1490 TlbEntry::DomainType::NoAccess, |
1491 is_atomic ? false : currState->isWrite, |
1492 ArmFault::TranslationLL + L1, isStage2, 1493 ArmFault::VmsaTran); 1494 return; 1495 case L1Descriptor::Section: 1496 if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) { 1497 /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is 1498 * enabled if set, do l1.Desc.setAp0() instead of generating 1499 * AccessFlag0 1500 */ 1501 1502 currState->fault = std::make_shared<DataAbort>( 1503 currState->vaddr_tainted, 1504 currState->l1Desc.domain(), |
1505 is_atomic ? false : currState->isWrite, |
1506 ArmFault::AccessFlagLL + L1, 1507 isStage2, 1508 ArmFault::VmsaTran); 1509 } 1510 if (currState->l1Desc.supersection()) { 1511 panic("Haven't implemented supersections\n"); 1512 } 1513 insertTableEntry(currState->l1Desc, false); --- 46 unchanged lines hidden (view full) --- 1560 currState->vaddr_tainted, 1561 src + currState->longDesc.lookupLevel, 1562 isStage2, 1563 ArmFault::LpaeTran); 1564 } else { 1565 return std::make_shared<DataAbort>( 1566 currState->vaddr_tainted, 1567 TlbEntry::DomainType::NoAccess, |
1568 currState->req->isAtomic() ? false : currState->isWrite, |
1569 src + currState->longDesc.lookupLevel, 1570 isStage2, 1571 ArmFault::LpaeTran); 1572 } 1573} 1574 1575void 1576TableWalker::doLongDescriptor() --- 27 unchanged lines hidden (view full) --- 1604 currState->longDesc.data, 1605 currState->longDesc.type()); 1606 } 1607 1608 TlbEntry te; 1609 1610 switch (currState->longDesc.type()) { 1611 case LongDescriptor::Invalid: |
1612 DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n", 1613 currState->longDesc.lookupLevel, 1614 ArmFault::TranslationLL + currState->longDesc.lookupLevel); 1615 1616 currState->fault = generateLongDescFault(ArmFault::TranslationLL); |
1617 if (!currState->timing) { 1618 currState->tc = NULL; 1619 currState->req = NULL; 1620 } |
1621 return; 1622 1623 case LongDescriptor::Block: 1624 case LongDescriptor::Page: 1625 { 1626 auto fault_source = ArmFault::FaultSourceInvalid; 1627 // Check for address size fault 1628 if (checkAddrSizeFaultAArch64( --- 110 unchanged lines hidden (view full) --- 1739 1740 currState->l2Desc.data = htog(currState->l2Desc.data, 1741 byteOrder(currState->tc)); 1742 1743 DPRINTF(TLB, "L2 descriptor for %#x is %#x\n", 1744 currState->vaddr_tainted, currState->l2Desc.data); 1745 TlbEntry te; 1746 |
1747 const bool is_atomic = currState->req->isAtomic(); 1748 |
1749 if (currState->l2Desc.invalid()) { 1750 DPRINTF(TLB, "L2 descriptor invalid, causing fault\n"); 1751 if (!currState->timing) { 1752 currState->tc = NULL; 1753 currState->req = NULL; 1754 } 1755 if (currState->isFetch) 1756 currState->fault = std::make_shared<PrefetchAbort>( 1757 currState->vaddr_tainted, 1758 ArmFault::TranslationLL + L2, 1759 isStage2, 1760 ArmFault::VmsaTran); 1761 else 1762 currState->fault = std::make_shared<DataAbort>( 1763 currState->vaddr_tainted, currState->l1Desc.domain(), |
1764 is_atomic ? false : currState->isWrite, 1765 ArmFault::TranslationLL + L2, |
1766 isStage2, 1767 ArmFault::VmsaTran); 1768 return; 1769 } 1770 1771 if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) { 1772 /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is enabled 1773 * if set, do l2.Desc.setAp0() instead of generating AccessFlag0 1774 */ 1775 DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n", 1776 currState->sctlr.afe, currState->l2Desc.ap()); 1777 1778 currState->fault = std::make_shared<DataAbort>( 1779 currState->vaddr_tainted, |
1780 TlbEntry::DomainType::NoAccess, 1781 is_atomic ? false : currState->isWrite, |
1782 ArmFault::AccessFlagLL + L2, isStage2, 1783 ArmFault::VmsaTran); 1784 } 1785 1786 insertTableEntry(currState->l2Desc, false); 1787} 1788 1789void --- 505 unchanged lines hidden --- |