arm: change instruction classes to catch hyp traps

Change-Id: I122918d0e3dfd01ae1a4ca4f19240a069115c8b7
This commit is contained in:
Dylan Johnson 2016-08-02 10:38:01 +01:00
parent c20b6c56f6
commit e727a0eeaa
3 changed files with 44 additions and 14 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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: