summaryrefslogtreecommitdiff
path: root/sys/src/9/zynq
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-06-18 04:35:46 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-06-18 04:35:46 +0200
commitfd8597ac315b3be5f5bdb85445345a7ba4627c15 (patch)
treee0136bfba812c251ada5f369d5f0c051930b6c82 /sys/src/9/zynq
parent58dc03cec0df3cf569f73ea90d71f17e6a3dc84d (diff)
zynq: fix barriers
unlock()/iunlock(): we need to place the coherence() *before* "l->key = 0", so that any stores that where done while holding the lock become observable *before* other processors see the lock released. cas()/tas(): place memory barrier before successfull return to prevent reordering.
Diffstat (limited to 'sys/src/9/zynq')
-rw-r--r--sys/src/9/zynq/l.s25
1 files changed, 22 insertions, 3 deletions
diff --git a/sys/src/9/zynq/l.s b/sys/src/9/zynq/l.s
index 0d7cff8c2..5d35146fd 100644
--- a/sys/src/9/zynq/l.s
+++ b/sys/src/9/zynq/l.s
@@ -55,7 +55,8 @@ _start3:
MOVW $0, R0
MCR 15, 0, R0, C(8), C(7), 0
- ADD $TTBATTR, R4, R1
+ DSB
+ ORR $TTBATTR, R4, R1
MCR 15, 0, R1, C(2), C(0), 0
MOVW $0x20c5047b, R1
MOVW $_virt(SB), R2
@@ -236,8 +237,25 @@ TEXT gotolabel(SB), $-4
MOVW $1, R0
RET
-TEXT tas(SB), $0
+TEXT cas(SB), $0
+ MOVW ov+4(FP), R1
+ MOVW nv+8(FP), R2
+spincas:
+ LDREX (R0), R3
+ CMP.S R3, R1
+ BNE fail
+ STREX R2, (R0), R4
+ CMP.S $0, R4
+ BNE spincas
+ MOVW $1, R0
DMB
+ RET
+fail:
+ CLREX
+ MOVW $0, R0
+ RET
+
+TEXT tas(SB), $0
MOVW $0xDEADDEAD, R2
_tas1:
LDREX (R0), R1
@@ -267,7 +285,7 @@ TEXT ttbget(SB), $0
RET
TEXT ttbput(SB), $0
- ORR $(TTBATTR), R0
+ ORR $TTBATTR, R0
MCR 15, 0, R0, C(2), C(0), 0
RET
@@ -282,6 +300,7 @@ TEXT flushtlb(SB), $0
RET
TEXT setasid(SB), $0
+ DSB /* errata */
MCR 15, 0, R0, C(13), C(0), 1
RET