arch-arm: Correction for address size in EL1&0 translation
authorAnouk Van Laer <anouk.vanlaer@arm.com>
Tue, 4 Sep 2018 10:44:42 +0000 (11:44 +0100)
committerAnouk Van Laer <anouk.vanlaer@arm.com>
Thu, 13 Sep 2018 09:08:19 +0000 (09:08 +0000)
When doing EL0/1 translation in stage2, the
physical address size will be defined by the
hypervisor (via VTCR_EL2.ps, not TCR.ips).

See D10.2.121 of the ARM ARM.

Change-Id: Ic7df97c0f5950a648f7408cde3955a640b562c1d
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/12552
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>

src/arch/arm/miscregs.hh
src/arch/arm/table_walker.cc

index c1d5efa107d07a41c02c22ed856c7cf6c7f78c89..50e64777cddb984990a3233eddd399f8f42b72a0 100644 (file)
@@ -1810,6 +1810,7 @@ namespace ArmISA
         Bitfield<11, 10> orgn0;
         Bitfield<13, 12> sh0;
         Bitfield<15, 14> tg0;
+        Bitfield<18, 16> ps; // Only defined for VTCR_EL2
     EndBitUnion(VTCR_t)
 
     BitUnion32(PRRR)
index 66714fff8f504382241d2ee624f157cb4c3904f1..1a7b5d37526bb8a15ca97dbb26664df667683b18 100644 (file)
@@ -771,30 +771,33 @@ TableWalker::processWalkAArch64()
             start_lookup_level = SLL[sl_tg];
             panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
                      "Cannot discern lookup level from vtcr.{sl0,tg0}");
-        } else switch (bits(currState->vaddr, 63,48)) {
-          case 0:
-            DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
-            ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
-            tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
-            tg = GrainMap_tg0[currState->tcr.tg0];
-            if (bits(currState->vaddr, 63, tsz) != 0x0 ||
-                currState->tcr.epd0)
-              fault = true;
-            break;
-          case 0xffff:
-            DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
-            ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
-            tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
-            tg = GrainMap_tg1[currState->tcr.tg1];
-            if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
-                currState->tcr.epd1)
-              fault = true;
-            break;
-          default:
-            // top two bytes must be all 0s or all 1s, else invalid addr
-            fault = true;
+            ps = currState->vtcr.ps;
+        } else {
+            switch (bits(currState->vaddr, 63,48)) {
+              case 0:
+                DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
+                ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
+                tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
+                tg = GrainMap_tg0[currState->tcr.tg0];
+                if (bits(currState->vaddr, 63, tsz) != 0x0 ||
+                    currState->tcr.epd0)
+                  fault = true;
+                break;
+              case 0xffff:
+                DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
+                ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
+                tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
+                tg = GrainMap_tg1[currState->tcr.tg1];
+                if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
+                    currState->tcr.epd1)
+                  fault = true;
+                break;
+              default:
+                // top two bytes must be all 0s or all 1s, else invalid addr
+                fault = true;
+            }
+            ps = currState->tcr.ips;
         }
-        ps = currState->tcr.ips;
         break;
       case EL2:
         switch(bits(currState->vaddr, 63,48)) {