diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index f203d5257..44a2f5251 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -194,7 +194,7 @@ def format Thumb32BranchesAndMiscCtrl() {{ case 0x1: return new Enterx(machInst); case 0x2: - return new WarnUnimplemented("clrex", machInst); + return new Clrex(machInst); case 0x4: return new WarnUnimplemented("dsb", machInst); case 0x5: diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa index 079b472f3..92e4db22d 100644 --- a/src/arch/arm/isa/formats/uncond.isa +++ b/src/arch/arm/isa/formats/uncond.isa @@ -97,7 +97,7 @@ def format ArmUnconditional() {{ } else if (op1 == 0x57) { switch (op2) { case 0x1: - return new WarnUnimplemented("clrex", machInst); + return new Clrex(machInst); case 0x4: return new WarnUnimplemented("dsb", machInst); case 0x5: diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 341f3d1ce..09364cd23 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -668,6 +668,17 @@ let {{ decoder_output += ImmOpConstructor.subst(setendIop) exec_output += PredOpExecute.subst(setendIop) + clrexCode = ''' + unsigned memAccessFlags = ArmISA::TLB::Clrex|3|Request::LLSC; + fault = xc->read(0, (uint32_t&)Mem, memAccessFlags); + ''' + clrexIop = InstObjParams("clrex", "Clrex","PredOp", + { "code": clrexCode, + "predicate_test": predicateTest },[]) + header_output += BasicDeclare.subst(clrexIop) + decoder_output += BasicConstructor.subst(clrexIop) + exec_output += PredOpExecute.subst(clrexIop) + cpsCode = ''' uint32_t mode = bits(imm, 4, 0); uint32_t f = bits(imm, 5); diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 9cc00a89e..b7e951767 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -355,6 +355,13 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode, DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n", cpsr.mode == MODE_USER, flags & UserMode); + // If this is a clrex instruction, provide a PA of 0 with no fault + // This will force the monitor to set the tracked address to 0 + // a bit of a hack but this effectively clrears this processors monitor + if (flags & Clrex){ + req->setPaddr(0); + return NoFault; + } if (!is_fetch) { assert(flags & MustBeOne); if (sctlr.a || !(flags & AllowUnaligned)) { diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index 1bddd8497..d1ba42b39 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -78,7 +78,8 @@ class TLB : public BaseTLB // Because zero otherwise looks like a valid setting and may be used // accidentally, this bit must be non-zero to show it was used on // purpose. - MustBeOne = 0x20 + MustBeOne = 0x20, + Clrex = 0x40 }; protected: typedef std::multimap PageTable;