diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-18 04:35:46 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-18 04:35:46 +0200 |
commit | fd8597ac315b3be5f5bdb85445345a7ba4627c15 (patch) | |
tree | e0136bfba812c251ada5f369d5f0c051930b6c82 /sys/src/9 | |
parent | 58dc03cec0df3cf569f73ea90d71f17e6a3dc84d (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')
-rw-r--r-- | sys/src/9/port/taslock.c | 4 | ||||
-rw-r--r-- | sys/src/9/zynq/l.s | 25 |
2 files changed, 24 insertions, 5 deletions
diff --git a/sys/src/9/port/taslock.c b/sys/src/9/port/taslock.c index 730538ba7..19c78d358 100644 --- a/sys/src/9/port/taslock.c +++ b/sys/src/9/port/taslock.c @@ -192,8 +192,8 @@ unlock(Lock *l) 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 @@ iunlock(Lock *l) sr = l->sr; l->m = nil; - l->key = 0; coherence(); + l->key = 0; m->ilockdepth--; if(up) up->lastilock = nil; 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 |