Deleted Added
sdiff udiff text old ( 14095:4f5d16d7cf45 ) new ( 14280:9e3f2937f72c )
full compact
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 ---