summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/insts/pseudo.cc31
-rw-r--r--src/arch/arm/insts/pseudo.hh18
-rw-r--r--src/arch/arm/isa/formats/misc.isa9
3 files changed, 44 insertions, 14 deletions
diff --git a/src/arch/arm/insts/pseudo.cc b/src/arch/arm/insts/pseudo.cc
index de4a5afdc..526369b33 100644
--- a/src/arch/arm/insts/pseudo.cc
+++ b/src/arch/arm/insts/pseudo.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 ARM Limited
+ * Copyright (c) 2014,2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -182,21 +182,40 @@ WarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const
-FlushPipeInst::FlushPipeInst(const char *_mnemonic, ExtMachInst _machInst)
+McrMrcMiscInst::McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
+ uint64_t _iss, MiscRegIndex _miscReg)
: ArmStaticInst(_mnemonic, _machInst, No_OpClass)
{
flags[IsNonSpeculative] = true;
+ iss = _iss;
+ miscReg = _miscReg;
}
Fault
-FlushPipeInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
+McrMrcMiscInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
{
- Fault fault = std::make_shared<FlushPipe>();
- return fault;
+ uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR);
+ uint32_t hcr = xc->readMiscReg(MISCREG_HCR);
+ uint32_t scr = xc->readMiscReg(MISCREG_SCR);
+ uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR);
+ uint32_t hstr = xc->readMiscReg(MISCREG_HSTR);
+ uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR);
+
+ bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr,
+ hcptr, iss);
+ if (hypTrap) {
+ return std::make_shared<HypervisorTrap>(machInst, iss,
+ EC_TRAPPED_CP15_MCR_MRC);
+ }
+
+ if (miscReg == MISCREG_DCCMVAC)
+ return std::make_shared<FlushPipe>();
+ else
+ return NoFault;
}
std::string
-FlushPipeInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+McrMrcMiscInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (pipe flush)", mnemonic);
}
diff --git a/src/arch/arm/insts/pseudo.hh b/src/arch/arm/insts/pseudo.hh
index 3bf3b2c3a..fe28789f0 100644
--- a/src/arch/arm/insts/pseudo.hh
+++ b/src/arch/arm/insts/pseudo.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 ARM Limited
+ * Copyright (c) 2014,2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -115,10 +115,21 @@ class WarnUnimplemented : public ArmStaticInst
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
-class FlushPipeInst : public ArmStaticInst
+/**
+ * Certain mrc/mcr instructions act as nops or flush the pipe based on what
+ * register the instruction is trying to access. This inst/class exists so that
+ * we can still check for hyp traps, as the normal nop instruction
+ * does not.
+ */
+class McrMrcMiscInst : public ArmStaticInst
{
+ private:
+ uint64_t iss;
+ MiscRegIndex miscReg;
+
public:
- FlushPipeInst(const char *_mnemonic, ExtMachInst _machInst);
+ McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
+ uint64_t _iss, MiscRegIndex _miscReg);
Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const;
@@ -127,5 +138,4 @@ class FlushPipeInst : public ArmStaticInst
};
-
#endif
diff --git a/src/arch/arm/isa/formats/misc.isa b/src/arch/arm/isa/formats/misc.isa
index f81b96f2f..43a7cc975 100644
--- a/src/arch/arm/isa/formats/misc.isa
+++ b/src/arch/arm/isa/formats/misc.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
@@ -181,15 +181,16 @@ let {{
switch (miscReg) {
case MISCREG_NOP:
- return new NopInst(machInst);
+ return new McrMrcMiscInst(isRead ? "mrc nop" : "mcr nop",
+ machInst, iss, MISCREG_NOP);
case MISCREG_CP15_UNIMPL:
return new FailUnimplemented(isRead ? "mrc unkown" : "mcr unkown",
machInst,
csprintf("miscreg crn:%d opc1:%d crm:%d opc2:%d %s unknown",
crn, opc1, crm, opc2, isRead ? "read" : "write"));
case MISCREG_DCCMVAC:
- return new FlushPipeInst(
- isRead ? "mrc dccmvac" : "mcr dccmvac", machInst);
+ return new McrMrcMiscInst(isRead ? "mrc dccmvac" : "mcr dccmvac",
+ machInst, iss, MISCREG_DCCMVAC);
case MISCREG_CP15ISB:
return new Isb(machInst, iss);
case MISCREG_CP15DSB: