shithub: riscv

Download patch

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