arch-arm: Add System register trap check for EL1

This change adds and refactors the register trap checks
for EL1 in the same function, unifying the registry trapping

Change-Id: Ief3e0a9f70cc8cd44c1c8215515f36168927362d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31694
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Jordi Vaquero
2020-07-22 13:20:46 +02:00
parent 5fe43e8496
commit 11e0dccbd5
4 changed files with 36 additions and 25 deletions

View File

@@ -114,9 +114,26 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
uint32_t &immediate) const
{
const CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1);
const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
bool trap_to_sup = false;
switch (misc_reg) {
case MISCREG_DAIF:
trap_to_sup = !scr.ns && !scr.eel2 && !sctlr.uma && el == EL0;
trap_to_sup = trap_to_sup ||
(el == EL0 && (scr.ns || scr.eel2) && !hcr.tge && !sctlr.uma);
break;
case MISCREG_DC_ZVA_Xt:
// In syscall-emulation mode, this test is skipped and DCZVA is always
// allowed at EL0
trap_to_sup = el == EL0 && !sctlr.dze && FullSystem;
break;
case MISCREG_DC_CIVAC_Xt:
case MISCREG_DC_CVAC_Xt:
trap_to_sup = el == EL0 && !sctlr.uci;
break;
case MISCREG_FPCR:
case MISCREG_FPSR:
case MISCREG_FPEXC32_EL2:
@@ -127,6 +144,24 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
immediate = 0x1E00000;
}
break;
case MISCREG_DC_CVAU_Xt:
trap_to_sup = !sctlr.uci && (!hcr.tge || (!scr.ns && !scr.eel2)) &&
el == EL1;
break;
case MISCREG_CTR_EL0:
trap_to_sup = el == EL0 && !sctlr.uct &&
(!hcr.tge || (!scr.ns && !scr.eel2));
break;
case MISCREG_MDCCSR_EL0:
{
DBGDS32 mdscr = tc->readMiscReg(MISCREG_MDSCR_EL1);
trap_to_sup = el == EL0 && mdscr.tdcc &&
(hcr.tge == 0x0 || ( scr.ns == 0x0));
}
break;
case MISCREG_ZCR_EL1:
trap_to_sup = el == EL1 && ((cpacr.zen & 0x1) == 0x0);
break;
// Generic Timer
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
trap_to_sup = el == EL0 &&

View File

@@ -312,14 +312,6 @@ let {{
msrMrs64EnabledCheckCode = '''
// Check for read/write access right
if (!can%sAArch64SysReg(flat_idx, Hcr64, Scr64, cpsr, xc->tcBase())) {
if (flat_idx == MISCREG_DAIF ||
flat_idx == MISCREG_DC_ZVA_Xt ||
flat_idx == MISCREG_DC_CVAC_Xt ||
flat_idx == MISCREG_DC_CIVAC_Xt
)
return std::make_shared<UndefinedInstruction>(
machInst, 0, EC_TRAPPED_MSR_MRS_64,
mnemonic);
return std::make_shared<UndefinedInstruction>(machInst, false,
mnemonic);
}

View File

@@ -1415,23 +1415,6 @@ canWriteAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
if ((reg == MISCREG_SP_EL0) && (tc->readMiscReg(MISCREG_SPSEL) == 0))
return false;
ExceptionLevel el = currEL(cpsr);
if (reg == MISCREG_DAIF) {
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
if (el == EL0 && !sctlr.uma)
return false;
}
if (FullSystem && reg == MISCREG_DC_ZVA_Xt) {
// In syscall-emulation mode, this test is skipped and DCZVA is always
// allowed at EL0
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
if (el == EL0 && !sctlr.dze)
return false;
}
if (reg == MISCREG_DC_CVAC_Xt || reg == MISCREG_DC_CIVAC_Xt) {
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
if (el == EL0 && !sctlr.uci)
return false;
}
bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
bool el2_host = EL2Enabled(tc) && hcr.e2h;

View File

@@ -730,6 +730,7 @@ namespace ArmISA
Bitfield<14> hde;
Bitfield<13> res0_;
Bitfield<12> udccdis;
Bitfield<12> tdcc;
Bitfield<11, 7> res0_2;
Bitfield<6> err;
Bitfield<5, 2> moe;