From fd8597ac315b3be5f5bdb85445345a7ba4627c15 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 18 Jun 2015 04:35:46 +0200 Subject: 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. --- sys/src/9/port/taslock.c | 4 ++-- 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 -- cgit v1.2.3