]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/spin_lock-arm.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / spin_lock-arm.cpp
1 //---------------------------------------------------------------------------
2 INTERFACE [arm && mp]:
3
4 EXTENSION class Spin_lock
5 {
6 public:
7   enum { Arch_lock = 2 };
8 };
9 //---------------------------------------------------------------------------
10 IMPLEMENTATION [arm && mp]:
11
12 #include "processor.h"
13
14 PRIVATE template<typename Lock_t> inline NEEDS["processor.h"]
15 void
16 Spin_lock<Lock_t>::lock_arch()
17 {
18   Lock_t dummy, tmp;
19
20 #define L(z) \
21   __asm__ __volatile__ ( \
22       "1: ldr" #z "     %[d], [%[lock]]           \n" \
23       "   tst     %[d], #2                  \n" /* Arch_lock == #2 */ \
24       "   wfene                             \n" \
25       "   bne     1b                        \n" \
26       "   ldrex"#z"   %[d], [%[lock]]           \n" \
27       "   tst     %[d], #2                  \n" \
28       "   orr     %[tmp], %[d], #2          \n" \
29       "   strex"#z"eq %[d], %[tmp], [%[lock]]   \n" \
30       "   teqeq   %[d], #0                  \n" \
31       "   bne     1b                        \n" \
32       : [d] "=&r" (dummy), [tmp] "=&r"(tmp), "+m" (_lock) \
33       : [lock] "r" (&_lock) \
34       : "cc" \
35       )
36   if (sizeof(Lock_t) == sizeof(char))
37     L(b);
38   else if (sizeof(Lock_t) == sizeof(short))
39     L(h);
40   else
41     L();
42
43 #undef L
44 }
45
46 PRIVATE template<typename Lock_t> inline
47 void
48 Spin_lock<Lock_t>::unlock_arch()
49 {
50   Lock_t tmp;
51 #define UNL(z) \
52   __asm__ __volatile__( \
53       "ldr"#z " %[tmp], %[lock]             \n" \
54       "bic %[tmp], %[tmp], #2          \n" /* Arch_lock == #2 */ \
55       "str"#z " %[tmp], %[lock]             \n" \
56       "mcr p15, 0, %[tmp], c7, c10, 4  \n" /* drain write buffer */ \
57       "sev                             \n" \
58       : [lock] "=m" (_lock), [tmp] "=&r" (tmp))
59   if (sizeof(Lock_t) == sizeof(char))
60     UNL(b);
61   else if (sizeof(Lock_t) == sizeof(short))
62     UNL(h);
63   else
64     UNL();
65 #undef UNL
66 }