summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa/formats/branch.isa2
-rw-r--r--src/arch/arm/isa/formats/uncond.isa2
-rw-r--r--src/arch/arm/isa/insts/misc.isa11
-rw-r--r--src/arch/arm/tlb.cc7
-rw-r--r--src/arch/arm/tlb.hh3
5 files changed, 22 insertions, 3 deletions
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<Addr, int> PageTable;