diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 79973185d..2a6b7c359 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -71,6 +71,9 @@ template<> ArmFault::FaultVals ArmFaultVals::vals = template<> ArmFault::FaultVals ArmFaultVals::vals = {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; +template<> ArmFault::FaultVals ArmFaultVals::vals = + {"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values + Addr ArmFault::getVector(ThreadContext *tc) { @@ -213,12 +216,22 @@ AbortFault::invoke(ThreadContext *tc) tc->setMiscReg(T::FarIndex, faultAddr); } +void +FlushPipe::invoke(ThreadContext *tc) { + DPRINTF(Faults, "Invoking FlushPipe Fault\n"); + + // Set the PC to the next instruction of the faulting instruction. + // Net effect is simply squashing all instructions behind and + // start refetching from the next instruction. + tc->setPC(tc->readNextPC()); + tc->setNextPC(tc->readNextNPC()); + tc->setMicroPC(0); + tc->setNextMicroPC(1); +} + template void AbortFault::invoke(ThreadContext *tc); template void AbortFault::invoke(ThreadContext *tc); // return via SUBS pc, lr, xxx; rfe, movs, ldm - - } // namespace ArmISA - diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 7dd881435..3eef0e551 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -227,6 +227,14 @@ class DataAbort : public AbortFault class Interrupt : public ArmFaultVals {}; class FastInterrupt : public ArmFaultVals {}; +// A fault that flushes the pipe, excluding the faulting instructions +class FlushPipe : public ArmFaultVals +{ + public: + FlushPipe() {} + void invoke(ThreadContext *tc); +}; + static inline Fault genMachineCheckFault() { return new Reset(); diff --git a/src/arch/arm/isa/formats/misc.isa b/src/arch/arm/isa/formats/misc.isa index 884d93066..2d47c286f 100644 --- a/src/arch/arm/isa/formats/misc.isa +++ b/src/arch/arm/isa/formats/misc.isa @@ -111,7 +111,7 @@ let {{ return new WarnUnimplemented( isRead ? "mrc dcimvac" : "mcr dcimvac", machInst); case MISCREG_DCCMVAC: - return new WarnUnimplemented( + return new FlushPipeInst( isRead ? "mrc dccmvac" : "mcr dccmvac", machInst); case MISCREG_DCCMVAU: return new WarnUnimplemented( diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa index a746f8a7b..a0e0afd32 100644 --- a/src/arch/arm/isa/formats/unimp.isa +++ b/src/arch/arm/isa/formats/unimp.isa @@ -101,6 +101,22 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; + + class FlushPipeInst : public ArmStaticInst + { + public: + FlushPipeInst(const char *_mnemonic, ExtMachInst _machInst) + : ArmStaticInst(_mnemonic, _machInst, No_OpClass) + { + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + }; }}; output decoder {{ @@ -117,6 +133,13 @@ output decoder {{ { return csprintf("%-10s (unimplemented)", mnemonic); } + + std::string + FlushPipeInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (pipe flush)", mnemonic); + } }}; output exec {{ @@ -142,6 +165,13 @@ output exec {{ return NoFault; } + + Fault + FlushPipeInst::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + return new FlushPipe(); + } }};