xref: /haiku/src/system/kernel/arch/m68k/arch_atomic.cpp (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
1 /*
2  * Copyright 2007, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  * 		François Revol <revol@free.fr>
7  *
8  * Copyright 2003, Marcus Overhagen. All rights reserved.
9  * Distributed under the terms of the OpenBeOS License.
10  */
11 
12 #include <KernelExport.h>
13 
14 #include <kernel.h>
15 #include <user_atomic.h>
16 
17 /*
18  * Emulation of 64 bit atomic functions.
19  * Slow, using spinlocks...
20  */
21 
22 #warning M68K: detect 060 here
23 #if 0
24 
25 static spinlock atomic_lock = 0;
26 
27 int64
28 atomic_set64(vint64 *value, int64 newValue)
29 {
30 	cpu_status status;
31 	int64 oldValue;
32 	status = disable_interrupts();
33 	acquire_spinlock(&atomic_lock);
34 	oldValue = *value;
35 	*value = newValue;
36 	release_spinlock(&atomic_lock);
37 	restore_interrupts(status);
38 	return oldValue;
39 }
40 
41 int64
42 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
43 {
44 	cpu_status status;
45 	int64 oldValue;
46 	status = disable_interrupts();
47 	acquire_spinlock(&atomic_lock);
48 	oldValue = *value;
49 	if (oldValue == testAgainst)
50 		*value = newValue;
51 	release_spinlock(&atomic_lock);
52 	restore_interrupts(status);
53 	return oldValue;
54 }
55 
56 int64
57 atomic_add64(vint64 *value, int64 addValue)
58 {
59 	cpu_status status;
60 	int64 oldValue;
61 	status = disable_interrupts();
62 	acquire_spinlock(&atomic_lock);
63 	oldValue = *value;
64 	*value += addValue;
65 	release_spinlock(&atomic_lock);
66 	restore_interrupts(status);
67 	return oldValue;
68 }
69 
70 int64
71 atomic_and64(vint64 *value, int64 andValue)
72 {
73 	cpu_status status;
74 	int64 oldValue;
75 	status = disable_interrupts();
76 	acquire_spinlock(&atomic_lock);
77 	oldValue = *value;
78 	*value &= andValue;
79 	release_spinlock(&atomic_lock);
80 	restore_interrupts(status);
81 	return oldValue;
82 }
83 
84 int64
85 atomic_or64(vint64 *value, int64 orValue)
86 {
87 	cpu_status status;
88 	int64 oldValue;
89 	status = disable_interrupts();
90 	acquire_spinlock(&atomic_lock);
91 	oldValue = *value;
92 	*value |= orValue;
93 	release_spinlock(&atomic_lock);
94 	restore_interrupts(status);
95 	return oldValue;
96 }
97 
98 int64
99 atomic_get64(vint64 *value)
100 {
101 	cpu_status status;
102 	int64 oldValue;
103 	status = disable_interrupts();
104 	acquire_spinlock(&atomic_lock);
105 	oldValue = *value;
106 	release_spinlock(&atomic_lock);
107 	restore_interrupts(status);
108 	return oldValue;
109 }
110 
111 int64
112 _user_atomic_set64(vint64 *value, int64 newValue)
113 {
114 	cpu_status status;
115 	int64 oldValue;
116 	if (!IS_USER_ADDRESS(value)
117 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
118 		goto access_violation;
119 
120 	status = disable_interrupts();
121 	acquire_spinlock(&atomic_lock);
122 	oldValue = *value;
123 	*value = newValue;
124 	release_spinlock(&atomic_lock);
125 	restore_interrupts(status);
126 	unlock_memory((void *)value, 8, B_READ_DEVICE);
127 	return oldValue;
128 
129 access_violation:
130 	// XXX kill application
131 	return -1;
132 }
133 
134 int64
135 _user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
136 {
137 	cpu_status status;
138 	int64 oldValue;
139 	if (!IS_USER_ADDRESS(value)
140 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
141 		goto access_violation;
142 
143 	status = disable_interrupts();
144 	acquire_spinlock(&atomic_lock);
145 	oldValue = *value;
146 	if (oldValue == testAgainst)
147 		*value = newValue;
148 	release_spinlock(&atomic_lock);
149 	restore_interrupts(status);
150 	unlock_memory((void *)value, 8, B_READ_DEVICE);
151 	return oldValue;
152 
153 access_violation:
154 	// XXX kill application
155 	return -1;
156 }
157 
158 int64
159 _user_atomic_add64(vint64 *value, int64 addValue)
160 {
161 	cpu_status status;
162 	int64 oldValue;
163 	if (!IS_USER_ADDRESS(value)
164 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
165 		goto access_violation;
166 
167 	status = disable_interrupts();
168 	acquire_spinlock(&atomic_lock);
169 	oldValue = *value;
170 	*value += addValue;
171 	release_spinlock(&atomic_lock);
172 	restore_interrupts(status);
173 	unlock_memory((void *)value, 8, B_READ_DEVICE);
174 	return oldValue;
175 
176 access_violation:
177 	// XXX kill application
178 	return -1;
179 }
180 
181 int64
182 _user_atomic_and64(vint64 *value, int64 andValue)
183 {
184 	cpu_status status;
185 	int64 oldValue;
186 	if (!IS_USER_ADDRESS(value)
187 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
188 		goto access_violation;
189 
190 	status = disable_interrupts();
191 	acquire_spinlock(&atomic_lock);
192 	oldValue = *value;
193 	*value &= andValue;
194 	release_spinlock(&atomic_lock);
195 	restore_interrupts(status);
196 	unlock_memory((void *)value, 8, B_READ_DEVICE);
197 	return oldValue;
198 
199 access_violation:
200 	// XXX kill application
201 	return -1;
202 }
203 
204 int64
205 _user_atomic_or64(vint64 *value, int64 orValue)
206 {
207 	cpu_status status;
208 	int64 oldValue;
209 	if (!IS_USER_ADDRESS(value)
210 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
211 		goto access_violation;
212 
213 	status = disable_interrupts();
214 	acquire_spinlock(&atomic_lock);
215 	oldValue = *value;
216 	*value |= orValue;
217 	release_spinlock(&atomic_lock);
218 	restore_interrupts(status);
219 	unlock_memory((void *)value, 8, B_READ_DEVICE);
220 	return oldValue;
221 access_violation:
222 	// XXX kill application
223 	return -1;
224 }
225 
226 int64
227 _user_atomic_get64(vint64 *value)
228 {
229 	cpu_status status;
230 	int64 oldValue;
231 	if (!IS_USER_ADDRESS(value)
232 		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
233 		goto access_violation;
234 
235 	status = disable_interrupts();
236 	acquire_spinlock(&atomic_lock);
237 	oldValue = *value;
238 	release_spinlock(&atomic_lock);
239 	restore_interrupts(status);
240 	unlock_memory((void *)value, 8, B_READ_DEVICE);
241 	return oldValue;
242 
243 access_violation:
244 	// XXX kill application
245 	return -1;
246 }
247 #endif
248