OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-ppc/] [spinlock.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
#ifndef __ASM_SPINLOCK_H
2
#define __ASM_SPINLOCK_H
3
 
4
#include <asm/system.h>
5
#include <asm/processor.h>
6
 
7
#if defined(CONFIG_DEBUG_SPINLOCK)
8
#define SPINLOCK_DEBUG 1
9
#else
10
#define SPINLOCK_DEBUG 0
11
#endif
12
 
13
/*
14
 * Simple spin lock operations.
15
 */
16
 
17
typedef struct {
18
        volatile unsigned long lock;
19
#if SPINLOCK_DEBUG
20
        volatile unsigned long owner_pc;
21
        volatile unsigned long owner_cpu;
22
#endif
23
} spinlock_t;
24
 
25
#ifdef __KERNEL__
26
#if SPINLOCK_DEBUG
27
#define SPINLOCK_DEBUG_INIT     , 0, 0
28
#else
29
#define SPINLOCK_DEBUG_INIT     /* */
30
#endif
31
 
32
#define SPIN_LOCK_UNLOCKED      (spinlock_t) { 0 SPINLOCK_DEBUG_INIT }
33
 
34
#define spin_lock_init(x)       do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
35
#define spin_is_locked(x)       ((x)->lock != 0)
36
#define spin_unlock_wait(x)     do { barrier(); } while(spin_is_locked(x))
37
 
38
#if SPINLOCK_DEBUG
39
 
40
extern void _spin_lock(spinlock_t *lock);
41
extern void _spin_unlock(spinlock_t *lock);
42
extern int spin_trylock(spinlock_t *lock);
43
extern unsigned long __spin_trylock(volatile unsigned long *lock);
44
 
45
#define spin_lock(lp)                   _spin_lock(lp)
46
#define spin_unlock(lp)                 _spin_unlock(lp)
47
 
48
#else /* ! SPINLOCK_DEBUG */
49
 
50
static inline void spin_lock(spinlock_t *lock)
51
{
52
        unsigned long tmp;
53
 
54
        __asm__ __volatile__(
55
        "b      1f              # spin_lock\n\
56
2:      lwzx    %0,0,%1\n\
57
        cmpwi   0,%0,0\n\
58
        bne+    2b\n\
59
1:      lwarx   %0,0,%1\n\
60
        cmpwi   0,%0,0\n\
61
        bne-    2b\n"
62
        PPC405_ERR77(0,%1)
63
"       stwcx.  %2,0,%1\n\
64
        bne-    2b\n\
65
        isync"
66
        : "=&r"(tmp)
67
        : "r"(&lock->lock), "r"(1)
68
        : "cr0", "memory");
69
}
70
 
71
static inline void spin_unlock(spinlock_t *lock)
72
{
73
        __asm__ __volatile__("eieio             # spin_unlock": : :"memory");
74
        lock->lock = 0;
75
}
76
 
77
#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
78
 
79
#endif
80
 
81
/*
82
 * Read-write spinlocks, allowing multiple readers
83
 * but only one writer.
84
 *
85
 * NOTE! it is quite common to have readers in interrupts
86
 * but no interrupt writers. For those circumstances we
87
 * can "mix" irq-safe locks - any writer needs to get a
88
 * irq-safe write-lock, but readers can get non-irqsafe
89
 * read-locks.
90
 */
91
typedef struct {
92
        volatile unsigned long lock;
93
#if SPINLOCK_DEBUG
94
        volatile unsigned long owner_pc;
95
#endif
96
} rwlock_t;
97
 
98
#if SPINLOCK_DEBUG
99
#define RWLOCK_DEBUG_INIT     , 0
100
#else
101
#define RWLOCK_DEBUG_INIT     /* */
102
#endif
103
 
104
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
105
#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
106
 
107
#if SPINLOCK_DEBUG
108
 
109
extern void _read_lock(rwlock_t *rw);
110
extern void _read_unlock(rwlock_t *rw);
111
extern void _write_lock(rwlock_t *rw);
112
extern void _write_unlock(rwlock_t *rw);
113
 
114
#define read_lock(rw)           _read_lock(rw)
115
#define write_lock(rw)          _write_lock(rw)
116
#define write_unlock(rw)        _write_unlock(rw)
117
#define read_unlock(rw)         _read_unlock(rw)
118
 
119
#else /* ! SPINLOCK_DEBUG */
120
 
121
static __inline__ void read_lock(rwlock_t *rw)
122
{
123
        unsigned int tmp;
124
 
125
        __asm__ __volatile__(
126
        "b      2f              # read_lock\n\
127
1:      lwzx    %0,0,%1\n\
128
        cmpwi   0,%0,0\n\
129
        blt+    1b\n\
130
2:      lwarx   %0,0,%1\n\
131
        addic.  %0,%0,1\n\
132
        ble-    1b\n"
133
        PPC405_ERR77(0,%1)
134
"       stwcx.  %0,0,%1\n\
135
        bne-    2b\n\
136
        isync"
137
        : "=&r"(tmp)
138
        : "r"(&rw->lock)
139
        : "cr0", "memory");
140
}
141
 
142
static __inline__ void read_unlock(rwlock_t *rw)
143
{
144
        unsigned int tmp;
145
 
146
        __asm__ __volatile__(
147
        "eieio                  # read_unlock\n\
148
1:      lwarx   %0,0,%1\n\
149
        addic   %0,%0,-1\n"
150
        PPC405_ERR77(0,%1)
151
"       stwcx.  %0,0,%1\n\
152
        bne-    1b"
153
        : "=&r"(tmp)
154
        : "r"(&rw->lock)
155
        : "cr0", "memory");
156
}
157
 
158
static __inline__ void write_lock(rwlock_t *rw)
159
{
160
        unsigned int tmp;
161
 
162
        __asm__ __volatile__(
163
        "b      2f              # write_lock\n\
164
1:      lwzx    %0,0,%1\n\
165
        cmpwi   0,%0,0\n\
166
        bne+    1b\n\
167
2:      lwarx   %0,0,%1\n\
168
        cmpwi   0,%0,0\n\
169
        bne-    1b\n"
170
        PPC405_ERR77(0,%1)
171
"       stwcx.  %2,0,%1\n\
172
        bne-    2b\n\
173
        isync"
174
        : "=&r"(tmp)
175
        : "r"(&rw->lock), "r"(-1)
176
        : "cr0", "memory");
177
}
178
 
179
static __inline__ void write_unlock(rwlock_t *rw)
180
{
181
        __asm__ __volatile__("eieio             # write_unlock": : :"memory");
182
        rw->lock = 0;
183
}
184
 
185
#endif
186
 
187
#endif /* __ASM_SPINLOCK_H */
188
#endif /* __KERNEL__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.