]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/loose_ends.c
xnu-517.7.7.tar.gz
[apple/xnu.git] / osfmk / i386 / loose_ends.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
e5568f75
A
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.
1c79356b 11 *
e5568f75
A
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
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
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.
1c79356b
A
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>
0b4e3aa0 57#include <mach/i386/vm_param.h>
1c79356b
A
58#include <kern/kern_types.h>
59#include <kern/misc_protos.h>
55e303ae
A
60#include <vm/pmap.h>
61#include <i386/param.h>
1c79356b
A
62#include <i386/misc_protos.h>
63
55e303ae
A
64#define value_64bit(value) ((value) & 0xFFFFFFFF00000000LL)
65#define low32(x) ((unsigned int)((x) & 0x00000000FFFFFFFFLL))
66
1c79356b
A
67 /*
68 * Should be rewritten in asm anyway.
69 */
0b4e3aa0 70
9bccf70c 71
55e303ae
A
72void
73bzero_phys(addr64_t p, uint32_t len)
74{
75 bzero((char *)phystokv(low32(p)), len);
76}
77
b4c24cb9
A
78/*
79 * copy 'size' bytes from physical to physical address
80 * the caller must validate the physical ranges
81 *
82 * if flush_action == 0, no cache flush necessary
83 * if flush_action == 1, flush the source
84 * if flush_action == 2, flush the dest
85 * if flush_action == 3, flush both source and dest
86 */
87
55e303ae
A
88extern void flush_dcache(vm_offset_t addr, unsigned count, int phys);
89
b4c24cb9
A
90kern_return_t copyp2p(vm_offset_t source, vm_offset_t dest, unsigned int size, unsigned int flush_action) {
91
92 switch(flush_action) {
93 case 1:
94 flush_dcache(source, size, 1);
95 break;
96 case 2:
97 flush_dcache(dest, size, 1);
98 break;
99 case 3:
100 flush_dcache(source, size, 1);
101 flush_dcache(dest, size, 1);
102 break;
103
104 }
55e303ae 105 bcopy_phys((addr64_t)source, (addr64_t)dest, (vm_size_t)size); /* Do a physical copy */
b4c24cb9
A
106
107 switch(flush_action) {
108 case 1:
109 flush_dcache(source, size, 1);
110 break;
111 case 2:
112 flush_dcache(dest, size, 1);
113 break;
114 case 3:
115 flush_dcache(source, size, 1);
116 flush_dcache(dest, size, 1);
117 break;
118
119 }
55e303ae 120 return KERN_SUCCESS;
b4c24cb9
A
121}
122
123
9bccf70c
A
124
125/*
126 * Copies data from a physical page to a virtual page. This is used to
127 * move data from the kernel to user state.
128 *
129 */
55e303ae 130#if 0
9bccf70c
A
131kern_return_t
132copyp2v(char *from, char *to, unsigned int size) {
133
134 return(copyout(phystokv(from), to, size));
135}
55e303ae
A
136#endif
137
138/*
139 * Copies data from a virtual page to a physical page. This is used to
140 * move data from the user address space into the kernel.
141 *
142 */
143#if 0
144kern_return_t
145copyv2p(char *from, char *to, unsigned int size) {
146
147 return(copyin(from, phystokv(to), size));
148}
149#endif
9bccf70c 150
0b4e3aa0
A
151/*
152 * bcopy_phys - like bcopy but copies from/to physical addresses.
153 * this is trivial since all phys mem is mapped into
154 * kernel virtual space
155 */
156
157void
55e303ae 158bcopy_phys(addr64_t from, addr64_t to, vm_size_t bytes)
0b4e3aa0 159{
55e303ae
A
160 /* this will die horribly if we ever run off the end of a page */
161 if ( value_64bit(from) || value_64bit(to)) panic("bcopy_phys: 64 bit value");
162 bcopy((char *)phystokv(low32(from)),
163 (char *)phystokv(low32(to)), bytes);
0b4e3aa0
A
164}
165
166
1c79356b
A
167/*
168 * ovbcopy - like bcopy, but recognizes overlapping ranges and handles
169 * them correctly.
170 */
171
172void
173ovbcopy(
174 const char *from,
175 char *to,
176 vm_size_t bytes) /* num bytes to copy */
177{
178 /* Assume that bcopy copies left-to-right (low addr first). */
179 if (from + bytes <= to || to + bytes <= from || to == from)
180 bcopy_no_overwrite(from, to, bytes); /* non-overlapping or no-op*/
181 else if (from > to)
182 bcopy_no_overwrite(from, to, bytes); /* overlapping but OK */
183 else {
184 /* to > from: overlapping, and must copy right-to-left. */
185 from += bytes - 1;
186 to += bytes - 1;
187 while (bytes-- > 0)
188 *to-- = *from--;
189 }
190}
191
192void
193bcopy(
194 const char *from,
195 char *to,
196 vm_size_t bytes) /* num bytes to copy */
197{
198 ovbcopy(from, to, bytes);
199}
200
201int bcmp(
202 const char *a,
203 const char *b,
204 vm_size_t len)
205{
206 if (len == 0)
207 return 0;
208
209 do
210 if (*a++ != *b++)
211 break;
212 while (--len);
213
214 return len;
215}
216
0b4e3aa0
A
217int
218memcmp(s1, s2, n)
219 register char *s1, *s2;
220 register n;
221{
222 while (--n >= 0)
223 if (*s1++ != *s2++)
224 return (*--s1 - *--s2);
225 return (0);
226}
227
228/*
229 * Abstract:
230 * strlen returns the number of characters in "string" preceeding
231 * the terminating null character.
232 */
233
234size_t
235strlen(
236 register const char *string)
237{
238 register const char *ret = string;
239
240 while (*string++ != '\0')
241 continue;
242 return string - 1 - ret;
243}
244
9bccf70c
A
245#include <libkern/OSAtomic.h>
246
247uint32_t
248hw_atomic_add(
249 uint32_t *dest,
250 uint32_t delt)
251{
252 uint32_t oldValue;
253 uint32_t newValue;
254
255 do {
256 oldValue = *dest;
257 newValue = (oldValue + delt);
258 } while (!OSCompareAndSwap((UInt32)oldValue,
259 (UInt32)newValue, (UInt32 *)dest));
260
261 return newValue;
262}
263
264uint32_t
265hw_atomic_sub(
266 uint32_t *dest,
267 uint32_t delt)
268{
269 uint32_t oldValue;
270 uint32_t newValue;
271
272 do {
273 oldValue = *dest;
274 newValue = (oldValue - delt);
275 } while (!OSCompareAndSwap((UInt32)oldValue,
276 (UInt32)newValue, (UInt32 *)dest));
277
278 return newValue;
279}
280
281uint32_t
282hw_atomic_or(
283 uint32_t *dest,
284 uint32_t mask)
285{
286 uint32_t oldValue;
287 uint32_t newValue;
288
289 do {
290 oldValue = *dest;
291 newValue = (oldValue | mask);
292 } while (!OSCompareAndSwap((UInt32)oldValue,
293 (UInt32)newValue, (UInt32 *)dest));
294
295 return newValue;
296}
297
298uint32_t
299hw_atomic_and(
300 uint32_t *dest,
301 uint32_t mask)
302{
303 uint32_t oldValue;
304 uint32_t newValue;
305
306 do {
307 oldValue = *dest;
308 newValue = (oldValue & mask);
309 } while (!OSCompareAndSwap((UInt32)oldValue,
310 (UInt32)newValue, (UInt32 *)dest));
311
312 return newValue;
313}
314
315uint32_t
316hw_compare_and_store(
317 uint32_t oldval,
318 uint32_t newval,
319 uint32_t *dest)
320{
321 return OSCompareAndSwap((UInt32)oldval, (UInt32)newval, (UInt32 *)dest);
322}
323
1c79356b
A
324#if MACH_ASSERT
325
326/*
327 * Machine-dependent routine to fill in an array with up to callstack_max
328 * levels of return pc information.
329 */
330void machine_callstack(
331 natural_t *buf,
332 vm_size_t callstack_max)
333{
334}
335
336#endif /* MACH_ASSERT */
55e303ae
A
337
338
339
340
341void fillPage(ppnum_t pa, unsigned int fill)
342{
343 unsigned int *addr = (unsigned int *)phystokv(i386_ptob(pa));
344 int i;
345 int cnt = NBPG/sizeof(unsigned int);
346
347 for (i = 0; i < cnt ; i++ )
348 *addr++ = fill;
349}
350
351#define cppvPHYS (cppvPsnk|cppvPsrc)
352
353kern_return_t copypv(addr64_t source, addr64_t sink, unsigned int size, int which)
354{
355 char *src32, *dst32;
356
357 if (value_64bit(source) | value_64bit(sink)) panic("copypv: 64 bit value");
358
359 src32 = (char *)low32(source);
360 dst32 = (char *)low32(sink);
361
362 if (which & cppvFsrc) flush_dcache(source, size, 1); /* If requested, flush source before move */
363 if (which & cppvFsnk) flush_dcache(sink, size, 1); /* If requested, flush sink before move */
364
365 switch (which & cppvPHYS) {
366
367 case cppvPHYS:
368 /*
369 * both destination and source are physical
370 */
371 bcopy_phys(source, sink, (vm_size_t)size);
372 break;
373
374 case cppvPsnk:
375 /*
376 * destination is physical, source is virtual
377 */
378 if (which & cppvKmap)
379 /*
380 * source is kernel virtual
381 */
382 bcopy(src32, (char *)phystokv(dst32), size);
383 else
384 /*
385 * source is user virtual
386 */
387 copyin(src32, (char *)phystokv(dst32), size);
388 break;
389
390 case cppvPsrc:
391 /*
392 * source is physical, destination is virtual
393 */
394 if (which & cppvKmap)
395 /*
396 * destination is kernel virtual
397 */
398 bcopy((char *)phystokv(src32), dst32, size);
399 else
400 /*
401 * destination is user virtual
402 */
403 copyout((char *)phystokv(src32), dst32, size);
404 break;
405
406 default:
407 panic("copypv: both virtual");
408 }
409
410 if (which & cppvFsrc) flush_dcache(source, size, 1); /* If requested, flush source before move */
411 if (which & cppvFsnk) flush_dcache(sink, size, 1); /* If requested, flush sink before move */
412
413 return KERN_SUCCESS;
414}
415
416
417void flush_dcache64(addr64_t addr, unsigned count, int phys)
418{
419}
420
421void invalidate_icache64(addr64_t addr, unsigned cnt, int phys)
422{
423}
424
425
426void switch_to_serial_console(void)
427{
428}
429
430addr64_t vm_last_addr;
431
432void
433mapping_set_mod(ppnum_t pn)
434{
435 pmap_set_modify(pn);
436}
437
438boolean_t
439mutex_preblock(
440 mutex_t *mutex,
441 thread_t thread)
442{
443 return (FALSE);
444}