diff options
author | Min Kyu Jeong <minkyu.jeong@arm.com> | 2010-08-25 19:10:43 -0500 |
---|---|---|
committer | Min Kyu Jeong <minkyu.jeong@arm.com> | 2010-08-25 19:10:43 -0500 |
commit | c23e8c31ebd4e856f205f5bdd8f4eb5e1eec87ee (patch) | |
tree | a04e718c24dc0d40829342042fba144b187fd1bb | |
parent | 8376f7bca3814844ab9cc592ff8f32c702a18629 (diff) | |
download | gem5-c23e8c31ebd4e856f205f5bdd8f4eb5e1eec87ee.tar.xz |
ARM: Adding a bogus fault that does nothing.
This fault can used to flush the pipe, not including the faulting instruction.
The particular case I needed this was for a self-modifying code. It needed to
drain the store queue and force the following instruction to refetch from
icache. DCCMVAC cp15 mcr instruction is modified to raise this fault.
-rw-r--r-- | src/arch/arm/faults.cc | 19 | ||||
-rw-r--r-- | src/arch/arm/faults.hh | 8 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/misc.isa | 2 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/unimp.isa | 30 |
4 files changed, 55 insertions, 4 deletions
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<Interrupt>::vals = template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; +template<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = + {"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values + Addr ArmFault::getVector(ThreadContext *tc) { @@ -213,12 +216,22 @@ AbortFault<T>::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<PrefetchAbort>::invoke(ThreadContext *tc); template void AbortFault<DataAbort>::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<DataAbort> class Interrupt : public ArmFaultVals<Interrupt> {}; class FastInterrupt : public ArmFaultVals<FastInterrupt> {}; +// A fault that flushes the pipe, excluding the faulting instructions +class FlushPipe : public ArmFaultVals<FlushPipe> +{ + 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(); + } }}; |