summaryrefslogtreecommitdiff
path: root/src/arch/arm/linux/process.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-06-09 23:41:03 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-06-09 23:41:03 -0700
commit3ff1e922c22dcc68274b16fcce080cd69b69b47b (patch)
tree07342655b1b6418f950fa9edffe8ca64a90e8091 /src/arch/arm/linux/process.cc
parent37ac2871d5a65dfa19b63c3bed9c6622d6b8b6c9 (diff)
downloadgem5-3ff1e922c22dcc68274b16fcce080cd69b69b47b.tar.xz
ARM: Add a cmpxchg implementation to the "comm page".
This implementation does what it's supposed to (I think), but it's not atomic and doesn't have memory barriers like the kernel's version.
Diffstat (limited to 'src/arch/arm/linux/process.cc')
-rw-r--r--src/arch/arm/linux/process.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 620bcf116..bc6388b73 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -482,6 +482,18 @@ ArmLinuxProcess::startup()
swiNeg1, sizeof(swiNeg1));
}
+ // This -should- be atomic, but I don't think all the support that we'd
+ // need is implemented. There should also be memory barriers around it.
+ uint8_t cmpxchg[] =
+ {
+ 0x00, 0x30, 0x92, 0xe5, //ldr r3, [r2]
+ 0x00, 0x30, 0x53, 0xe0, //subs r3, r3, r0
+ 0x00, 0x10, 0x92, 0x05, //streq r1, [r2]
+ 0x03, 0x00, 0xa0, 0xe1, //mov r0, r3
+ 0x0e, 0xf0, 0xa0, 0xe1 //usr_ret lr
+ };
+ tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
+
uint8_t get_tls[] =
{
0x08, 0x00, 0x9f, 0xe5, //ldr r0, [pc, #(16 - 8)]