diff options
author | Adrian Herrera <adrian.herrera@arm.com> | 2019-11-06 13:30:15 +0000 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-12-18 09:14:08 +0000 |
commit | b18c2e575ee079b873767b57604138e00bc1c465 (patch) | |
tree | a00f7f5abcb66194266de22675c3bd5ec003be7f /src | |
parent | 3723cda9c2baa704602acaa8f941a996a636df49 (diff) | |
download | gem5-b18c2e575ee079b873767b57604138e00bc1c465.tar.xz |
arch-arm: AArch64 trap check, arbitrary ECs/Imms
This patch generalises trap checking when accessing system registers
in AArch64. Depending on the accessed register, a different Exception
Class (EC) and immediate value may be set.
Previously this only took SIMD traps into account.
Change-Id: I30717676a210c770531e39e4c6a6e1fbfdfdc583
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23765
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/insts/misc64.cc | 45 | ||||
-rw-r--r-- | src/arch/arm/insts/misc64.hh | 9 |
2 files changed, 27 insertions, 27 deletions
diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc index 2d0422f62..0c263fb65 100644 --- a/src/arch/arm/insts/misc64.cc +++ b/src/arch/arm/insts/misc64.cc @@ -87,32 +87,23 @@ Fault MiscRegOp64::trap(ThreadContext *tc, MiscRegIndex misc_reg, ExceptionLevel el, uint32_t immediate) const { - bool is_vfp_neon = false; + ExceptionClass ec = EC_TRAPPED_MSR_MRS_64; // Check for traps to supervisor (FP/SIMD regs) - if (el <= EL1 && checkEL1Trap(tc, misc_reg, el)) { - - return std::make_shared<SupervisorTrap>(machInst, 0x1E00000, - EC_TRAPPED_SIMD_FP); + if (el <= EL1 && checkEL1Trap(tc, misc_reg, el, ec, immediate)) { + return std::make_shared<SupervisorTrap>(machInst, immediate, ec); } // Check for traps to hypervisor if ((ArmSystem::haveVirtualization(tc) && el <= EL2) && - checkEL2Trap(tc, misc_reg, el, &is_vfp_neon)) { - - return std::make_shared<HypervisorTrap>( - machInst, is_vfp_neon ? 0x1E00000 : immediate, - is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64); + checkEL2Trap(tc, misc_reg, el, ec, immediate)) { + return std::make_shared<HypervisorTrap>(machInst, immediate, ec); } // Check for traps to secure monitor if ((ArmSystem::haveSecurity(tc) && el <= EL3) && - checkEL3Trap(tc, misc_reg, el, &is_vfp_neon)) { - - return std::make_shared<SecureMonitorTrap>( - machInst, - is_vfp_neon ? 0x1E00000 : immediate, - is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64); + checkEL3Trap(tc, misc_reg, el, ec, immediate)) { + return std::make_shared<SecureMonitorTrap>(machInst, immediate, ec); } return NoFault; @@ -120,7 +111,8 @@ MiscRegOp64::trap(ThreadContext *tc, MiscRegIndex misc_reg, bool MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el) const + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const { const CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1); @@ -130,8 +122,11 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg, case MISCREG_FPSR: case MISCREG_FPEXC32_EL2: if ((el == EL0 && cpacr.fpen != 0x3) || - (el == EL1 && !(cpacr.fpen & 0x1))) + (el == EL1 && !(cpacr.fpen & 0x1))) { trap_to_sup = true; + ec = EC_TRAPPED_SIMD_FP; + immediate = 0x1E00000; + } break; default: break; @@ -141,7 +136,8 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg, bool MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el, bool * is_vfp_neon) const + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const { const CPTR cptr = tc->readMiscReg(MISCREG_CPTR_EL2); const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); @@ -149,7 +145,6 @@ MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg, const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); bool trap_to_hyp = false; - *is_vfp_neon = false; if (!inSecureState(scr, cpsr) && (el != EL2)) { switch (misc_reg) { @@ -158,7 +153,8 @@ MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg, case MISCREG_FPSR: case MISCREG_FPEXC32_EL2: trap_to_hyp = cptr.tfp; - *is_vfp_neon = true; + ec = EC_TRAPPED_SIMD_FP; + immediate = 0x1E00000; break; // CPACR case MISCREG_CPACR_EL1: @@ -290,12 +286,12 @@ MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg, bool MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el, bool * is_vfp_neon) const + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const { const CPTR cptr = tc->readMiscReg(MISCREG_CPTR_EL3); bool trap_to_mon = false; - *is_vfp_neon = false; switch (misc_reg) { // FP/SIMD regs @@ -303,7 +299,8 @@ MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg, case MISCREG_FPSR: case MISCREG_FPEXC32_EL2: trap_to_mon = cptr.tfp; - *is_vfp_neon = true; + ec = EC_TRAPPED_SIMD_FP; + immediate = 0x1E00000; break; // CPACR, CPTR case MISCREG_CPACR_EL1: diff --git a/src/arch/arm/insts/misc64.hh b/src/arch/arm/insts/misc64.hh index 741b7b5e0..9f4a6aed4 100644 --- a/src/arch/arm/insts/misc64.hh +++ b/src/arch/arm/insts/misc64.hh @@ -133,13 +133,16 @@ class MiscRegOp64 : public ArmStaticInst ExceptionLevel el, uint32_t immediate) const; private: bool checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el) const; + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const; bool checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el, bool *is_vfp_neon) const; + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const; bool checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg, - ExceptionLevel el, bool *is_vfp_neon) const; + ExceptionLevel el, ExceptionClass &ec, + uint32_t &immediate) const; }; |