summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2018-04-20 09:50:29 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2018-05-29 10:07:53 +0000
commit89b3397cf0daba4b2a339e26183aa82e1a573ad0 (patch)
treed578e132772ba806c674e2f452153cc3024801ff
parent2456c917ac654f6b67243c72a47240d22a2bf712 (diff)
downloadgem5-89b3397cf0daba4b2a339e26183aa82e1a573ad0.tar.xz
arch-arm: Implement ARMv8.1 TTBR1_EL2 register
This patch implements the ARMv8.1 TTBR1_EL2 register, which is used for getting the translation table base address when a Host Operating System is running at EL2. (HCR_EL2.E2H = 1) Change-Id: Ic0ab351cae3fd64855eda7c18c8757da0d7b8663 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/10382 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
-rw-r--r--src/arch/arm/miscregs.cc2
-rw-r--r--src/arch/arm/table_walker.cc43
2 files changed, 33 insertions, 12 deletions
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index 08eb255f3..e1ddbf9d3 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -3535,7 +3535,7 @@ ISA::initializeMiscRegMetadata()
.hyp().mon()
.mapsTo(MISCREG_HTTBR);
InitReg(MISCREG_TTBR1_EL2)
- .unimplemented();
+ .hyp().mon();
InitReg(MISCREG_TCR_EL2)
.hyp().mon()
.mapsTo(MISCREG_HTCR);
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 3c79e43ac..26a07d70e 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2017 ARM Limited
+ * Copyright (c) 2010, 2012-2018 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -739,9 +739,9 @@ TableWalker::processWalkAArch64()
DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
currState->vaddr_tainted, currState->tcr);
- static const GrainSize GrainMapDefault[] =
+ static const GrainSize GrainMap_tg0[] =
{ Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
- static const GrainSize GrainMap_EL1_tg1[] =
+ static const GrainSize GrainMap_tg1[] =
{ ReservedGrain, Grain16KB, Grain4KB, Grain64KB };
statWalkWaitTime.sample(curTick() - currState->startTime);
@@ -761,7 +761,7 @@ TableWalker::processWalkAArch64()
DPRINTF(TLB, " - Selecting VTTBR0 (AArch64 stage 2)\n");
ttbr = currState->tc->readMiscReg(MISCREG_VTTBR_EL2);
tsz = 64 - currState->vtcr.t0sz64;
- tg = GrainMapDefault[currState->vtcr.tg0];
+ tg = GrainMap_tg0[currState->vtcr.tg0];
// ARM DDI 0487A.f D7-2148
// The starting level of stage 2 translation depends on
// VTCR_EL2.SL0 and VTCR_EL2.TG0
@@ -781,7 +781,7 @@ TableWalker::processWalkAArch64()
DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
- tg = GrainMapDefault[currState->tcr.tg0];
+ tg = GrainMap_tg0[currState->tcr.tg0];
if (bits(currState->vaddr, 63, tsz) != 0x0 ||
currState->tcr.epd0)
fault = true;
@@ -790,7 +790,7 @@ TableWalker::processWalkAArch64()
DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
- tg = GrainMap_EL1_tg1[currState->tcr.tg1];
+ tg = GrainMap_tg1[currState->tcr.tg1];
if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
currState->tcr.epd1)
fault = true;
@@ -802,16 +802,37 @@ TableWalker::processWalkAArch64()
ps = currState->tcr.ips;
break;
case EL2:
+ switch(bits(currState->vaddr, 63,48)) {
+ case 0:
+ DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
+ ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
+ tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
+ tg = GrainMap_tg0[currState->tcr.tg0];
+ break;
+
+ case 0xffff:
+ DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
+ ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL2);
+ tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
+ tg = GrainMap_tg1[currState->tcr.tg1];
+ if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
+ currState->tcr.epd1 || !currState->hcr.e2h)
+ fault = true;
+ break;
+
+ default:
+ // invalid addr if top two bytes are not all 0s
+ fault = true;
+ }
+ ps = currState->tcr.ips;
+ break;
case EL3:
switch(bits(currState->vaddr, 63,48)) {
case 0:
DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
- if (currState->el == EL2)
- ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
- else
- ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
+ ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
- tg = GrainMapDefault[currState->tcr.tg0];
+ tg = GrainMap_tg0[currState->tcr.tg0];
break;
default:
// invalid addr if top two bytes are not all 0s