]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/loose_ends.c
b0cd27fffdea95a0cd901f63905aa54f6ab5336c
[apple/xnu.git] / osfmk / i386 / loose_ends.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * @OSF_COPYRIGHT@
24 */
25 /*
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
28 * All Rights Reserved.
29 *
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
35 *
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39 *
40 * Carnegie Mellon requests users of this software to return to
41 *
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
46 *
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
49 */
50 /*
51 */
52 #include <mach_assert.h>
53
54 #include <string.h>
55 #include <mach/boolean.h>
56 #include <mach/i386/vm_types.h>
57 #include <mach/i386/vm_param.h>
58 #include <kern/kern_types.h>
59 #include <kern/misc_protos.h>
60 #include <i386/misc_protos.h>
61
62 /*
63 * Should be rewritten in asm anyway.
64 */
65
66
67 /*
68 * copy 'size' bytes from physical to physical address
69 * the caller must validate the physical ranges
70 *
71 * if flush_action == 0, no cache flush necessary
72 * if flush_action == 1, flush the source
73 * if flush_action == 2, flush the dest
74 * if flush_action == 3, flush both source and dest
75 */
76
77 kern_return_t copyp2p(vm_offset_t source, vm_offset_t dest, unsigned int size, unsigned int flush_action) {
78
79 switch(flush_action) {
80 case 1:
81 flush_dcache(source, size, 1);
82 break;
83 case 2:
84 flush_dcache(dest, size, 1);
85 break;
86 case 3:
87 flush_dcache(source, size, 1);
88 flush_dcache(dest, size, 1);
89 break;
90
91 }
92 bcopy_phys((char *)source, (char *)dest, size); /* Do a physical copy */
93
94 switch(flush_action) {
95 case 1:
96 flush_dcache(source, size, 1);
97 break;
98 case 2:
99 flush_dcache(dest, size, 1);
100 break;
101 case 3:
102 flush_dcache(source, size, 1);
103 flush_dcache(dest, size, 1);
104 break;
105
106 }
107 }
108
109
110
111 /*
112 * Copies data from a physical page to a virtual page. This is used to
113 * move data from the kernel to user state.
114 *
115 */
116
117 kern_return_t
118 copyp2v(char *from, char *to, unsigned int size) {
119
120 return(copyout(phystokv(from), to, size));
121 }
122
123 /*
124 * bcopy_phys - like bcopy but copies from/to physical addresses.
125 * this is trivial since all phys mem is mapped into
126 * kernel virtual space
127 */
128
129 void
130 bcopy_phys(const char *from, char *to, vm_size_t bytes)
131 {
132 bcopy((char *)phystokv(from), (char *)phystokv(to), bytes);
133 }
134
135
136 /*
137 * ovbcopy - like bcopy, but recognizes overlapping ranges and handles
138 * them correctly.
139 */
140
141 void
142 ovbcopy(
143 const char *from,
144 char *to,
145 vm_size_t bytes) /* num bytes to copy */
146 {
147 /* Assume that bcopy copies left-to-right (low addr first). */
148 if (from + bytes <= to || to + bytes <= from || to == from)
149 bcopy_no_overwrite(from, to, bytes); /* non-overlapping or no-op*/
150 else if (from > to)
151 bcopy_no_overwrite(from, to, bytes); /* overlapping but OK */
152 else {
153 /* to > from: overlapping, and must copy right-to-left. */
154 from += bytes - 1;
155 to += bytes - 1;
156 while (bytes-- > 0)
157 *to-- = *from--;
158 }
159 }
160
161 void
162 bcopy(
163 const char *from,
164 char *to,
165 vm_size_t bytes) /* num bytes to copy */
166 {
167 ovbcopy(from, to, bytes);
168 }
169
170 int bcmp(
171 const char *a,
172 const char *b,
173 vm_size_t len)
174 {
175 if (len == 0)
176 return 0;
177
178 do
179 if (*a++ != *b++)
180 break;
181 while (--len);
182
183 return len;
184 }
185
186 int
187 memcmp(s1, s2, n)
188 register char *s1, *s2;
189 register n;
190 {
191 while (--n >= 0)
192 if (*s1++ != *s2++)
193 return (*--s1 - *--s2);
194 return (0);
195 }
196
197 /*
198 * Abstract:
199 * strlen returns the number of characters in "string" preceeding
200 * the terminating null character.
201 */
202
203 size_t
204 strlen(
205 register const char *string)
206 {
207 register const char *ret = string;
208
209 while (*string++ != '\0')
210 continue;
211 return string - 1 - ret;
212 }
213
214 #include <libkern/OSAtomic.h>
215
216 uint32_t
217 hw_atomic_add(
218 uint32_t *dest,
219 uint32_t delt)
220 {
221 uint32_t oldValue;
222 uint32_t newValue;
223
224 do {
225 oldValue = *dest;
226 newValue = (oldValue + delt);
227 } while (!OSCompareAndSwap((UInt32)oldValue,
228 (UInt32)newValue, (UInt32 *)dest));
229
230 return newValue;
231 }
232
233 uint32_t
234 hw_atomic_sub(
235 uint32_t *dest,
236 uint32_t delt)
237 {
238 uint32_t oldValue;
239 uint32_t newValue;
240
241 do {
242 oldValue = *dest;
243 newValue = (oldValue - delt);
244 } while (!OSCompareAndSwap((UInt32)oldValue,
245 (UInt32)newValue, (UInt32 *)dest));
246
247 return newValue;
248 }
249
250 uint32_t
251 hw_atomic_or(
252 uint32_t *dest,
253 uint32_t mask)
254 {
255 uint32_t oldValue;
256 uint32_t newValue;
257
258 do {
259 oldValue = *dest;
260 newValue = (oldValue | mask);
261 } while (!OSCompareAndSwap((UInt32)oldValue,
262 (UInt32)newValue, (UInt32 *)dest));
263
264 return newValue;
265 }
266
267 uint32_t
268 hw_atomic_and(
269 uint32_t *dest,
270 uint32_t mask)
271 {
272 uint32_t oldValue;
273 uint32_t newValue;
274
275 do {
276 oldValue = *dest;
277 newValue = (oldValue & mask);
278 } while (!OSCompareAndSwap((UInt32)oldValue,
279 (UInt32)newValue, (UInt32 *)dest));
280
281 return newValue;
282 }
283
284 uint32_t
285 hw_compare_and_store(
286 uint32_t oldval,
287 uint32_t newval,
288 uint32_t *dest)
289 {
290 return OSCompareAndSwap((UInt32)oldval, (UInt32)newval, (UInt32 *)dest);
291 }
292
293 #if MACH_ASSERT
294
295 /*
296 * Machine-dependent routine to fill in an array with up to callstack_max
297 * levels of return pc information.
298 */
299 void machine_callstack(
300 natural_t *buf,
301 vm_size_t callstack_max)
302 {
303 }
304
305 #endif /* MACH_ASSERT */