]>
Commit | Line | Data |
---|---|---|
0c530ab8 | 1 | /* |
39236c6e | 2 | * Copyright (c) 2006-2012 Apple Inc. All rights reserved. |
0c530ab8 | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
0a7de745 | 5 | * |
2d21ac55 A |
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. | |
0a7de745 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
0a7de745 | 17 | * |
2d21ac55 A |
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 | |
0c530ab8 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
0a7de745 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
0c530ab8 A |
27 | */ |
28 | ||
29 | #include <string.h> | |
30 | ||
31 | #include <mach/machine/vm_types.h> | |
32 | ||
33 | #include <mach/boolean.h> | |
34 | #include <kern/thread.h> | |
35 | #include <kern/zalloc.h> | |
36 | ||
0c530ab8 A |
37 | #include <kern/kalloc.h> |
38 | #include <kern/spl.h> | |
39 | ||
40 | #include <vm/pmap.h> | |
41 | #include <vm/vm_map.h> | |
42 | #include <vm/vm_kern.h> | |
43 | #include <mach/vm_param.h> | |
44 | #include <mach/vm_prot.h> | |
45 | #include <vm/vm_object.h> | |
46 | #include <vm/vm_page.h> | |
47 | ||
48 | #include <mach/machine/vm_param.h> | |
49 | #include <machine/thread.h> | |
50 | ||
0a7de745 | 51 | #include <kern/misc_protos.h> /* prototyping */ |
0c530ab8 A |
52 | #include <i386/misc_protos.h> |
53 | ||
54 | #include <i386/cpuid.h> | |
55 | #include <i386/cpu_data.h> | |
56 | #include <i386/mp.h> | |
57 | #include <i386/cpu_number.h> | |
58 | #include <i386/machine_cpu.h> | |
0c530ab8 A |
59 | #include <i386/seg.h> |
60 | ||
61 | #include <vm/vm_protos.h> | |
62 | ||
63 | #include <sys/kdebug.h> | |
64 | ||
65 | #include <i386/postcode.h> | |
66 | ||
0c530ab8 | 67 | #if DEBUG |
316670eb | 68 | extern void dump_regs64(void); |
0c530ab8 A |
69 | extern void dump_gdt(void *); |
70 | extern void dump_ldt(void *); | |
71 | extern void dump_idt(void *); | |
72 | extern void dump_tss(void *); | |
39236c6e | 73 | extern void dump_frame32(x86_saved_state32_t *sp); |
0c530ab8 A |
74 | extern void dump_frame64(x86_saved_state64_t *sp); |
75 | extern void dump_frame(x86_saved_state_t *sp); | |
76 | ||
77 | void | |
78 | dump_frame(x86_saved_state_t *sp) | |
79 | { | |
0a7de745 | 80 | if (is_saved_state32(sp)) { |
39236c6e | 81 | dump_frame32(&sp->ss_32); |
0a7de745 | 82 | } else if (is_saved_state64(sp)) { |
0c530ab8 | 83 | dump_frame64(&sp->ss_64); |
0a7de745 | 84 | } else { |
0c530ab8 | 85 | kprintf("dump_frame(%p) unknown type %d\n", sp, sp->flavor); |
0a7de745 | 86 | } |
0c530ab8 A |
87 | } |
88 | ||
89 | void | |
39236c6e | 90 | dump_frame32(x86_saved_state32_t *sp) |
0c530ab8 | 91 | { |
0a7de745 A |
92 | unsigned int i; |
93 | uint32_t *ip = (uint32_t *) sp; | |
0c530ab8 | 94 | |
39236c6e | 95 | kprintf("dump_frame32(%p):\n", sp); |
0a7de745 | 96 | |
0c530ab8 | 97 | for (i = 0; |
0a7de745 A |
98 | i < sizeof(x86_saved_state32_t) / sizeof(uint32_t); |
99 | i++, ip++) { | |
2d21ac55 | 100 | kprintf("%p: 0x%08x\n", ip, *ip); |
0a7de745 | 101 | } |
0c530ab8 | 102 | |
39236c6e A |
103 | kprintf("sp->gs: 0x%08x\n", sp->gs); |
104 | kprintf("sp->fs: 0x%08x\n", sp->fs); | |
105 | kprintf("sp->es: 0x%08x\n", sp->es); | |
106 | kprintf("sp->ds: 0x%08x\n", sp->ds); | |
107 | kprintf("sp->edi: 0x%08x\n", sp->edi); | |
108 | kprintf("sp->esi: 0x%08x\n", sp->esi); | |
109 | kprintf("sp->ebp: 0x%08x\n", sp->ebp); | |
110 | kprintf("sp->cr2: 0x%08x\n", sp->cr2); | |
111 | kprintf("sp->ebx: 0x%08x\n", sp->ebx); | |
112 | kprintf("sp->edx: 0x%08x\n", sp->edx); | |
113 | kprintf("sp->ecx: 0x%08x\n", sp->ecx); | |
114 | kprintf("sp->eax: 0x%08x\n", sp->eax); | |
115 | kprintf("sp->trapno: 0x%08x\n", sp->eax); | |
116 | kprintf("sp->eip: 0x%08x\n", sp->eip); | |
117 | kprintf("sp->cs: 0x%08x\n", sp->cs); | |
118 | kprintf("sp->efl: 0x%08x\n", sp->efl); | |
119 | kprintf("sp->uesp: 0x%08x\n", sp->uesp); | |
120 | kprintf("sp->ss: 0x%08x\n", sp->ss); | |
0c530ab8 A |
121 | |
122 | postcode(0x99); | |
123 | } | |
124 | ||
125 | void | |
126 | dump_frame64(x86_saved_state64_t *sp) | |
127 | { | |
0a7de745 A |
128 | unsigned int i; |
129 | uint64_t *ip = (uint64_t *) sp; | |
0c530ab8 A |
130 | |
131 | kprintf("dump_frame64(%p):\n", sp); | |
0a7de745 | 132 | |
0c530ab8 | 133 | for (i = 0; |
0a7de745 A |
134 | i < sizeof(x86_saved_state64_t) / sizeof(uint64_t); |
135 | i++, ip++) { | |
2d21ac55 | 136 | kprintf("%p: 0x%016llx\n", ip, *ip); |
0a7de745 | 137 | } |
0c530ab8 A |
138 | |
139 | kprintf("sp->isf.trapno: 0x%08x\n", sp->isf.trapno); | |
b0d623f7 | 140 | kprintf("sp->isf.trapfn: 0x%016llx\n", sp->isf.trapfn); |
0c530ab8 A |
141 | kprintf("sp->isf.err: 0x%016llx\n", sp->isf.err); |
142 | kprintf("sp->isf.rip: 0x%016llx\n", sp->isf.rip); | |
143 | kprintf("sp->isf.cs: 0x%016llx\n", sp->isf.cs); | |
144 | kprintf("sp->isf.rflags: 0x%016llx\n", sp->isf.rflags); | |
145 | kprintf("sp->isf.rsp: 0x%016llx\n", sp->isf.rsp); | |
146 | kprintf("sp->isf.ss: 0x%016llx\n", sp->isf.ss); | |
147 | ||
148 | kprintf("sp->fs: 0x%016x\n", sp->fs); | |
149 | kprintf("sp->gs: 0x%016x\n", sp->gs); | |
150 | kprintf("sp->rax: 0x%016llx\n", sp->rax); | |
151 | kprintf("sp->rcx: 0x%016llx\n", sp->rcx); | |
152 | kprintf("sp->rbx: 0x%016llx\n", sp->rbx); | |
153 | kprintf("sp->rbp: 0x%016llx\n", sp->rbp); | |
154 | kprintf("sp->r11: 0x%016llx\n", sp->r11); | |
155 | kprintf("sp->r12: 0x%016llx\n", sp->r12); | |
156 | kprintf("sp->r13: 0x%016llx\n", sp->r13); | |
157 | kprintf("sp->r14: 0x%016llx\n", sp->r14); | |
158 | kprintf("sp->r15: 0x%016llx\n", sp->r15); | |
159 | kprintf("sp->cr2: 0x%016llx\n", sp->cr2); | |
0c530ab8 A |
160 | kprintf("sp->r9: 0x%016llx\n", sp->r9); |
161 | kprintf("sp->r8: 0x%016llx\n", sp->r8); | |
162 | kprintf("sp->r10: 0x%016llx\n", sp->r10); | |
163 | kprintf("sp->rdx: 0x%016llx\n", sp->rdx); | |
164 | kprintf("sp->rsi: 0x%016llx\n", sp->rsi); | |
165 | kprintf("sp->rdi: 0x%016llx\n", sp->rdi); | |
166 | ||
167 | postcode(0x98); | |
168 | } | |
169 | ||
170 | void | |
171 | dump_gdt(void *gdtp) | |
172 | { | |
0a7de745 A |
173 | unsigned int i; |
174 | uint32_t *ip = (uint32_t *) gdtp; | |
0c530ab8 | 175 | |
2d21ac55 | 176 | kprintf("GDT:\n"); |
0c530ab8 | 177 | for (i = 0; i < GDTSZ; i++, ip += 2) { |
0a7de745 A |
178 | kprintf("%p: 0x%08x\n", ip + 0, *(ip + 0)); |
179 | kprintf("%p: 0x%08x\n", ip + 1, *(ip + 1)); | |
0c530ab8 A |
180 | } |
181 | } | |
182 | ||
183 | void | |
184 | dump_ldt(void *ldtp) | |
185 | { | |
0a7de745 A |
186 | unsigned int i; |
187 | uint32_t *ip = (uint32_t *) ldtp; | |
0c530ab8 | 188 | |
2d21ac55 | 189 | kprintf("LDT:\n"); |
0c530ab8 | 190 | for (i = 0; i < LDTSZ_MIN; i++, ip += 2) { |
0a7de745 A |
191 | kprintf("%p: 0x%08x\n", ip + 0, *(ip + 0)); |
192 | kprintf("%p: 0x%08x\n", ip + 1, *(ip + 1)); | |
0c530ab8 A |
193 | } |
194 | } | |
195 | ||
196 | void | |
197 | dump_idt(void *idtp) | |
198 | { | |
0a7de745 A |
199 | unsigned int i; |
200 | uint32_t *ip = (uint32_t *) idtp; | |
0c530ab8 | 201 | |
2d21ac55 | 202 | kprintf("IDT64:\n"); |
0c530ab8 | 203 | for (i = 0; i < 16; i++, ip += 4) { |
0a7de745 A |
204 | kprintf("%p: 0x%08x\n", ip + 0, *(ip + 0)); |
205 | kprintf("%p: 0x%08x\n", ip + 1, *(ip + 1)); | |
206 | kprintf("%p: 0x%08x\n", ip + 2, *(ip + 2)); | |
207 | kprintf("%p: 0x%08x\n", ip + 3, *(ip + 3)); | |
0c530ab8 A |
208 | } |
209 | } | |
210 | ||
211 | void | |
212 | dump_tss(void *tssp) | |
213 | { | |
0a7de745 A |
214 | unsigned int i; |
215 | uint32_t *ip = (uint32_t *) tssp; | |
0c530ab8 | 216 | |
2d21ac55 | 217 | kprintf("TSS64:\n"); |
0a7de745 A |
218 | for (i = 0; i < sizeof(master_ktss64) / sizeof(uint32_t); i++, ip++) { |
219 | kprintf("%p: 0x%08x\n", ip + 0, *(ip + 0)); | |
0c530ab8 A |
220 | } |
221 | } | |
316670eb | 222 | |
0a7de745 A |
223 | void |
224 | dump_regs64(void) | |
316670eb | 225 | { |
0a7de745 A |
226 | #define SNAP_REG(reg) \ |
227 | uint64_t reg; \ | |
316670eb A |
228 | __asm__ volatile("mov %%" #reg ", %0" : "=m" (reg)) |
229 | ||
0a7de745 | 230 | #define KPRINT_REG(reg) \ |
316670eb A |
231 | kprintf("%3s: %p\n", #reg, (void *) reg) |
232 | ||
233 | SNAP_REG(rsp); | |
234 | SNAP_REG(rbp); | |
235 | SNAP_REG(rax); | |
236 | SNAP_REG(rbx); | |
237 | SNAP_REG(rcx); | |
238 | SNAP_REG(rdx); | |
239 | SNAP_REG(rsi); | |
240 | SNAP_REG(rdi); | |
241 | SNAP_REG(r8); | |
242 | SNAP_REG(r9); | |
243 | SNAP_REG(r10); | |
244 | SNAP_REG(r11); | |
245 | SNAP_REG(r12); | |
246 | SNAP_REG(r13); | |
247 | SNAP_REG(r14); | |
248 | ||
249 | KPRINT_REG(rsp); | |
250 | KPRINT_REG(rbp); | |
251 | KPRINT_REG(rax); | |
252 | KPRINT_REG(rbx); | |
253 | KPRINT_REG(rcx); | |
254 | KPRINT_REG(rdx); | |
255 | KPRINT_REG(rsi); | |
256 | KPRINT_REG(rdi); | |
257 | KPRINT_REG(r8); | |
258 | KPRINT_REG(r9); | |
259 | KPRINT_REG(r10); | |
260 | KPRINT_REG(r11); | |
261 | KPRINT_REG(r12); | |
262 | KPRINT_REG(r13); | |
263 | KPRINT_REG(r14); | |
264 | } | |
0c530ab8 | 265 | #endif /* DEBUG */ |