1 #ifndef __SPINLOCK_H__
2 #define __SPINLOCK_H__
3 
4 #include <gctypes.h>
5 #include <lwp_threads.h>
6 
7 typedef struct {
8 	vu32 lock;
9 } spinlock_t;
10 
11 #define SPIN_LOCK_UNLOCKED		(spinlock_t){0}
12 
13 #define spin_lock_init(x)		do { *(x) = SPIN_LOCK_UNLOCKED; }while(0)
14 
_test_and_set(u32 * atomic)15 static __inline__ u32 _test_and_set(u32 *atomic)
16 {
17 	 register u32 ret;
18 
19 	__asm__ __volatile__ ("1: lwarx %0,0,%1\n"
20 						  "   cmpwi   0,%0,0\n"
21 						  "   bne-    2f\n"
22 						  "   stwcx.  %2,0,%1\n"
23 						  "   bne-    1b\n"
24 						  "   isync\n"
25 						  "2:" : "=&r"(ret)
26 							   : "r"(atomic), "r"(1)
27 							   : "cr0", "memory");
28 
29 	return ret;
30 }
31 
atomic_inc(u32 * pint)32 static __inline__ u32 atomic_inc(u32 *pint)
33 {
34 	register u32 ret;
35 	__asm__ __volatile__(
36 		"1:	lwarx	%0,0,%1\n\
37 			addi	%0,%0,1\n\
38 			stwcx.	%0,0,%1\n\
39 			bne-	1b\n\
40 			isync\n"
41 			: "=&r"(ret) : "r"(pint)
42 			: "cr0", "memory");
43 	return ret;
44 }
45 
atomic_dec(u32 * pint)46 static __inline__ u32 atomic_dec(u32 *pint)
47 {
48 	register u32 ret;
49 	__asm__ __volatile__(
50 		"1:	lwarx	%0,0,%1\n\
51 			addi	%0,%0,-1\n\
52 			stwcx.	%0,0,%1\n\
53 			bne-	1b\n\
54 			isync\n"
55 			: "=&r"(ret) : "r"(pint)
56 			: "cr0", "memory");
57 	return ret;
58 }
59 
spin_lock(spinlock_t * lock)60 static __inline__ void spin_lock(spinlock_t *lock)
61 {
62         register u32 tmp;
63 
64         __asm__ __volatile__(
65 	   "b       1f                      # spin_lock\n\
66 2:      lwzx    %0,0,%1\n\
67         cmpwi   0,%0,0\n\
68         bne+    2b\n\
69 1:      lwarx   %0,0,%1\n\
70         cmpwi   0,%0,0\n\
71         bne-    2b\n\
72         stwcx.  %2,0,%1\n\
73         bne-    2b\n\
74         isync"
75         : "=&r"(tmp)
76         : "r"(lock), "r"(1)
77         : "cr0", "memory");
78 }
79 
spin_lock_irqsave(spinlock_t * lock,register u32 * p_isr_level)80 static __inline__ void spin_lock_irqsave(spinlock_t *lock,register u32 *p_isr_level)
81 {
82 	register u32 level;
83     register u32 tmp;
84 
85 	_CPU_ISR_Disable(level);
86 
87     __asm__ __volatile__(
88    "	b       1f                      # spin_lock\n\
89 	2:  lwzx    %0,0,%1\n\
90 		cmpwi   0,%0,0\n\
91 		bne+    2b\n\
92 	1:	lwarx   %0,0,%1\n\
93 		cmpwi   0,%0,0\n\
94 		bne-    2b\n\
95 		stwcx.  %2,0,%1\n\
96 		bne-    2b\n\
97 		isync"
98     : "=&r"(tmp)
99     : "r"(lock), "r"(1)
100     : "cr0", "memory");
101 
102 	*p_isr_level = level;
103 }
104 
spin_unlock(spinlock_t * lock)105 static __inline__ void spin_unlock(spinlock_t *lock)
106 {
107         __asm__ __volatile__("eieio             # spin_unlock": : :"memory");
108         lock->lock = 0;
109 }
110 
spin_unlock_irqrestore(spinlock_t * lock,register u32 isr_level)111 static __inline__ void spin_unlock_irqrestore(spinlock_t *lock,register u32 isr_level)
112 {
113     __asm__ __volatile__(
114 		"eieio             # spin_unlock"
115 		: : :"memory");
116     lock->lock = 0;
117 
118 	_CPU_ISR_Restore(isr_level);
119 }
120 
121 typedef struct {
122 	vu32 lock;
123 } rwlock_t;
124 
125 #define RW_LOCK_UNLOCKED		(rwlock_t){0}
126 
127 #define read_lock_init(lp)		do { *(lp) = RW_LOCK_UNLOCKED; }while(0)
128 
read_lock(rwlock_t * rw)129 static __inline__ void read_lock(rwlock_t *rw)
130 {
131         register u32 tmp;
132 
133         __asm__ __volatile__(
134         "b              2f              # read_lock\n\
135 1:      lwzx            %0,0,%1\n\
136         cmpwi           0,%0,0\n\
137         blt+            1b\n\
138 2:      lwarx           %0,0,%1\n\
139         addic.          %0,%0,1\n\
140         ble-            1b\n\
141         stwcx.          %0,0,%1\n\
142         bne-            2b\n\
143         isync"
144         : "=&r"(tmp)
145         : "r"(&rw->lock)
146         : "cr0", "memory");
147 }
148 
read_unlock(rwlock_t * rw)149 static __inline__ void read_unlock(rwlock_t *rw)
150 {
151         register u32 tmp;
152 
153         __asm__ __volatile__(
154         "eieio                          # read_unlock\n\
155 1:      lwarx           %0,0,%1\n\
156         addic           %0,%0,-1\n\
157         stwcx.          %0,0,%1\n\
158         bne-            1b"
159         : "=&r"(tmp)
160         : "r"(&rw->lock)
161         : "cr0", "memory");
162 }
163 
write_lock(rwlock_t * rw)164 static __inline__ void write_lock(rwlock_t *rw)
165 {
166         register u32 tmp;
167 
168         __asm__ __volatile__(
169         "b              2f              # write_lock\n\
170 1:      lwzx            %0,0,%1\n\
171         cmpwi           0,%0,0\n\
172         bne+            1b\n\
173 2:      lwarx           %0,0,%1\n\
174         cmpwi           0,%0,0\n\
175         bne-            1b\n\
176         stwcx.          %2,0,%1\n\
177         bne-            2b\n\
178         isync"
179         : "=&r"(tmp)
180         : "r"(&rw->lock), "r"(-1)
181         : "cr0", "memory");
182 }
183 
write_unlock(rwlock_t * rw)184 static __inline__ void write_unlock(rwlock_t *rw)
185 {
186         __asm__ __volatile__("eieio             # write_unlock": : :"memory");
187         rw->lock = 0;
188 }
189 
190 #endif
191