summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa/insts/misc.isa36
-rw-r--r--src/arch/arm/miscregs.cc26
-rw-r--r--src/arch/arm/miscregs.hh41
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,