]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
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. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
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. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
28 | /* | |
29 | * @OSF_COPYRIGHT@ | |
30 | */ | |
31 | /* | |
32 | * Mach Operating System | |
33 | * Copyright (c) 1991,1990 Carnegie Mellon University | |
34 | * All Rights Reserved. | |
35 | * | |
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. | |
41 | * | |
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. | |
45 | * | |
46 | * Carnegie Mellon requests users of this software to return to | |
47 | * | |
48 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |
49 | * School of Computer Science | |
50 | * Carnegie Mellon University | |
51 | * Pittsburgh PA 15213-3890 | |
52 | * | |
53 | * any improvements or extensions that they make and grant Carnegie Mellon | |
54 | * the rights to redistribute these changes. | |
55 | */ | |
56 | ||
57 | #include <mach_rt.h> | |
58 | #include <platforms.h> | |
59 | #include <mach_kdb.h> | |
60 | #include <mach_kgdb.h> | |
61 | #include <mach_kdp.h> | |
62 | #include <stat_time.h> | |
63 | #include <mach_assert.h> | |
64 | ||
65 | #include <sys/errno.h> | |
66 | #include <i386/asm.h> | |
67 | #include <i386/cpuid.h> | |
68 | #include <i386/eflags.h> | |
69 | #include <i386/proc_reg.h> | |
70 | #include <i386/trap.h> | |
71 | #include <assym.s> | |
72 | #include <mach/exception_types.h> | |
73 | #include <config_dtrace.h> | |
74 | ||
75 | #define _ARCH_I386_ASM_HELP_H_ /* Prevent inclusion of user header */ | |
76 | #include <mach/i386/syscall_sw.h> | |
77 | ||
78 | #include <i386/mp.h> | |
79 | ||
80 | /* | |
81 | * Fault recovery. | |
82 | */ | |
83 | ||
84 | #ifdef __MACHO__ | |
85 | #define RECOVERY_SECTION .section __VECTORS, __recover | |
86 | #else | |
87 | #define RECOVERY_SECTION .text | |
88 | #define RECOVERY_SECTION .text | |
89 | #endif | |
90 | ||
91 | #define RECOVER_TABLE_START \ | |
92 | .align 3 ; \ | |
93 | .globl EXT(recover_table) ;\ | |
94 | LEXT(recover_table) ;\ | |
95 | .text | |
96 | ||
97 | #define RECOVER(addr) \ | |
98 | .align 3; \ | |
99 | .quad 9f ;\ | |
100 | .quad addr ;\ | |
101 | .text ;\ | |
102 | 9: | |
103 | ||
104 | #define RECOVER_TABLE_END \ | |
105 | .align 3 ;\ | |
106 | .globl EXT(recover_table_end) ;\ | |
107 | LEXT(recover_table_end) ;\ | |
108 | .text | |
109 | ||
110 | /* | |
111 | * Allocate recovery and table. | |
112 | */ | |
113 | RECOVERY_SECTION | |
114 | RECOVER_TABLE_START | |
115 | ||
116 | Entry(call_continuation) | |
117 | movq %rdi,%rcx /* get continuation */ | |
118 | movq %rsi,%rdi /* continuation param */ | |
119 | movq %rdx,%rsi /* wait result */ | |
120 | movq %gs:CPU_KERNEL_STACK,%rsp /* set the stack */ | |
121 | xorq %rbp,%rbp /* zero frame pointer */ | |
122 | call *%rcx /* call continuation */ | |
123 | movq %gs:CPU_ACTIVE_THREAD,%rdi | |
124 | call EXT(thread_terminate) | |
125 | ||
126 | /* | |
127 | * int rdmsr_carefully(uint32_t msr, uint32_t *lo, uint32_t *hi) | |
128 | */ | |
129 | ENTRY(rdmsr_carefully) | |
130 | movl %edi, %ecx | |
131 | movq %rdx, %rdi | |
132 | RECOVERY_SECTION | |
133 | RECOVER(rdmsr_fail) | |
134 | rdmsr | |
135 | movl %eax, (%rsi) | |
136 | movl %edx, (%rdi) | |
137 | xorl %eax, %eax | |
138 | ret | |
139 | ||
140 | rdmsr_fail: | |
141 | movq $1, %rax | |
142 | ret | |
143 | ||
144 | .globl EXT(thread_exception_return) | |
145 | .globl EXT(thread_bootstrap_return) | |
146 | LEXT(thread_bootstrap_return) | |
147 | #if CONFIG_DTRACE | |
148 | call EXT(dtrace_thread_bootstrap) | |
149 | #endif | |
150 | ||
151 | LEXT(thread_exception_return) | |
152 | cli | |
153 | movq %gs:CPU_ACTIVE_THREAD,%rsp | |
154 | movq ACT_PCB_ISS(%rsp), %rsp | |
155 | xorl %ecx, %ecx /* don't check if we're in the PFZ */ | |
156 | jmp EXT(return_from_trap) | |
157 | ||
158 | /* | |
159 | * Copyin/out from user/kernel address space. | |
160 | * rdi: source address | |
161 | * rsi: destination address | |
162 | * rdx: byte count | |
163 | */ | |
164 | Entry(_bcopy) | |
165 | // TODO not pop regs; movq; think about 32 bit or 64 bit byte count | |
166 | xchgq %rdi, %rsi /* source %rsi, dest %rdi */ | |
167 | ||
168 | cld /* count up */ | |
169 | movl %edx,%ecx /* move by longwords first */ | |
170 | shrl $3,%ecx | |
171 | RECOVERY_SECTION | |
172 | RECOVER(_bcopy_fail) | |
173 | rep | |
174 | movsq /* move longwords */ | |
175 | ||
176 | movl %edx,%ecx /* now move remaining bytes */ | |
177 | andl $7,%ecx | |
178 | RECOVERY_SECTION | |
179 | RECOVER(_bcopy_fail) | |
180 | rep | |
181 | movsb | |
182 | ||
183 | xorl %eax,%eax /* return 0 for success */ | |
184 | ret /* and return */ | |
185 | ||
186 | _bcopy_fail: | |
187 | movl $(EFAULT),%eax /* return error for failure */ | |
188 | ret | |
189 | ||
190 | ||
191 | ||
192 | /* | |
193 | * Copyin string from user/kern address space. | |
194 | * rdi: source address | |
195 | * rsi: destination address | |
196 | * rdx: max byte count | |
197 | * rcx: actual byte count (OUT) | |
198 | */ | |
199 | Entry(_bcopystr) | |
200 | pushq %rdi | |
201 | xchgq %rdi, %rsi /* source %rsi, dest %rdi */ | |
202 | ||
203 | xorl %eax,%eax /* set to 0 here so that high 24 bits */ | |
204 | /* are 0 for the cmpl against 0 */ | |
205 | 2: | |
206 | RECOVERY_SECTION | |
207 | RECOVER(_bcopystr_fail) /* copy bytes... */ | |
208 | movb (%rsi),%al | |
209 | incq %rsi | |
210 | testq %rdi,%rdi /* if kernel address is ... */ | |
211 | jz 3f /* not NULL */ | |
212 | movb %al,(%rdi) /* copy the byte */ | |
213 | incq %rdi | |
214 | 3: | |
215 | testl %eax,%eax /* did we just stuff the 0-byte? */ | |
216 | jz 4f /* yes, return 0 already in %eax */ | |
217 | decq %rdx /* decrement #bytes left in buffer */ | |
218 | jnz 2b /* buffer not full, copy another byte */ | |
219 | movl $(ENAMETOOLONG),%eax /* buffer full, no \0: ENAMETOOLONG */ | |
220 | 4: | |
221 | cmpq $0,%rcx /* get OUT len ptr */ | |
222 | jz _bcopystr_ret /* if null, just return */ | |
223 | subq (%rsp),%rsi | |
224 | movq %rsi,(%rcx) /* else set OUT arg to xfer len */ | |
225 | popq %rdi /* restore registers */ | |
226 | _bcopystr_ret: | |
227 | ret /* and return */ | |
228 | ||
229 | _bcopystr_fail: | |
230 | popq %rdi /* restore registers */ | |
231 | movl $(EFAULT),%eax /* return error for failure */ | |
232 | ret | |
233 | ||
234 | ||
235 | /* | |
236 | * Done with recovery table. | |
237 | */ | |
238 | RECOVERY_SECTION | |
239 | RECOVER_TABLE_END | |
240 |