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 --- 204 unchanged lines hidden (view full) --- 215 else 216 currState->vaddr = currState->vaddr_tainted; 217 218 if (currState->aarch64) { 219 switch (currState->el) { 220 case EL0: 221 case EL1: 222 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1); |
223 currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1); |
224 break; 225 // @todo: uncomment this to enable Virtualization 226 // case EL2: 227 // assert(haveVirtualization); 228 // currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2); |
229 // currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2); |
230 // break; 231 case EL3: 232 assert(haveSecurity); 233 currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL3); |
234 currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL3); |
235 break; 236 default: 237 panic("Invalid exception level"); 238 break; 239 } 240 } else { 241 currState->sctlr = currState->tc->readMiscReg(flattenMiscRegNsBanked( 242 MISCREG_SCTLR, currState->tc, !currState->isSecure)); --- 377 unchanged lines hidden (view full) --- 620 flag = Request::UNCACHEABLE; 621 } 622 623 if (currState->isSecure) 624 flag.set(Request::SECURE); 625 626 currState->longDesc.lookupLevel = start_lookup_level; 627 currState->longDesc.aarch64 = false; |
628 currState->longDesc.grainSize = Grain4KB; |
629 630 Event *event = start_lookup_level == L1 ? (Event *) &doL1LongDescEvent 631 : (Event *) &doL2LongDescEvent; 632 633 bool delayed = fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data, 634 sizeof(uint64_t), flag, start_lookup_level, 635 event, &TableWalker::doLongDescriptor); 636 if (!delayed) { --- 20 unchanged lines hidden (view full) --- 657 bits(addr, MaxPhysAddrRange - 1, currPhysAddrRange)); 658} 659 660Fault 661TableWalker::processWalkAArch64() 662{ 663 assert(currState->aarch64); 664 |
665 DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n", 666 currState->vaddr_tainted, currState->tcr); |
667 |
668 static const GrainSize GrainMapDefault[] = 669 { Grain4KB, Grain64KB, Grain16KB, ReservedGrain }; 670 static const GrainSize GrainMap_EL1_tg1[] = 671 { ReservedGrain, Grain16KB, Grain4KB, Grain64KB }; 672 |
673 // Determine TTBR, table size, granule size and phys. address range 674 Addr ttbr = 0; 675 int tsz = 0, ps = 0; |
676 GrainSize tg = Grain4KB; // grain size computed from tg* field |
677 bool fault = false; 678 switch (currState->el) { 679 case EL0: 680 case EL1: 681 switch (bits(currState->vaddr, 63,48)) { 682 case 0: 683 DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); 684 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1); |
685 tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); 686 tg = GrainMapDefault[currState->tcr.tg0]; |
687 if (bits(currState->vaddr, 63, tsz) != 0x0 || |
688 currState->tcr.epd0) |
689 fault = true; 690 break; 691 case 0xffff: 692 DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n"); 693 ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1); |
694 tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz); 695 tg = GrainMap_EL1_tg1[currState->tcr.tg1]; |
696 if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) || |
697 currState->tcr.epd1) |
698 fault = true; 699 break; 700 default: 701 // top two bytes must be all 0s or all 1s, else invalid addr 702 fault = true; 703 } |
704 ps = currState->tcr.ips; |
705 break; 706 case EL2: 707 case EL3: 708 switch(bits(currState->vaddr, 63,48)) { 709 case 0: |
710 DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); 711 if (currState->el == EL2) 712 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2); 713 else 714 ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3); 715 tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz); 716 tg = GrainMapDefault[currState->tcr.tg0]; |
717 break; 718 default: 719 // invalid addr if top two bytes are not all 0s |
720 fault = true; |
721 } |
722 ps = currState->tcr.ips; |
723 break; 724 } 725 726 if (fault) { 727 Fault f; 728 if (currState->isFetch) 729 f = new PrefetchAbort(currState->vaddr_tainted, 730 ArmFault::TranslationLL + L0, isStage2, --- 12 unchanged lines hidden (view full) --- 743 } else { 744 currState->tc = NULL; 745 currState->req = NULL; 746 } 747 return f; 748 749 } 750 |
751 if (tg == ReservedGrain) { 752 warn_once("Reserved granule size requested; gem5's IMPLEMENTATION " 753 "DEFINED behavior takes this to mean 4KB granules\n"); 754 tg = Grain4KB; 755 } 756 757 int stride = tg - 3; 758 LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS; 759 |
760 // Determine starting lookup level |
761 // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library 762 // in ARM DDI 0487A. These table values correspond to the cascading tests 763 // to compute the lookup level and are of the form 764 // (grain_size + N*stride), for N = {1, 2, 3}. 765 // A value of 64 will never succeed and a value of 0 will always succeed. 766 { 767 struct GrainMap { 768 GrainSize grain_size; 769 unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS]; 770 }; 771 static const GrainMap GM[] = { 772 { Grain4KB, { 39, 30, 0, 0 } }, 773 { Grain16KB, { 47, 36, 25, 0 } }, 774 { Grain64KB, { 64, 42, 29, 0 } } 775 }; 776 777 const unsigned *lookup = NULL; // points to a lookup_level_cutoff 778 779 for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[] 780 if (tg == GM[i].grain_size) { 781 lookup = GM[i].lookup_level_cutoff; 782 break; 783 } 784 } 785 assert(lookup); 786 787 for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) { 788 if (tsz > lookup[L]) { 789 start_lookup_level = (LookupLevel) L; 790 break; 791 } 792 } 793 panic_if(start_lookup_level == MAX_LOOKUP_LEVELS, 794 "Table walker couldn't find lookup level\n"); |
795 } 796 797 // Determine table base address |
798 int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg; |
799 Addr base_addr = mbits(ttbr, 47, base_addr_lo); 800 801 // Determine physical address size and raise an Address Size Fault if 802 // necessary 803 int pa_range = decodePhysAddrRange64(ps); 804 // Clamp to lower limit 805 if (pa_range > physAddrRange) 806 currState->physAddrRange = physAddrRange; --- 26 unchanged lines hidden (view full) --- 833 } 834 return f; 835 836 } 837 838 // Determine descriptor address 839 Addr desc_addr = base_addr | 840 (bits(currState->vaddr, tsz - 1, |
841 stride * (3 - start_lookup_level) + tg) << 3); |
842 843 // Trickbox address check 844 Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure, 845 currState->vaddr, sizeof(uint64_t), currState->isFetch, 846 currState->isWrite, TlbEntry::DomainType::NoAccess, 847 start_lookup_level); 848 if (f) { 849 DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted); --- 10 unchanged lines hidden (view full) --- 860 861 Request::Flags flag = 0; 862 if (currState->sctlr.c == 0) { 863 flag = Request::UNCACHEABLE; 864 } 865 866 currState->longDesc.lookupLevel = start_lookup_level; 867 currState->longDesc.aarch64 = true; |
868 currState->longDesc.grainSize = tg; |
869 870 if (currState->timing) { 871 Event *event; 872 switch (start_lookup_level) { 873 case L0: 874 event = (Event *) &doL0LongDescEvent; 875 break; 876 case L1: --- 1112 unchanged lines hidden --- |