xref: /netbsd-src/sys/arch/vax/include/lock.h (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: lock.h,v 1.12 2003/06/23 11:01:49 martin Exp $	*/
2 
3 /*
4  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *     This product includes software developed at Ludd, University of Lule}.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef _VAX_LOCK_H_
34 #define _VAX_LOCK_H_
35 
36 #ifdef _KERNEL
37 #include "opt_multiprocessor.h"
38 #include <machine/cpu.h>
39 #endif
40 
41 typedef __volatile int		__cpu_simple_lock_t;
42 
43 #define __SIMPLELOCK_LOCKED	1
44 #define __SIMPLELOCK_UNLOCKED	0
45 
46 static __inline void
47 __cpu_simple_lock_init(__cpu_simple_lock_t *alp)
48 {
49 #ifdef _KERNEL
50 	__asm__ __volatile ("movl %0,%%r1;jsb Sunlock"
51 		: /* No output */
52 		: "g"(alp)
53 		: "r1","cc","memory");
54 #else
55 	__asm__ __volatile ("bbcci $0,%0,1f;1:"
56 		: /* No output */
57 		: "m"(*alp)
58 		: "cc");
59 #endif
60 }
61 
62 static __inline int
63 __cpu_simple_lock_try(__cpu_simple_lock_t *alp)
64 {
65 	int ret;
66 
67 #ifdef _KERNEL
68 	__asm__ __volatile ("movl %1,%%r1;jsb Slocktry;movl %%r0,%0"
69 		: "=&r"(ret)
70 		: "g"(alp)
71 		: "r0","r1","cc","memory");
72 #else
73 	__asm__ __volatile ("clrl %0;bbssi $0,%1,1f;incl %0;1:"
74 		: "=&r"(ret)
75 		: "m"(*alp)
76 		: "cc");
77 #endif
78 
79 	return ret;
80 }
81 
82 #ifdef _KERNEL
83 #define	VAX_LOCK_CHECKS ((1 << IPI_SEND_CNCHAR) | (1 << IPI_DDB))
84 #define	__cpu_simple_lock(alp)						\
85 do {									\
86 	struct cpu_info *__ci = curcpu();				\
87 									\
88 	while (__cpu_simple_lock_try(alp) == 0) {			\
89 		int __s;						\
90 									\
91 		if (__ci->ci_ipimsgs & VAX_LOCK_CHECKS) {		\
92 			__s = splipi();					\
93 			cpu_handle_ipi();				\
94 			splx(__s);					\
95 		}							\
96 	}								\
97 } while (0)
98 #else
99 static __inline void
100 __cpu_simple_lock(__cpu_simple_lock_t *alp)
101 {
102 	__asm__ __volatile ("1:bbssi $0,%0,1b"
103 		: /* No outputs */
104 		: "m"(*alp)
105 		: "cc");
106 }
107 #endif /* _KERNEL */
108 
109 #if 0
110 static __inline void
111 __cpu_simple_lock(__cpu_simple_lock_t *alp)
112 {
113 	struct cpu_info *ci = curcpu();
114 
115 	while (__cpu_simple_lock_try(alp) == 0) {
116 		int s;
117 
118 		if (ci->ci_ipimsgs & IPI_SEND_CNCHAR) {
119 			s = splipi();
120 			cpu_handle_ipi();
121 			splx(s);
122 		}
123 	}
124 
125 #if 0
126 	__asm__ __volatile ("movl %0,%%r1;jsb Slock"
127 		: /* No output */
128 		: "g"(alp)
129 		: "r0","r1","cc","memory");
130 #endif
131 #if 0
132 	__asm__ __volatile ("1:;bbssi $0, %0, 1b"
133 		: /* No output */
134 		: "m"(*alp));
135 #endif
136 }
137 #endif
138 
139 static __inline void
140 __cpu_simple_unlock(__cpu_simple_lock_t *alp)
141 {
142 #ifdef _KERNEL
143 	__asm__ __volatile ("movl %0,%%r1;jsb Sunlock"
144 		: /* No output */
145 		: "g"(alp)
146 		: "r1","cc","memory");
147 #else
148 	__asm__ __volatile ("bbcci $0,%0,1f;1:"
149 		: /* No output */
150 		: "m"(*alp)
151 		: "cc");
152 #endif
153 }
154 
155 #if defined(MULTIPROCESSOR)
156 /*
157  * On the Vax, interprocessor interrupts can come in at device priority
158  * level or lower. This can cause some problems while waiting for r/w
159  * spinlocks from a high'ish priority level: IPIs that come in will not
160  * be processed. This can lead to deadlock.
161  *
162  * This hook allows IPIs to be processed while a spinlock's interlock
163  * is released.
164  */
165 #define SPINLOCK_SPIN_HOOK						\
166 do {									\
167 	struct cpu_info *__ci = curcpu();				\
168 	int __s;							\
169 									\
170 	if (__ci->ci_ipimsgs != 0) {					\
171 		/* printf("CPU %lu has IPIs pending\n",			\
172 		    __ci->ci_cpuid); */					\
173 		__s = splipi();						\
174 		cpu_handle_ipi();					\
175 		splx(__s);						\
176 	}								\
177 } while (0)
178 #endif /* MULTIPROCESSOR */
179 #endif /* _VAX_LOCK_H_ */
180