ref: fd8597ac315b3be5f5bdb85445345a7ba4627c15
parent: 58dc03cec0df3cf569f73ea90d71f17e6a3dc84d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jun 18 00:35:46 EDT 2015
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.
--- a/sys/src/9/port/taslock.c
+++ b/sys/src/9/port/taslock.c
@@ -192,8 +192,8 @@
if(l->p != up)
print("unlock: up changed: pc %#p, acquired at pc %#p, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up);
l->m = nil;
- l->key = 0;
coherence();
+ l->key = 0;
if(up && --up->nlocks == 0 && up->delaysched && islo()){
/*
@@ -231,8 +231,8 @@
sr = l->sr;
l->m = nil;
- l->key = 0;
coherence();
+ l->key = 0;
m->ilockdepth--;
if(up)
up->lastilock = nil;
--- a/sys/src/9/zynq/l.s
+++ b/sys/src/9/zynq/l.s
@@ -55,7 +55,8 @@
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 @@
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 @@
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 @@
RET
TEXT setasid(SB), $0
+ DSB /* errata */
MCR 15, 0, R0, C(13), C(0), 1
RET