Deleted Added
sdiff udiff text old ( 10109:b58c5c5854de ) new ( 10324:f40134eb3f85 )
full compact
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 ---