diff options
-rw-r--r-- | src/arch/arm/isa/insts/misc.isa | 36 | ||||
-rw-r--r-- | src/arch/arm/miscregs.cc | 26 | ||||
-rw-r--r-- | src/arch/arm/miscregs.hh | 41 |
3 files changed, 71 insertions, 32 deletions
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 77c22e6ca..6d6e56b8f 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2013 ARM Limited +// Copyright (c) 2010-2013,2017 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -814,7 +814,9 @@ let {{ mrc14code = ''' MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1); - if (!canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) { + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); + if (!can_read || undefined) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } @@ -836,7 +838,9 @@ let {{ mcr14code = ''' MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest); - if (!canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) { + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); + if (undefined || !can_write) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } @@ -861,12 +865,13 @@ let {{ xc->tcBase()->flattenMiscIndex(preFlatOp1); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); - bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); - + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } @@ -891,12 +896,14 @@ let {{ xc->tcBase()->flattenMiscIndex(preFlatDest); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); - bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } @@ -920,12 +927,13 @@ let {{ MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(preFlatOp1); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); - bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); - + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } @@ -949,12 +957,14 @@ let {{ MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(preFlatDest); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); - bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); } diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index 09af405ad..20861480b 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013, 2015-2016 ARM Limited + * Copyright (c) 2010-2013, 2015-2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -41,6 +41,8 @@ #include "arch/arm/miscregs.hh" +#include <tuple> + #include "arch/arm/isa.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" @@ -1967,11 +1969,12 @@ decodeCP15Reg64(unsigned crm, unsigned opc1) return MISCREG_CP15_UNIMPL; } -bool -canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc) +std::tuple<bool, bool> +canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr) { bool secure = !scr.ns; - bool canRead; + bool canRead = false; + bool undefined = false; switch (cpsr.mode) { case MODE_USER: @@ -1995,18 +1998,19 @@ canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc) canRead = miscRegInfo[reg][MISCREG_HYP_RD]; break; default: - panic("Unrecognized mode setting in CPSR.\n"); + undefined = true; } // can't do permissions checkes on the root of a banked pair of regs assert(!miscRegInfo[reg][MISCREG_BANKED]); - return canRead; + return std::make_tuple(canRead, undefined); } -bool -canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc) +std::tuple<bool, bool> +canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr) { bool secure = !scr.ns; - bool canWrite; + bool canWrite = false; + bool undefined = false; switch (cpsr.mode) { case MODE_USER: @@ -2030,11 +2034,11 @@ canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc) canWrite = miscRegInfo[reg][MISCREG_HYP_WR]; break; default: - panic("Unrecognized mode setting in CPSR.\n"); + undefined = true; } // can't do permissions checkes on the root of a banked pair of regs assert(!miscRegInfo[reg][MISCREG_BANKED]); - return canWrite; + return std::make_tuple(canWrite, undefined); } int diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 742295c29..779ead7f4 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 ARM Limited + * Copyright (c) 2010-2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -44,6 +44,7 @@ #define __ARCH_ARM_MISCREGS_HH__ #include <bitset> +#include <tuple> #include "base/bitunion.hh" #include "base/compiler.hh" @@ -1847,13 +1848,37 @@ namespace ArmISA EndBitUnion(CPTR) - // Checks read access permissions to coproc. registers - bool canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, - ThreadContext *tc); - - // Checks write access permissions to coproc. registers - bool canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, - ThreadContext *tc); + /** + * Check for permission to read coprocessor registers. + * + * Checks whether an instruction at the current program mode has + * permissions to read the coprocessor registers. This function + * returns whether the check is undefined and if not whether the + * read access is permitted. + * + * @param the misc reg indicating the coprocessor + * @param the SCR + * @param the CPSR + * @return a tuple of booleans: can_read, undefined + */ + std::tuple<bool, bool> canReadCoprocReg(MiscRegIndex reg, SCR scr, + CPSR cpsr); + + /** + * Check for permission to write coprocessor registers. + * + * Checks whether an instruction at the current program mode has + * permissions to write the coprocessor registers. This function + * returns whether the check is undefined and if not whether the + * write access is permitted. + * + * @param the misc reg indicating the coprocessor + * @param the SCR + * @param the CPSR + * @return a tuple of booleans: can_write, undefined + */ + std::tuple<bool, bool> canWriteCoprocReg(MiscRegIndex reg, SCR scr, + CPSR cpsr); // Checks read access permissions to AArch64 system registers bool canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, |