From f48ad5b29d6f291b4f3679ff5fb7b5beae10d6fa Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Thu, 2 Jun 2016 13:38:30 +0100 Subject: arm: Correctly check FP/SIMD access permission in aarch32 The current implementation of aarch32 FP/SIMD in gem5 assumes that EL1 and higher are all 32-bit. This breaks interprocessing since an aarch64 EL1 uses different enable/disable bits. This change updates the permission checks to according to what is prescribed by the ARM ARM. Change-Id: Icdcef31b00644cfeebec00216b3993aa1de12b88 Signed-off-by: Andreas Sandberg Reviewed-by: Mitch Hayenga Reviewed-by: Nathanael Premillieu --- src/arch/arm/isa/insts/fp.isa | 2 +- src/arch/arm/isa/templates/neon.isa | 27 ++----- src/arch/arm/isa/templates/vfp.isa | 154 +++++++++++------------------------- 3 files changed, 52 insertions(+), 131 deletions(-) (limited to 'src/arch/arm/isa') diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index 9a7f3f8a0..34dff5139 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -260,7 +260,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop); exec_output += PredOpExecute.subst(vmrsFpscrIop); - vmrsApsrFpscrCode = vmrsApsrEnabledCheckCode + ''' + vmrsApsrFpscrCode = vfpEnabledCheckCode + ''' FPSCR fpscr = FpCondCodes; CondCodesNZ = (fpscr.n << 1) | fpscr.z; CondCodesC = fpscr.c; diff --git a/src/arch/arm/isa/templates/neon.isa b/src/arch/arm/isa/templates/neon.isa index 45df741e7..9e9b79957 100644 --- a/src/arch/arm/isa/templates/neon.isa +++ b/src/arch/arm/isa/templates/neon.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2012 ARM Limited +// Copyright (c) 2010-2012, 2016 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -40,26 +40,11 @@ let {{ simdEnabledCheckCode = ''' { - uint32_t issEnCheck; - bool trapEnCheck; - uint32_t seq; - if (!vfpNeonEnabled(seq, Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, - trapEnCheck, xc->tcBase(), Fpexc, true)) - {return disabledFault();} - if (trapEnCheck) { - CPSR cpsrEnCheck = Cpsr; - if (cpsrEnCheck.mode == MODE_HYP) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } else { - if (!inSecureState(Scr, Cpsr)) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } - } - } + Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + true, true); + if (fault != NoFault) + return fault; } ''' }}; diff --git a/src/arch/arm/isa/templates/vfp.isa b/src/arch/arm/isa/templates/vfp.isa index 4da00e8d5..1c945cddc 100644 --- a/src/arch/arm/isa/templates/vfp.isa +++ b/src/arch/arm/isa/templates/vfp.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2013 ARM Limited +// Copyright (c) 2010-2013, 2016 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -39,125 +39,61 @@ let {{ vfpEnabledCheckCode = ''' - uint32_t issEnCheck; - bool trapEnCheck; - uint32_t seq; - if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, - trapEnCheck, xc->tcBase(), Fpexc)) - {return disabledFault();} - if (trapEnCheck) { - CPSR cpsrEnCheck = Cpsr; - if (cpsrEnCheck.mode == MODE_HYP) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR, mnemonic); - } else { - if (!inSecureState(Scr, Cpsr)) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } - } - } + { + Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + true, false); + if (fault != NoFault) + return fault; + } ''' vfp64EnabledCheckCode = ''' - CPSR cpsrEnCheck = Cpsr; - ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsrEnCheck.el; - if (!vfpNeon64Enabled(Cpacr64, el)) - return std::make_shared(machInst, 0x1E00000, - EC_TRAPPED_SIMD_FP); - - if (ArmSystem::haveVirtualization(xc->tcBase()) && el <= EL2) { - HCPTR cptrEnCheck = xc->tcBase()->readMiscReg(MISCREG_CPTR_EL2); - if (cptrEnCheck.tfp) - return std::make_shared(machInst, 0x1E00000, - EC_TRAPPED_SIMD_FP); - } - - if (ArmSystem::haveSecurity(xc->tcBase())) { - HCPTR cptrEnCheck = xc->tcBase()->readMiscReg(MISCREG_CPTR_EL3); - if (cptrEnCheck.tfp) - return std::make_shared(machInst, 0x1E00000, - EC_TRAPPED_SIMD_FP); - } + { + Fault fault = checkFPAdvSIMDEnabled64(xc->tcBase(), Cpsr, Cpacr64); + if (fault != NoFault) + return fault; + } ''' vmsrEnabledCheckCode = ''' - uint32_t issEnCheck; - bool trapEnCheck; - uint32_t seq; - if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, - trapEnCheck, xc->tcBase())) - if (dest != (int)MISCREG_FPEXC && dest != (int)MISCREG_FPSID) - {return disabledFault();} - if (!inPrivilegedMode(Cpsr)) - if (dest != (int)MISCREG_FPSCR) - return disabledFault(); - if (trapEnCheck) { - CPSR cpsrEnCheck = Cpsr; - if (cpsrEnCheck.mode == MODE_HYP) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR, mnemonic); - } else { - if (!inSecureState(Scr, Cpsr)) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } - } + { + Fault fault = NoFault; + if (dest == (int)MISCREG_FPSCR) { + fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + true, false); + } else if (!inPrivilegedMode(Cpsr)) { + fault = disabledFault(); + } else { + fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + false, false); } + + if (fault != NoFault) + return fault; + } ''' vmrsEnabledCheckCode = ''' - uint32_t issEnCheck; - bool trapEnCheck; - uint32_t seq; - if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, - trapEnCheck, xc->tcBase())) - if (op1 != (int)MISCREG_FPEXC && op1 != (int)MISCREG_FPSID && - op1 != (int)MISCREG_MVFR0 && op1 != (int)MISCREG_MVFR1) - {return disabledFault();} - if (!inPrivilegedMode(Cpsr)) - if (op1 != (int)MISCREG_FPSCR) - return disabledFault(); - if (trapEnCheck) { - CPSR cpsrEnCheck = Cpsr; - if (cpsrEnCheck.mode == MODE_HYP) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR, mnemonic); - } else { - if (!inSecureState(Scr, Cpsr)) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } - } - } - ''' - vmrsApsrEnabledCheckCode = ''' - uint32_t issEnCheck; - bool trapEnCheck; - uint32_t seq; - if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, - trapEnCheck, xc->tcBase())) - {return disabledFault();} - if (trapEnCheck) { - CPSR cpsrEnCheck = Cpsr; - if (cpsrEnCheck.mode == MODE_HYP) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR, mnemonic); - } else { - if (!inSecureState(Scr, Cpsr)) { - return std::make_shared( - machInst, issEnCheck, - EC_TRAPPED_HCPTR); - } - } + { + Fault fault = NoFault; + if (op1 == (int)MISCREG_FPSCR) { + fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + true, false); + } else if (!inPrivilegedMode(Cpsr)) { + fault = disabledFault(); + } else { + fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(), + Cpsr, Cpacr, Nsacr, Fpexc, + false, false); } + + if (fault != NoFault) + return fault; + } ''' }}; -- cgit v1.2.3