diff -r de4d73880c47 -r 9cfb61b56f3a src/arch/arm/faults.hh --- a/src/arch/arm/faults.hh Mon Aug 23 11:32:59 2010 -0500 +++ b/src/arch/arm/faults.hh Mon Aug 23 11:33:14 2010 -0500 @@ -227,6 +227,14 @@ 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 -r de4d73880c47 -r 9cfb61b56f3a src/arch/arm/faults.cc --- a/src/arch/arm/faults.cc Mon Aug 23 11:32:59 2010 -0500 +++ b/src/arch/arm/faults.cc Mon Aug 23 11:33:14 2010 -0500 @@ -71,6 +71,9 @@ 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 @@ 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 -r de4d73880c47 -r 9cfb61b56f3a src/arch/arm/isa/formats/misc.isa --- a/src/arch/arm/isa/formats/misc.isa Mon Aug 23 11:32:59 2010 -0500 +++ b/src/arch/arm/isa/formats/misc.isa Mon Aug 23 11:33:14 2010 -0500 @@ -111,7 +111,7 @@ 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 -r de4d73880c47 -r 9cfb61b56f3a src/arch/arm/isa/formats/unimp.isa --- a/src/arch/arm/isa/formats/unimp.isa Mon Aug 23 11:32:59 2010 -0500 +++ b/src/arch/arm/isa/formats/unimp.isa Mon Aug 23 11:33:14 2010 -0500 @@ -101,6 +101,22 @@ 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 @@ { 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 @@ return NoFault; } + + Fault + FlushPipeInst::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + return new FlushPipe(); + } }};