]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/loose_ends.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
28 * All Rights Reserved.
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.
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.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
52 #include <mach_assert.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>
61 #include <i386/param.h>
62 #include <i386/misc_protos.h>
64 #define value_64bit(value) ((value) & 0xFFFFFFFF00000000LL)
65 #define low32(x) ((unsigned int)((x) & 0x00000000FFFFFFFFLL))
68 * Should be rewritten in asm anyway.
73 bzero_phys(addr64_t p
, uint32_t len
)
75 bzero((char *)phystokv(low32(p
)), len
);
79 * copy 'size' bytes from physical to physical address
80 * the caller must validate the physical ranges
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
88 extern void flush_dcache(vm_offset_t addr
, unsigned count
, int phys
);
90 kern_return_t
copyp2p(vm_offset_t source
, vm_offset_t dest
, unsigned int size
, unsigned int flush_action
) {
92 switch(flush_action
) {
94 flush_dcache(source
, size
, 1);
97 flush_dcache(dest
, size
, 1);
100 flush_dcache(source
, size
, 1);
101 flush_dcache(dest
, size
, 1);
105 bcopy_phys((addr64_t
)source
, (addr64_t
)dest
, (vm_size_t
)size
); /* Do a physical copy */
107 switch(flush_action
) {
109 flush_dcache(source
, size
, 1);
112 flush_dcache(dest
, size
, 1);
115 flush_dcache(source
, size
, 1);
116 flush_dcache(dest
, size
, 1);
126 * Copies data from a physical page to a virtual page. This is used to
127 * move data from the kernel to user state.
132 copyp2v(char *from
, char *to
, unsigned int size
) {
134 return(copyout(phystokv(from
), to
, size
));
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.
145 copyv2p(char *from
, char *to
, unsigned int size
) {
147 return(copyin(from
, phystokv(to
), size
));
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
158 bcopy_phys(addr64_t from
, addr64_t to
, vm_size_t bytes
)
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
);
168 * ovbcopy - like bcopy, but recognizes overlapping ranges and handles
176 vm_size_t bytes
) /* num bytes to copy */
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*/
182 bcopy_no_overwrite(from
, to
, bytes
); /* overlapping but OK */
184 /* to > from: overlapping, and must copy right-to-left. */
196 vm_size_t bytes
) /* num bytes to copy */
198 ovbcopy(from
, to
, bytes
);
219 register char *s1
, *s2
;
224 return (*--s1
- *--s2
);
230 * strlen returns the number of characters in "string" preceeding
231 * the terminating null character.
236 register const char *string
)
238 register const char *ret
= string
;
240 while (*string
++ != '\0')
242 return string
- 1 - ret
;
245 #include <libkern/OSAtomic.h>
257 newValue
= (oldValue
+ delt
);
258 } while (!OSCompareAndSwap((UInt32
)oldValue
,
259 (UInt32
)newValue
, (UInt32
*)dest
));
274 newValue
= (oldValue
- delt
);
275 } while (!OSCompareAndSwap((UInt32
)oldValue
,
276 (UInt32
)newValue
, (UInt32
*)dest
));
291 newValue
= (oldValue
| mask
);
292 } while (!OSCompareAndSwap((UInt32
)oldValue
,
293 (UInt32
)newValue
, (UInt32
*)dest
));
308 newValue
= (oldValue
& mask
);
309 } while (!OSCompareAndSwap((UInt32
)oldValue
,
310 (UInt32
)newValue
, (UInt32
*)dest
));
316 hw_compare_and_store(
321 return OSCompareAndSwap((UInt32
)oldval
, (UInt32
)newval
, (UInt32
*)dest
);
327 * Machine-dependent routine to fill in an array with up to callstack_max
328 * levels of return pc information.
330 void machine_callstack(
332 vm_size_t callstack_max
)
336 #endif /* MACH_ASSERT */
341 void fillPage(ppnum_t pa
, unsigned int fill
)
343 unsigned int *addr
= (unsigned int *)phystokv(i386_ptob(pa
));
345 int cnt
= NBPG
/sizeof(unsigned int);
347 for (i
= 0; i
< cnt
; i
++ )
351 #define cppvPHYS (cppvPsnk|cppvPsrc)
353 kern_return_t
copypv(addr64_t source
, addr64_t sink
, unsigned int size
, int which
)
357 if (value_64bit(source
) | value_64bit(sink
)) panic("copypv: 64 bit value");
359 src32
= (char *)low32(source
);
360 dst32
= (char *)low32(sink
);
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 */
365 switch (which
& cppvPHYS
) {
369 * both destination and source are physical
371 bcopy_phys(source
, sink
, (vm_size_t
)size
);
376 * destination is physical, source is virtual
378 if (which
& cppvKmap
)
380 * source is kernel virtual
382 bcopy(src32
, (char *)phystokv(dst32
), size
);
385 * source is user virtual
387 copyin(src32
, (char *)phystokv(dst32
), size
);
392 * source is physical, destination is virtual
394 if (which
& cppvKmap
)
396 * destination is kernel virtual
398 bcopy((char *)phystokv(src32
), dst32
, size
);
401 * destination is user virtual
403 copyout((char *)phystokv(src32
), dst32
, size
);
407 panic("copypv: both virtual");
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 */
417 void flush_dcache64(addr64_t addr
, unsigned count
, int phys
)
421 void invalidate_icache64(addr64_t addr
, unsigned cnt
, int phys
)
426 void switch_to_serial_console(void)
430 addr64_t vm_last_addr
;
433 mapping_set_mod(ppnum_t pn
)