summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCurtis Dunham <Curtis.Dunham@arm.com>2016-06-02 16:44:57 +0100
committerCurtis Dunham <Curtis.Dunham@arm.com>2016-06-02 16:44:57 +0100
commitd31c0f165d3978b2b2418379e03c9dd8aedfae7a (patch)
tree39a4e631e6423c6830fe9e3b7f7c2c4fc3ecf65d
parent1a65e946367d22f3504fcf28d6ba2e7ef597d258 (diff)
downloadgem5-d31c0f165d3978b2b2418379e03c9dd8aedfae7a.tar.xz
arm: refactor page table format determination
In particular, when EL0 is in AArch32 but EL1 is AArch64, AArch64 memory translation must be used. This is essential for typical AArch64/32 interworking use cases.
-rw-r--r--src/arch/arm/table_walker.cc16
-rw-r--r--src/arch/arm/tlb.cc8
2 files changed, 13 insertions, 11 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index e1e00442d..82bec2547 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -220,7 +220,11 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
currState->startTime = curTick();
currState->tc = _tc;
- currState->aarch64 = opModeIs64(currOpMode(_tc));
+ // ARM DDI 0487A.f (ARMv8 ARM) pg J8-5672
+ // aarch32/translation/translation/AArch32.TranslateAddress dictates
+ // even AArch32 EL0 will use AArch64 translation if EL1 is in AArch64.
+ currState->aarch64 = opModeIs64(currOpMode(_tc)) ||
+ ((currEL(_tc) == EL0) && ELIs64(_tc, EL1));
currState->el = currEL(_tc);
currState->transState = _trans;
currState->req = _req;
@@ -290,9 +294,8 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
currState->stage2Req = !currState->aarch64 && currState->hcr.vm &&
!isStage2 && !currState->isSecure && !currState->isHyp;
- bool long_desc_format = currState->aarch64 ||
- (_haveLPAE && currState->ttbcr.eae) ||
- _isHyp || isStage2;
+ bool long_desc_format = currState->aarch64 || _isHyp || isStage2 ||
+ longDescFormatInUse(currState->tc);
if (long_desc_format) {
// Helper variables used for hierarchical permissions
@@ -377,7 +380,8 @@ TableWalker::processWalkWrapper()
Fault f;
if (currState->aarch64)
f = processWalkAArch64();
- else if ((_haveLPAE && currState->ttbcr.eae) || currState->isHyp || isStage2)
+ else if (longDescFormatInUse(currState->tc) ||
+ currState->isHyp || isStage2)
f = processWalkLPAE();
else
f = processWalk();
@@ -565,7 +569,7 @@ TableWalker::processWalkLPAE()
ttbr = currState->tc->readMiscReg(MISCREG_HTTBR);
tsz = currState->htcr.t0sz;
} else {
- assert(_haveLPAE && currState->ttbcr.eae);
+ assert(longDescFormatInUse(currState->tc));
// Determine boundaries of TTBR0/1 regions
if (currState->ttbcr.t0sz)
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 1f6910262..db132e2d6 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -951,7 +951,7 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
bool is_fetch = (mode == Execute);
bool is_write = (mode == Write);
- bool long_desc_format = aarch64 || (haveLPAE && ttbcr.eae);
+ bool long_desc_format = aarch64 || longDescFormatInUse(tc);
ArmFault::TranMethod tranMethod = long_desc_format ? ArmFault::LpaeTran
: ArmFault::VmsaTran;
@@ -1247,15 +1247,13 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType)
!isSecure));
scr = tc->readMiscReg(MISCREG_SCR);
isPriv = cpsr.mode != MODE_USER;
- if (haveLPAE && ttbcr.eae) {
- // Long-descriptor translation table format in use
+ if (longDescFormatInUse(tc)) {
uint64_t ttbr_asid = tc->readMiscReg(
flattenMiscRegNsBanked(ttbcr.a1 ? MISCREG_TTBR1
: MISCREG_TTBR0,
tc, !isSecure));
asid = bits(ttbr_asid, 55, 48);
- } else {
- // Short-descriptor translation table format in use
+ } else { // Short-descriptor translation table format in use
CONTEXTIDR context_id = tc->readMiscReg(flattenMiscRegNsBanked(
MISCREG_CONTEXTIDR, tc,!isSecure));
asid = context_id.asid;