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.
This commit is contained in:
parent
1a65e94636
commit
d31c0f165d
2 changed files with 13 additions and 11 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue