diff -r 5ef3d161c661 -r 3da29bd2d887 src/arch/arm/isa/formats/branch.isa --- a/src/arch/arm/isa/formats/branch.isa Fri Aug 13 11:54:24 2010 -0500 +++ b/src/arch/arm/isa/formats/branch.isa Fri Aug 13 11:54:59 2010 -0500 @@ -194,7 +194,7 @@ 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 -r 5ef3d161c661 -r 3da29bd2d887 src/arch/arm/isa/formats/uncond.isa --- a/src/arch/arm/isa/formats/uncond.isa Fri Aug 13 11:54:24 2010 -0500 +++ b/src/arch/arm/isa/formats/uncond.isa Fri Aug 13 11:54:59 2010 -0500 @@ -97,7 +97,7 @@ } 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 -r 5ef3d161c661 -r 3da29bd2d887 src/arch/arm/isa/insts/misc.isa --- a/src/arch/arm/isa/insts/misc.isa Fri Aug 13 11:54:24 2010 -0500 +++ b/src/arch/arm/isa/insts/misc.isa Fri Aug 13 11:54:59 2010 -0500 @@ -666,6 +666,17 @@ 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); @@ -697,4 +708,5 @@ header_output += ImmOpDeclare.subst(cpsIop) decoder_output += ImmOpConstructor.subst(cpsIop) exec_output += PredOpExecute.subst(cpsIop) + }}; diff -r 5ef3d161c661 -r 3da29bd2d887 src/arch/arm/tlb.hh --- a/src/arch/arm/tlb.hh Fri Aug 13 11:54:24 2010 -0500 +++ b/src/arch/arm/tlb.hh Fri Aug 13 11:54:59 2010 -0500 @@ -78,7 +78,8 @@ // 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; diff -r 5ef3d161c661 -r 3da29bd2d887 src/arch/arm/tlb.cc --- a/src/arch/arm/tlb.cc Fri Aug 13 11:54:24 2010 -0500 +++ b/src/arch/arm/tlb.cc Fri Aug 13 11:54:59 2010 -0500 @@ -355,6 +355,13 @@ 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)) {