MP Implementation 1/2: Get the APIC code working again, sweetly integrate the
[dragonfly.git] / sys / i386 / include / lock.h
CommitLineData
984263bc 1/*
8a8d5d85 2 * Copyright (c) 2003, Matthew Dillon, All rights reserved.
984263bc
MD
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. The name of the developer may NOT be used to endorse or promote products
10 * derived from this software without specific prior written permission.
11 *
12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22 * SUCH DAMAGE.
23 *
24 * $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $
8a8d5d85 25 * $DragonFly: src/sys/i386/include/Attic/lock.h,v 1.3 2003/07/06 21:23:49 dillon Exp $
984263bc
MD
26 */
27
984263bc
MD
28#ifndef _MACHINE_LOCK_H_
29#define _MACHINE_LOCK_H_
30
8a8d5d85
MD
31#ifndef _MACHINE_PSL_H_
32#include <machine/psl.h>
33#endif
984263bc 34
8a8d5d85
MD
35/*
36 * MP_FREE_LOCK is used by both assembly and C under SMP.
37 */
984263bc 38#ifdef SMP
8a8d5d85
MD
39#define MP_FREE_LOCK 0xffffffff /* value of lock when free */
40#endif
984263bc 41
8a8d5d85 42#ifdef LOCORE
984263bc
MD
43
44/*
8a8d5d85
MD
45 * Spinlock assembly support. Note: eax and ecx can be tromped. No
46 * other register will be. Note that these routines are sometimes
47 * called with (%edx) as the mem argument.
48 *
49 * Under UP the spinlock routines still serve to disable/restore
50 * interrupts.
984263bc
MD
51 */
52
984263bc 53
8a8d5d85 54#ifdef SMP
984263bc 55
8a8d5d85
MD
56#define SPIN_INIT(mem) \
57 movl $0,mem ; \
58
59#define SPIN_INIT_NOREG(mem) \
60 SPIN_INIT(mem) ; \
61
62#define SPIN_LOCK(mem) \
63 pushfl ; \
64 popl %ecx ; /* flags */ \
65 cli ; \
66 orl $PSL_C,%ecx ; /* make sure non-zero */ \
677: ; \
68 movl $0,%eax ; /* expected contents of lock */ \
69 cmpxchgl %ecx,mem ; /* Z=1 (jz) on success */ \
70 jz 8f ; \
71 jmp 7b ; \
728: ; \
73
74#define SPIN_LOCK_PUSH_REGS \
75 subl $8,%esp ; \
76 movl %ecx,(%esp) ; \
77 movl %eax,4(%esp) ; \
78
79#define SPIN_LOCK_POP_REGS \
80 movl (%esp),%ecx ; \
81 movl 4(%esp),%eax ; \
82 addl $8,%esp ; \
83
84#define SPIN_LOCK_FRAME_SIZE 8
85
86#define SPIN_LOCK_NOREG(mem) \
87 SPIN_LOCK_PUSH_REGS ; \
88 SPIN_LOCK(mem) ; \
89 SPIN_LOCK_POP_REGS ; \
90
91#define SPIN_UNLOCK(mem) \
92 pushl mem ; \
93 movl $0,mem ; \
94 popfl ; \
95
96#define SPIN_UNLOCK_PUSH_REGS
97#define SPIN_UNLOCK_POP_REGS
98#define SPIN_UNLOCK_FRAME_SIZE 0
99
100#define SPIN_UNLOCK_NOREG(mem) \
101 SPIN_UNLOCK(mem) ; \
984263bc 102
8a8d5d85 103#else
984263bc 104
8a8d5d85
MD
105#define SPIN_LOCK(mem) \
106 pushfl ; \
107 cli ; \
108 orl $PSL_C,(%esp) ; \
109 popl mem ; \
984263bc 110
8a8d5d85
MD
111#define SPIN_LOCK_PUSH_RESG
112#define SPIN_LOCK_POP_REGS
113#define SPIN_LOCK_FRAME_SIZE 0
984263bc 114
8a8d5d85
MD
115#define SPIN_UNLOCK(mem) \
116 pushl mem ; \
117 movl $0,mem ; \
118 popfl ; \
984263bc 119
8a8d5d85
MD
120#define SPIN_UNLOCK_PUSH_REGS
121#define SPIN_UNLOCK_POP_REGS
122#define SPIN_UNLOCK_FRAME_SIZE 0
984263bc 123
8a8d5d85 124#endif /* SMP */
984263bc 125
8a8d5d85 126#else /* LOCORE */
984263bc 127
8a8d5d85
MD
128/*
129 * Spinlock functions (UP and SMP). Under UP a spinlock still serves
130 * to disable/restore interrupts even if it doesn't spin.
131 */
132struct spinlock {
133 volatile int opaque;
134};
984263bc 135
8a8d5d85
MD
136typedef struct spinlock *spinlock_t;
137
138void mpintr_lock(void); /* disables int / spinlock combo */
139void mpintr_unlock(void);
140void com_lock(void); /* disables int / spinlock combo */
141void com_unlock(void);
142void imen_lock(void); /* disables int / spinlock combo */
143void imen_unlock(void);
144void clock_lock(void); /* disables int / spinlock combo */
145void clock_unlock(void);
146void cons_lock(void); /* disables int / spinlock combo */
147void cons_unlock(void);
148
149extern struct spinlock smp_rv_spinlock;
150
151void spin_lock(spinlock_t lock);
152void spin_lock_np(spinlock_t lock);
153void spin_unlock(spinlock_t lock);
154void spin_unlock_np(spinlock_t lock);
155#if 0
156void spin_lock_init(spinlock_t lock);
157#endif
984263bc
MD
158
159/*
8a8d5d85
MD
160 * Inline version of spinlock routines -- overrides assembly. Only unlock
161 * and init here please.
984263bc 162 */
8a8d5d85
MD
163static __inline void
164spin_lock_init(spinlock_t lock)
165{
166 lock->opaque = 0;
167}
984263bc
MD
168
169/*
8a8d5d85
MD
170 * MP LOCK functions for SMP and UP. Under UP the MP lock does not exist
171 * but we leave a few functions intact as macros for convenience.
984263bc 172 */
8a8d5d85 173#ifdef SMP
984263bc 174
8a8d5d85
MD
175void get_mplock(void);
176int try_mplock(void);
177void rel_mplock(void);
178int cpu_try_mplock(void);
179#if 0
180void cpu_rel_mplock(void);
181#endif
182void cpu_get_initial_mplock(void);
984263bc 183
8a8d5d85 184extern u_int mp_lock;
984263bc 185
8a8d5d85
MD
186#define MP_LOCK_HELD() (mp_lock == mycpu->gd_cpuid)
187#define ASSERT_MP_LOCK_HELD() KKASSERT(MP_LOCK_HELD())
984263bc 188
984263bc 189static __inline void
8a8d5d85 190cpu_rel_mplock(void)
984263bc 191{
8a8d5d85 192 mp_lock = MP_FREE_LOCK;
984263bc
MD
193}
194
8a8d5d85 195#else
984263bc 196
8a8d5d85
MD
197#define get_mplock()
198#define try_mplock() 1
199#define rel_mplock()
200#define ASSERT_MP_LOCK_HELD()
984263bc 201
8a8d5d85
MD
202#endif /* SMP */
203#endif /* LOCORE */
204#endif /* !_MACHINE_LOCK_H_ */