2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
58 #include <mach_assert.h>
61 #include <mach/boolean.h>
62 #include <mach/i386/vm_types.h>
63 #include <mach/i386/vm_param.h>
64 #include <kern/kern_types.h>
65 #include <kern/misc_protos.h>
66 #include <sys/errno.h>
67 #include <i386/param.h>
68 #include <i386/misc_protos.h>
69 #include <i386/cpu_data.h>
70 #include <i386/machine_routines.h>
71 #include <i386/cpuid.h>
74 #include <vm/vm_map.h>
75 #include <vm/vm_kern.h>
76 #include <vm/vm_fault.h>
78 #include <libkern/OSAtomic.h>
79 #include <sys/kdebug.h>
84 #define KERNEL_DEBUG KERNEL_DEBUG_CONSTANT
89 /* XXX - should be gone from here */
90 extern void invalidate_icache64(addr64_t addr
, unsigned cnt
, int phys
);
91 extern void flush_dcache64(addr64_t addr
, unsigned count
, int phys
);
92 extern boolean_t
phys_page_exists(ppnum_t
);
93 extern void bcopy_no_overwrite(const char *from
, char *to
,vm_size_t bytes
);
94 extern void pmap_set_reference(ppnum_t pn
);
95 extern void mapping_set_mod(ppnum_t pa
);
96 extern void mapping_set_ref(ppnum_t pn
);
98 extern void ovbcopy(const char *from
,
101 void machine_callstack(natural_t
*buf
, vm_size_t callstack_max
);
104 #define value_64bit(value) ((value) & 0xFFFFFFFF00000000ULL)
105 #define low32(x) ((unsigned int)((x) & 0x00000000FFFFFFFFULL))
107 #define INT_SIZE (BYTE_SIZE * sizeof (int))
110 * Set indicated bit in bit string.
113 setbit(int bitno
, int *s
)
115 s
[bitno
/ INT_SIZE
] |= 1 << (bitno
% INT_SIZE
);
119 * Clear indicated bit in bit string.
122 clrbit(int bitno
, int *s
)
124 s
[bitno
/ INT_SIZE
] &= ~(1 << (bitno
% INT_SIZE
));
128 * Test if indicated bit is set in bit string.
131 testbit(int bitno
, int *s
)
133 return s
[bitno
/ INT_SIZE
] & (1 << (bitno
% INT_SIZE
));
137 * Find first bit set in bit string.
144 for (offset
= 0; !*s
; offset
+= (int)INT_SIZE
, ++s
);
145 return offset
+ __builtin_ctz(*s
);
149 ffs(unsigned int mask
)
155 * NOTE: cannot use __builtin_ffs because it generates a call to
158 return 1 + __builtin_ctz(mask
);
166 bzero_phys(src64
,bytes
);
174 bzero(PHYSMAP_PTOV(src64
), bytes
);
179 * bcopy_phys - like bcopy but copies from/to physical addresses.
188 /* Not necessary for K64 - but ensure we stay within a page */
189 if (((((uint32_t)src64
& (NBPG
-1)) + bytes
) > NBPG
) ||
190 ((((uint32_t)dst64
& (NBPG
-1)) + bytes
) > NBPG
) ) {
191 panic("bcopy_phys alignment");
193 bcopy(PHYSMAP_PTOV(src64
), PHYSMAP_PTOV(dst64
), bytes
);
197 * ovbcopy - like bcopy, but recognizes overlapping ranges and handles
205 vm_size_t bytes
) /* num bytes to copy */
207 /* Assume that bcopy copies left-to-right (low addr first). */
208 if (from
+ bytes
<= to
|| to
+ bytes
<= from
|| to
== from
)
209 bcopy_no_overwrite(from
, to
, bytes
); /* non-overlapping or no-op*/
211 bcopy_no_overwrite(from
, to
, bytes
); /* overlapping but OK */
213 /* to > from: overlapping, and must copy right-to-left. */
223 * Read data from a physical address. Memory should not be cache inhibited.
228 ml_phys_read_data(pmap_paddr_t paddr
, int size
)
236 s1
= *(unsigned char *)PHYSMAP_PTOV(paddr
);
240 s2
= *(unsigned short *)PHYSMAP_PTOV(paddr
);
245 result
= *(unsigned int *)PHYSMAP_PTOV(paddr
);
252 static unsigned long long
253 ml_phys_read_long_long(pmap_paddr_t paddr
)
255 return *(unsigned long long *)PHYSMAP_PTOV(paddr
);
260 unsigned int ml_phys_read( vm_offset_t paddr
)
262 return ml_phys_read_data((pmap_paddr_t
)paddr
, 4);
265 unsigned int ml_phys_read_word(vm_offset_t paddr
) {
267 return ml_phys_read_data((pmap_paddr_t
)paddr
, 4);
270 unsigned int ml_phys_read_64(addr64_t paddr64
)
272 return ml_phys_read_data((pmap_paddr_t
)paddr64
, 4);
275 unsigned int ml_phys_read_word_64(addr64_t paddr64
)
277 return ml_phys_read_data((pmap_paddr_t
)paddr64
, 4);
280 unsigned int ml_phys_read_half(vm_offset_t paddr
)
282 return ml_phys_read_data((pmap_paddr_t
)paddr
, 2);
285 unsigned int ml_phys_read_half_64(addr64_t paddr64
)
287 return ml_phys_read_data((pmap_paddr_t
)paddr64
, 2);
290 unsigned int ml_phys_read_byte(vm_offset_t paddr
)
292 return ml_phys_read_data((pmap_paddr_t
)paddr
, 1);
295 unsigned int ml_phys_read_byte_64(addr64_t paddr64
)
297 return ml_phys_read_data((pmap_paddr_t
)paddr64
, 1);
300 unsigned long long ml_phys_read_double(vm_offset_t paddr
)
302 return ml_phys_read_long_long((pmap_paddr_t
)paddr
);
305 unsigned long long ml_phys_read_double_64(addr64_t paddr64
)
307 return ml_phys_read_long_long((pmap_paddr_t
)paddr64
);
313 * Write data to a physical address. Memory should not be cache inhibited.
317 ml_phys_write_data(pmap_paddr_t paddr
, unsigned long data
, int size
)
321 *(unsigned char *)PHYSMAP_PTOV(paddr
) = (unsigned char)data
;
324 *(unsigned short *)PHYSMAP_PTOV(paddr
) = (unsigned short)data
;
328 *(unsigned int *)PHYSMAP_PTOV(paddr
) = (unsigned int)data
;
334 ml_phys_write_long_long(pmap_paddr_t paddr
, unsigned long long data
)
336 *(unsigned long long *)PHYSMAP_PTOV(paddr
) = data
;
341 void ml_phys_write_byte(vm_offset_t paddr
, unsigned int data
)
343 ml_phys_write_data((pmap_paddr_t
)paddr
, data
, 1);
346 void ml_phys_write_byte_64(addr64_t paddr64
, unsigned int data
)
348 ml_phys_write_data((pmap_paddr_t
)paddr64
, data
, 1);
351 void ml_phys_write_half(vm_offset_t paddr
, unsigned int data
)
353 ml_phys_write_data((pmap_paddr_t
)paddr
, data
, 2);
356 void ml_phys_write_half_64(addr64_t paddr64
, unsigned int data
)
358 ml_phys_write_data((pmap_paddr_t
)paddr64
, data
, 2);
361 void ml_phys_write(vm_offset_t paddr
, unsigned int data
)
363 ml_phys_write_data((pmap_paddr_t
)paddr
, data
, 4);
366 void ml_phys_write_64(addr64_t paddr64
, unsigned int data
)
368 ml_phys_write_data((pmap_paddr_t
)paddr64
, data
, 4);
371 void ml_phys_write_word(vm_offset_t paddr
, unsigned int data
)
373 ml_phys_write_data((pmap_paddr_t
)paddr
, data
, 4);
376 void ml_phys_write_word_64(addr64_t paddr64
, unsigned int data
)
378 ml_phys_write_data((pmap_paddr_t
)paddr64
, data
, 4);
381 void ml_phys_write_double(vm_offset_t paddr
, unsigned long long data
)
383 ml_phys_write_long_long((pmap_paddr_t
)paddr
, data
);
386 void ml_phys_write_double_64(addr64_t paddr64
, unsigned long long data
)
388 ml_phys_write_long_long((pmap_paddr_t
)paddr64
, data
);
392 /* PCI config cycle probing
395 * Read the memory location at physical address paddr.
396 * This is a part of a device probe, so there is a good chance we will
397 * have a machine check here. So we have to be able to handle that.
398 * We assume that machine checks are enabled both in MSR and HIDs
402 ml_probe_read(vm_offset_t paddr
, unsigned int *val
)
404 if ((PAGE_SIZE
- (paddr
& PAGE_MASK
)) < 4)
407 *val
= ml_phys_read((pmap_paddr_t
)paddr
);
413 * Read the memory location at physical address paddr.
414 * This is a part of a device probe, so there is a good chance we will
415 * have a machine check here. So we have to be able to handle that.
416 * We assume that machine checks are enabled both in MSR and HIDs
419 ml_probe_read_64(addr64_t paddr64
, unsigned int *val
)
421 if ((PAGE_SIZE
- (paddr64
& PAGE_MASK
)) < 4)
424 *val
= ml_phys_read_64((pmap_paddr_t
)paddr64
);
434 const char *a
= (const char *)pa
;
435 const char *b
= (const char *)pb
;
449 memcmp(const void *s1
, const void *s2
, size_t n
)
452 const unsigned char *p1
= s1
, *p2
= s2
;
456 return (*--p1
- *--p2
);
464 * strlen returns the number of characters in "string" preceeding
465 * the terminating null character.
470 register const char *string
)
472 register const char *ret
= string
;
474 while (*string
++ != '\0')
476 return string
- 1 - ret
;
480 hw_compare_and_store(uint32_t oldval
, uint32_t newval
, volatile uint32_t *dest
)
482 return OSCompareAndSwap((UInt32
)oldval
,
484 (volatile UInt32
*)dest
);
490 * Machine-dependent routine to fill in an array with up to callstack_max
491 * levels of return pc information.
493 void machine_callstack(
494 __unused natural_t
*buf
,
495 __unused vm_size_t callstack_max
)
499 #endif /* MACH_ASSERT */
501 void fillPage(ppnum_t pa
, unsigned int fill
)
505 int cnt
= PAGE_SIZE
/ sizeof(unsigned int);
509 for (i
= 0, addr
= (unsigned int *)PHYSMAP_PTOV(src
); i
< cnt
; i
++)
513 static inline void __sfence(void)
515 __asm__
volatile("sfence");
517 static inline void __mfence(void)
519 __asm__
volatile("mfence");
521 static inline void __wbinvd(void)
523 __asm__
volatile("wbinvd");
525 static inline void __clflush(void *ptr
)
527 __asm__
volatile("clflush (%0)" : : "r" (ptr
));
530 void dcache_incoherent_io_store64(addr64_t pa
, unsigned int count
)
532 uint32_t linesize
= cpuid_info()->cache_linesize
;
538 istate
= ml_set_interrupts_enabled(FALSE
);
540 for (addr
= pa
; addr
< pa
+ count
; addr
+= linesize
)
541 __clflush(PHYSMAP_PTOV(addr
));
543 (void) ml_set_interrupts_enabled(istate
);
548 void dcache_incoherent_io_flush64(addr64_t pa
, unsigned int count
)
550 return(dcache_incoherent_io_store64(pa
,count
));
554 flush_dcache64(__unused addr64_t addr
,
555 __unused
unsigned count
,
561 invalidate_icache64(__unused addr64_t addr
,
562 __unused
unsigned count
,
568 addr64_t vm_last_addr
;
571 mapping_set_mod(ppnum_t pn
)
577 mapping_set_ref(ppnum_t pn
)
579 pmap_set_reference(pn
);
583 cache_flush_page_phys(ppnum_t pa
)
586 unsigned char *cacheline_addr
;
587 int cacheline_size
= cpuid_info()->cache_linesize
;
588 int cachelines_to_flush
= PAGE_SIZE
/cacheline_size
;
592 istate
= ml_set_interrupts_enabled(FALSE
);
594 for (cacheline_addr
= (unsigned char *)PHYSMAP_PTOV(i386_ptob(pa
));
595 cachelines_to_flush
> 0;
596 cachelines_to_flush
--, cacheline_addr
+= cacheline_size
) {
597 __clflush((void *) cacheline_addr
);
600 (void) ml_set_interrupts_enabled(istate
);
606 static int copyio(int, user_addr_t
, char *, vm_size_t
, vm_size_t
*, int);
607 static int copyio_phys(addr64_t
, addr64_t
, vm_size_t
, int);
610 * The copy engine has the following characteristics
611 * - copyio() handles copies to/from user or kernel space
612 * - copypv() deals with physical or virtual addresses
614 * Readers familiar with the 32-bit kernel will expect Joe's thesis at this
615 * point describing the full glory of the copy window implementation. In K64,
616 * however, there is no need for windowing. Thanks to the vast shared address
617 * space, the kernel has direct access to userspace and to physical memory.
619 * User virtual addresses are accessible provided the user's cr3 is loaded.
620 * Physical addresses are accessible via the direct map and the PHYSMAP_PTOV()
623 * Copyin/out variants all boil done to just these 2 routines in locore.s which
624 * provide fault-recoverable copying:
626 extern int _bcopy(const void *, void *, vm_size_t
);
627 extern int _bcopystr(const void *, void *, vm_size_t
, vm_size_t
*);
633 #define COPYIN 0 /* from user virtual to kernel virtual */
634 #define COPYOUT 1 /* from kernel virtual to user virtual */
635 #define COPYINSTR 2 /* string variant of copyout */
636 #define COPYINPHYS 3 /* from user virtual to kernel physical */
637 #define COPYOUTPHYS 4 /* from kernel physical to user virtual */
641 copyio(int copy_type
, user_addr_t user_addr
, char *kernel_addr
,
642 vm_size_t nbytes
, vm_size_t
*lencopied
, int use_kernel_map
)
646 vm_size_t bytes_copied
;
648 boolean_t istate
= FALSE
;
649 boolean_t recursive_CopyIOActive
;
651 int debug_type
= 0xeff70010;
652 debug_type
+= (copy_type
<< 2);
655 thread
= current_thread();
657 KERNEL_DEBUG(debug_type
| DBG_FUNC_START
,
658 (unsigned)(user_addr
>> 32), (unsigned)user_addr
,
659 nbytes
, thread
->machine
.copyio_state
, 0);
664 pmap
= thread
->map
->pmap
;
666 /* Sanity and security check for addresses to/from a user */
667 if ((copy_type
== COPYIN
||
668 copy_type
== COPYINSTR
||
669 copy_type
== COPYOUT
) &&
670 (pmap
!= kernel_pmap
) &&
671 ((vm_offset_t
)kernel_addr
< VM_MIN_KERNEL_AND_KEXT_ADDRESS
||
672 !IS_USERADDR64_CANONICAL(user_addr
))) {
678 * If the no_shared_cr3 boot-arg is set (true), the kernel runs on
679 * its own pmap and cr3 rather than the user's -- so that wild accesses
680 * from kernel or kexts can be trapped. So, during copyin and copyout,
681 * we need to switch back to the user's map/cr3. The thread is flagged
682 * "CopyIOActive" at this time so that if the thread is pre-empted,
683 * we will later restore the correct cr3.
685 recursive_CopyIOActive
= thread
->machine
.specFlags
& CopyIOActive
;
686 thread
->machine
.specFlags
|= CopyIOActive
;
688 istate
= ml_set_interrupts_enabled(FALSE
);
689 if (get_cr3() != pmap
->pm_cr3
)
690 set_cr3(pmap
->pm_cr3
);
694 * Ensure that we're running on the target thread's cr3.
696 if ((pmap
!= kernel_pmap
) && !use_kernel_map
&&
697 (get_cr3() != pmap
->pm_cr3
)) {
698 panic("copyio(%d,%p,%p,%ld,%p,%d) cr3 is %p expects %p",
699 copy_type
, (void *)user_addr
, kernel_addr
, nbytes
, lencopied
, use_kernel_map
,
700 (void *) get_cr3(), (void *) pmap
->pm_cr3
);
703 (void) ml_set_interrupts_enabled(istate
);
705 KERNEL_DEBUG(0xeff70044 | DBG_FUNC_NONE
, (unsigned)user_addr
,
706 (unsigned)kernel_addr
, nbytes
, 0, 0);
711 error
= _bcopy((const void *) user_addr
,
717 error
= _bcopy(kernel_addr
,
723 error
= _bcopy((const void *) user_addr
,
724 PHYSMAP_PTOV(kernel_addr
),
729 error
= _bcopy((const void *) PHYSMAP_PTOV(kernel_addr
),
735 error
= _bcopystr((const void *) user_addr
,
741 * lencopied should be updated on success
742 * or ENAMETOOLONG... but not EFAULT
745 *lencopied
= bytes_copied
;
753 if (*(kernel_addr
+ bytes_copied
- 1) == 0) {
755 * we found a NULL terminator... we're done
763 * no more room in the buffer and we haven't
764 * yet come across a NULL terminator
769 error
= ENAMETOOLONG
;
775 if (!recursive_CopyIOActive
)
776 thread
->machine
.specFlags
&= ~CopyIOActive
;
778 istate
= ml_set_interrupts_enabled(FALSE
);
779 if (get_cr3() != kernel_pmap
->pm_cr3
)
780 set_cr3(kernel_pmap
->pm_cr3
);
781 (void) ml_set_interrupts_enabled(istate
);
785 KERNEL_DEBUG(debug_type
| DBG_FUNC_END
, (unsigned)user_addr
,
786 (unsigned)kernel_addr
, (unsigned)nbytes
, error
, 0);
793 copyio_phys(addr64_t source
, addr64_t sink
, vm_size_t csize
, int which
)
799 if (which
& cppvPsnk
) {
800 paddr
= (char *)sink
;
801 vaddr
= (user_addr_t
)source
;
804 paddr
= (char *)source
;
805 vaddr
= (user_addr_t
)sink
;
808 return copyio(ctype
, vaddr
, paddr
, csize
, NULL
, which
& cppvKmap
);
812 copyinmsg(const user_addr_t user_addr
, char *kernel_addr
, mach_msg_size_t nbytes
)
814 return copyio(COPYIN
, user_addr
, kernel_addr
, nbytes
, NULL
, 0);
818 copyin(const user_addr_t user_addr
, char *kernel_addr
, vm_size_t nbytes
)
820 return copyio(COPYIN
, user_addr
, kernel_addr
, nbytes
, NULL
, 0);
824 copyinstr(const user_addr_t user_addr
, char *kernel_addr
, vm_size_t nbytes
, vm_size_t
*lencopied
)
828 return copyio(COPYINSTR
, user_addr
, kernel_addr
, nbytes
, lencopied
, 0);
832 copyoutmsg(const char *kernel_addr
, user_addr_t user_addr
, mach_msg_size_t nbytes
)
834 return copyio(COPYOUT
, user_addr
, (char *)(uintptr_t)kernel_addr
, nbytes
, NULL
, 0);
838 copyout(const void *kernel_addr
, user_addr_t user_addr
, vm_size_t nbytes
)
840 return copyio(COPYOUT
, user_addr
, (char *)(uintptr_t)kernel_addr
, nbytes
, NULL
, 0);
845 copypv(addr64_t src64
, addr64_t snk64
, unsigned int size
, int which
)
847 unsigned int lop
, csize
;
850 KERNEL_DEBUG(0xeff7004c | DBG_FUNC_START
, (unsigned)src64
,
851 (unsigned)snk64
, size
, which
, 0);
853 if ((which
& (cppvPsrc
| cppvPsnk
)) == 0 ) /* Make sure that only one is virtual */
854 panic("copypv: no more than 1 parameter may be virtual\n"); /* Not allowed */
856 if ((which
& (cppvPsrc
| cppvPsnk
)) == (cppvPsrc
| cppvPsnk
))
857 bothphys
= 1; /* both are physical */
862 lop
= (unsigned int)(PAGE_SIZE
- (snk64
& (PAGE_SIZE
- 1))); /* Assume sink smallest */
864 if (lop
> (unsigned int)(PAGE_SIZE
- (src64
& (PAGE_SIZE
- 1))))
865 lop
= (unsigned int)(PAGE_SIZE
- (src64
& (PAGE_SIZE
- 1))); /* No, source is smaller */
868 * only need to compute the resid for the physical page
869 * address... we don't care about where we start/finish in
870 * the virtual since we just call the normal copyin/copyout
872 if (which
& cppvPsrc
)
873 lop
= (unsigned int)(PAGE_SIZE
- (src64
& (PAGE_SIZE
- 1)));
875 lop
= (unsigned int)(PAGE_SIZE
- (snk64
& (PAGE_SIZE
- 1)));
877 csize
= size
; /* Assume we can copy it all */
879 csize
= lop
; /* Nope, we can't do it all */
882 * flush_dcache64 is currently a nop on the i386...
883 * it's used when copying to non-system memory such
884 * as video capture cards... on PPC there was a need
885 * to flush due to how we mapped this memory... not
886 * sure if it's needed on i386.
888 if (which
& cppvFsrc
)
889 flush_dcache64(src64
, csize
, 1); /* If requested, flush source before move */
890 if (which
& cppvFsnk
)
891 flush_dcache64(snk64
, csize
, 1); /* If requested, flush sink before move */
894 bcopy_phys(src64
, snk64
, csize
); /* Do a physical copy, virtually */
896 if (copyio_phys(src64
, snk64
, csize
, which
))
897 return (KERN_FAILURE
);
900 if (which
& cppvFsrc
)
901 flush_dcache64(src64
, csize
, 1); /* If requested, flush source after move */
902 if (which
& cppvFsnk
)
903 flush_dcache64(snk64
, csize
, 1); /* If requested, flush sink after move */
905 size
-= csize
; /* Calculate what is left */
906 snk64
+= csize
; /* Bump sink to next physical address */
907 src64
+= csize
; /* Bump source to next physical address */
909 KERNEL_DEBUG(0xeff7004c | DBG_FUNC_END
, (unsigned)src64
,
910 (unsigned)snk64
, size
, which
, 0);
917 kdp_register_callout(void)
923 int host_vmxon(boolean_t exclusive __unused
)
925 return VMX_UNSUPPORTED
;
928 void host_vmxoff(void)