// -*- 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
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
/*
- * 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
#include "arch/arm/miscregs.hh"
+#include <tuple>
+
#include "arch/arm/isa.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
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:
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:
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
/*
- * 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
#define __ARCH_ARM_MISCREGS_HH__
#include <bitset>
+#include <tuple>
#include "base/bitunion.hh"
#include "base/compiler.hh"
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,