Kernel/arm7 - Serial works (realview-pb-a8)
[tpg/acess2.git] / Kernel / arch / arm7 / include / lock.h
1 /*
2  * Acess2
3  * ARM7 Architecture
4  *
5  * lock.h - Hardware level spinlocks
6  */
7 #ifndef _LOCK_H_
8 #define _LOCK_H_
9
10 // === CODE ===
11 struct sShortSpinlock {
12          int    Lock;
13 };
14
15 // --- Spinlocks ---
16 static inline int IS_LOCKED(struct sShortSpinlock *Lock)
17 {
18         return !!Lock->Lock;
19 }
20
21 static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock)
22 {
23         // TODO: Handle multiple CPUs
24         return !!Lock->Lock;
25 }
26
27 static inline int SHORTLOCK(struct sShortSpinlock *Lock)
28 {
29         #if 1
30         // Coped from linux, yes, but I know what it does now :)
31         Uint    tmp;
32         __asm__ __volatile__ (
33         "1:     ldrex   %0, [%1]\n"     // Exclusive LOAD
34         "       teq     %0, #0\n"       // Check if zero
35         "       strexeq %0, %2, [%1]\n" // Set to one if it is zero (releasing lock on the memory)
36         "       teqeq   %0, #0\n"       // If the lock was avaliable, check if the write succeeded
37         "       bne     1b"     // If the lock was unavaliable, or the write failed, loop
38                 : "=&r" (tmp)   // Temp
39                 : "r" (&Lock->Lock), "r" (1)
40                 : "cc"  // Condition codes clobbered
41                 );
42         #else
43          int    v = 1;
44         while( v )
45                 __asm__ __volatile__ (
46                         "swp %0, [%1]"
47                         : "=r" (v) : "r" (&Lock->Lock)
48                         : "cc"
49                         );
50         #endif
51         return 1;
52 }
53
54 static inline void SHORTREL(struct sShortSpinlock *Lock)
55 {
56         Lock->Lock = 0;
57 }
58
59 #endif
60

UCC git Repository :: git.ucc.asn.au