]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/AT386/model_dep.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / osfmk / i386 / AT386 / model_dep.c
CommitLineData
1c79356b 1/*
39236c6e 2 * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 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.
8f6c56a5 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.
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
8f6c56a5
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989, 1988 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/*
58 */
59
60/*
61 * File: model_dep.c
62 * Author: Avadis Tevanian, Jr., Michael Wayne Young
63 *
64 * Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
65 *
66 * Basic initialization for I386 - ISA bus machines.
67 */
68
1c79356b
A
69
70#include <mach/i386/vm_param.h>
71
72#include <string.h>
73#include <mach/vm_param.h>
74#include <mach/vm_prot.h>
75#include <mach/machine.h>
76#include <mach/time_value.h>
04b8595b 77#include <sys/kdebug.h>
1c79356b
A
78#include <kern/spl.h>
79#include <kern/assert.h>
80#include <kern/debug.h>
81#include <kern/misc_protos.h>
82#include <kern/startup.h>
83#include <kern/clock.h>
1c79356b 84#include <kern/cpu_data.h>
91447636 85#include <kern/machine.h>
b0d623f7
A
86#include <i386/postcode.h>
87#include <i386/mp_desc.h>
88#include <i386/misc_protos.h>
89#include <i386/thread.h>
90#include <i386/trap.h>
91#include <i386/machine_routines.h>
92#include <i386/mp.h> /* mp_rendezvous_break_lock */
93#include <i386/cpuid.h>
1c79356b 94#include <i386/fpu.h>
6d2010ae
A
95#include <i386/machine_cpu.h>
96#include <i386/pmap.h>
97#if CONFIG_MTRR
91447636 98#include <i386/mtrr.h>
6d2010ae
A
99#endif
100#include <i386/ucode.h>
0c530ab8 101#include <i386/pmCPU.h>
fe8ab488
A
102#include <i386/panic_hooks.h>
103
0c530ab8 104#include <architecture/i386/pio.h> /* inb() */
55e303ae 105#include <pexpert/i386/boot.h>
1c79356b 106
04b8595b 107#include <kdp/kdp_dyld.h>
0c530ab8
A
108#include <vm/pmap.h>
109#include <vm/vm_map.h>
110#include <vm/vm_kern.h>
111
9bccf70c 112#include <IOKit/IOPlatformExpert.h>
0c530ab8
A
113#include <IOKit/IOHibernatePrivate.h>
114
115#include <pexpert/i386/efi.h>
116
117#include <kern/thread.h>
316670eb 118#include <kern/sched.h>
0c530ab8
A
119#include <mach-o/loader.h>
120#include <mach-o/nlist.h>
9bccf70c 121
b0d623f7 122#include <libkern/kernel_mach_header.h>
6d2010ae
A
123#include <libkern/OSKextLibPrivate.h>
124
7ddcb079
A
125#if DEBUG
126#define DPRINTF(x...) kprintf(x)
127#else
6d2010ae 128#define DPRINTF(x...)
7ddcb079 129#endif
91447636 130
55e303ae 131static void machine_conf(void);
04b8595b 132void panic_print_symbol_name(vm_address_t search);
1c79356b 133
04b8595b
A
134extern boolean_t init_task_died;
135extern const char version[];
136extern char osversion[];
91447636
A
137extern int max_unsafe_quanta;
138extern int max_poll_quanta;
91447636
A
139extern unsigned int panic_is_inited;
140
04b8595b
A
141extern int proc_pid(void *p);
142
143/* Definitions for frame pointers */
144#define FP_ALIGNMENT_MASK ((uint32_t)(0x3))
145#define FP_LR_OFFSET ((uint32_t)4)
146#define FP_LR_OFFSET64 ((uint32_t)8)
147#define FP_MAX_NUM_TO_EVALUATE (50)
148
0c530ab8
A
149int db_run_mode;
150
0c530ab8
A
151volatile int pbtcpu = -1;
152hw_lock_data_t pbtlock; /* backtrace print lock */
153uint32_t pbtcnt = 0;
154
6d2010ae
A
155volatile int panic_double_fault_cpu = -1;
156
b0d623f7 157#define PRINT_ARGS_FROM_STACK_FRAME 0
b0d623f7 158
0c530ab8
A
159typedef struct _cframe_t {
160 struct _cframe_t *prev;
b0d623f7
A
161 uintptr_t caller;
162#if PRINT_ARGS_FROM_STACK_FRAME
0c530ab8 163 unsigned args[0];
b0d623f7 164#endif
0c530ab8
A
165} cframe_t;
166
2d21ac55
A
167static unsigned panic_io_port;
168static unsigned commit_paniclog_to_nvram;
0c530ab8 169
b7266188 170unsigned int debug_boot_arg;
c910b4d9 171
04b8595b
A
172/*
173 * Backtrace a single frame.
174 */
175void
176print_one_backtrace(pmap_t pmap, vm_offset_t topfp, const char *cur_marker,
177 boolean_t is_64_bit, boolean_t nvram_format)
178{
179 int i = 0;
180 addr64_t lr;
181 addr64_t fp;
182 addr64_t fp_for_ppn;
183 ppnum_t ppn;
184 boolean_t dump_kernel_stack;
185
186 fp = topfp;
187 fp_for_ppn = 0;
188 ppn = (ppnum_t)NULL;
189
190 if (fp >= VM_MIN_KERNEL_ADDRESS)
191 dump_kernel_stack = TRUE;
192 else
193 dump_kernel_stack = FALSE;
194
195 do {
196 if ((fp == 0) || ((fp & FP_ALIGNMENT_MASK) != 0))
197 break;
198 if (dump_kernel_stack && ((fp < VM_MIN_KERNEL_ADDRESS) || (fp > VM_MAX_KERNEL_ADDRESS)))
199 break;
200 if ((!dump_kernel_stack) && (fp >=VM_MIN_KERNEL_ADDRESS))
201 break;
202
203 /* Check to see if current address will result in a different
204 ppn than previously computed (to avoid recomputation) via
205 (addr) ^ fp_for_ppn) >> PAGE_SHIFT) */
206
207 if ((((fp + FP_LR_OFFSET) ^ fp_for_ppn) >> PAGE_SHIFT) != 0x0U) {
208 ppn = pmap_find_phys(pmap, fp + FP_LR_OFFSET);
209 fp_for_ppn = fp + (is_64_bit ? FP_LR_OFFSET64 : FP_LR_OFFSET);
210 }
211 if (ppn != (ppnum_t)NULL) {
212 if (is_64_bit) {
213 lr = ml_phys_read_double_64(((((vm_offset_t)ppn) << PAGE_SHIFT)) | ((fp + FP_LR_OFFSET64) & PAGE_MASK));
214 } else {
215 lr = ml_phys_read_word(((((vm_offset_t)ppn) << PAGE_SHIFT)) | ((fp + FP_LR_OFFSET) & PAGE_MASK));
216 }
217 } else {
218 if (is_64_bit) {
219 kdb_printf("%s\t Could not read LR from frame at 0x%016llx\n", cur_marker, fp + FP_LR_OFFSET64);
220 } else {
221 kdb_printf("%s\t Could not read LR from frame at 0x%08x\n", cur_marker, (uint32_t)(fp + FP_LR_OFFSET));
222 }
223 break;
224 }
225 if (((fp ^ fp_for_ppn) >> PAGE_SHIFT) != 0x0U) {
226 ppn = pmap_find_phys(pmap, fp);
227 fp_for_ppn = fp;
228 }
229 if (ppn != (ppnum_t)NULL) {
230 if (is_64_bit) {
231 fp = ml_phys_read_double_64(((((vm_offset_t)ppn) << PAGE_SHIFT)) | (fp & PAGE_MASK));
232 } else {
233 fp = ml_phys_read_word(((((vm_offset_t)ppn) << PAGE_SHIFT)) | (fp & PAGE_MASK));
234 }
235 } else {
236 if (is_64_bit) {
237 kdb_printf("%s\t Could not read FP from frame at 0x%016llx\n", cur_marker, fp);
238 } else {
239 kdb_printf("%s\t Could not read FP from frame at 0x%08x\n", cur_marker, (uint32_t)fp);
240 }
241 break;
242 }
243
244 if (nvram_format) {
245 if (is_64_bit) {
246 kdb_printf("%s\t0x%016llx\n", cur_marker, lr);
247 } else {
248 kdb_printf("%s\t0x%08x\n", cur_marker, (uint32_t)lr);
249 }
250 } else {
251 if (is_64_bit) {
252 kdb_printf("%s\t lr: 0x%016llx fp: 0x%016llx\n", cur_marker, lr, fp);
253 } else {
254 kdb_printf("%s\t lr: 0x%08x fp: 0x%08x\n", cur_marker, (uint32_t)lr, (uint32_t)fp);
255 }
256 }
257 } while ((++i < FP_MAX_NUM_TO_EVALUATE) && (fp != topfp));
258}
1c79356b 259void
2d21ac55 260machine_startup(void)
1c79356b 261{
55e303ae 262 int boot_arg;
1c79356b 263
55e303ae
A
264#if 0
265 if( PE_get_hotkey( kPEControlKey ))
266 halt_in_debugger = halt_in_debugger ? 0 : 1;
1c79356b
A
267#endif
268
b7266188 269 if (PE_parse_boot_argn("debug", &debug_boot_arg, sizeof (debug_boot_arg))) {
6d2010ae 270 panicDebugging = TRUE;
b7266188
A
271 if (debug_boot_arg & DB_HALT) halt_in_debugger=1;
272 if (debug_boot_arg & DB_PRT) disable_debug_output=FALSE;
273 if (debug_boot_arg & DB_SLOG) systemLogDiags=TRUE;
b7266188 274 if (debug_boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE;
04b8595b
A
275#if KDEBUG_MOJO_TRACE
276 if (debug_boot_arg & DB_PRT_KDEBUG) {
277 kdebug_serial = TRUE;
278 disable_debug_output = FALSE;
279 }
280#endif
b7266188
A
281 } else {
282 debug_boot_arg = 0;
55e303ae 283 }
1c79356b 284
593a1d5f 285 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram, sizeof (commit_paniclog_to_nvram)))
2d21ac55
A
286 commit_paniclog_to_nvram = 1;
287
288 /*
289 * Entering the debugger will put the CPUs into a "safe"
290 * power mode.
291 */
593a1d5f 292 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg, sizeof (boot_arg)))
2d21ac55
A
293 pmsafe_debug = boot_arg;
294
55e303ae
A
295#if NOTYET
296 hw_lock_init(&debugger_lock); /* initialize debugger lock */
6601e61a 297#endif
0c530ab8 298 hw_lock_init(&pbtlock); /* initialize print backtrace lock */
1c79356b 299
593a1d5f 300 if (PE_parse_boot_argn("preempt", &boot_arg, sizeof (boot_arg))) {
55e303ae 301 default_preemption_rate = boot_arg;
1c79356b 302 }
593a1d5f 303 if (PE_parse_boot_argn("unsafe", &boot_arg, sizeof (boot_arg))) {
55e303ae
A
304 max_unsafe_quanta = boot_arg;
305 }
593a1d5f 306 if (PE_parse_boot_argn("poll", &boot_arg, sizeof (boot_arg))) {
55e303ae
A
307 max_poll_quanta = boot_arg;
308 }
593a1d5f 309 if (PE_parse_boot_argn("yield", &boot_arg, sizeof (boot_arg))) {
55e303ae
A
310 sched_poll_yield_shift = boot_arg;
311 }
0c530ab8
A
312/* The I/O port to issue a read from, in the event of a panic. Useful for
313 * triggering logic analyzers.
314 */
593a1d5f 315 if (PE_parse_boot_argn("panic_io_port", &boot_arg, sizeof (boot_arg))) {
0c530ab8
A
316 /*I/O ports range from 0 through 0xFFFF */
317 panic_io_port = boot_arg & 0xffff;
318 }
319
55e303ae
A
320 machine_conf();
321
fe8ab488
A
322 panic_hooks_init();
323
1c79356b
A
324 /*
325 * Start the system.
326 */
91447636
A
327 kernel_bootstrap();
328 /*NOTREACHED*/
1c79356b
A
329}
330
55e303ae
A
331
332static void
333machine_conf(void)
1c79356b 334{
b0d623f7 335 machine_info.memory_size = (typeof(machine_info.memory_size))mem_size;
1c79356b
A
336}
337
0c530ab8
A
338
339extern void *gPEEFIRuntimeServices;
340extern void *gPEEFISystemTable;
341
342/*-
343 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
344 * code or tables extracted from it, as desired without restriction.
345 *
346 * First, the polynomial itself and its table of feedback terms. The
347 * polynomial is
348 * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
349 *
350 * Note that we take it "backwards" and put the highest-order term in
351 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
352 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
353 * the MSB being 1
354 *
355 * Note that the usual hardware shift register implementation, which
356 * is what we're using (we're merely optimizing it by doing eight-bit
357 * chunks at a time) shifts bits into the lowest-order term. In our
358 * implementation, that means shifting towards the right. Why do we
359 * do it this way? Because the calculated CRC must be transmitted in
360 * order from highest-order term to lowest-order term. UARTs transmit
361 * characters in order from LSB to MSB. By storing the CRC this way
362 * we hand it to the UART in the order low-byte to high-byte; the UART
363 * sends each low-bit to hight-bit; and the result is transmission bit
364 * by bit from highest- to lowest-order term without requiring any bit
365 * shuffling on our part. Reception works similarly
366 *
367 * The feedback terms table consists of 256, 32-bit entries. Notes
368 *
369 * The table can be generated at runtime if desired; code to do so
370 * is shown later. It might not be obvious, but the feedback
371 * terms simply represent the results of eight shift/xor opera
372 * tions for all combinations of data and CRC register values
373 *
374 * The values must be right-shifted by eight bits by the "updcrc
375 * logic; the shift must be unsigned (bring in zeroes). On some
376 * hardware you could probably optimize the shift in assembler by
377 * using byte-swap instructions
378 * polynomial $edb88320
379 *
380 *
381 * CRC32 code derived from work by Gary S. Brown.
382 */
383
384static uint32_t crc32_tab[] = {
385 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
386 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
387 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
388 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
389 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
390 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
391 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
392 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
393 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
394 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
395 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
396 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
397 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
398 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
399 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
400 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
401 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
402 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
403 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
404 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
405 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
406 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
407 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
408 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
409 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
410 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
411 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
412 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
413 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
414 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
415 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
416 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
417 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
418 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
419 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
420 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
421 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
422 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
423 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
424 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
425 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
426 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
427 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
428};
429
430static uint32_t
431crc32(uint32_t crc, const void *buf, size_t size)
432{
433 const uint8_t *p;
434
435 p = buf;
436 crc = crc ^ ~0U;
437
438 while (size--)
439 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
440
441 return crc ^ ~0U;
442}
443
444static void
445efi_set_tables_64(EFI_SYSTEM_TABLE_64 * system_table)
446{
447 EFI_RUNTIME_SERVICES_64 *runtime;
448 uint32_t hdr_cksum;
449 uint32_t cksum;
450
6d2010ae 451 DPRINTF("Processing 64-bit EFI tables at %p\n", system_table);
0c530ab8 452 do {
6d2010ae
A
453 DPRINTF("Header:\n");
454 DPRINTF(" Signature: 0x%016llx\n", system_table->Hdr.Signature);
455 DPRINTF(" Revision: 0x%08x\n", system_table->Hdr.Revision);
456 DPRINTF(" HeaderSize: 0x%08x\n", system_table->Hdr.HeaderSize);
457 DPRINTF(" CRC32: 0x%08x\n", system_table->Hdr.CRC32);
458 DPRINTF("RuntimeServices: 0x%016llx\n", system_table->RuntimeServices);
0c530ab8
A
459 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
460 kprintf("Bad EFI system table signature\n");
461 break;
462 }
463 // Verify signature of the system table
464 hdr_cksum = system_table->Hdr.CRC32;
465 system_table->Hdr.CRC32 = 0;
466 cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
467
6d2010ae 468 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
0c530ab8
A
469 system_table->Hdr.CRC32 = hdr_cksum;
470 if (cksum != hdr_cksum) {
471 kprintf("Bad EFI system table checksum\n");
472 break;
473 }
474
b0d623f7
A
475 gPEEFISystemTable = system_table;
476
b0d623f7
A
477 if(system_table->RuntimeServices == 0) {
478 kprintf("No runtime table present\n");
479 break;
480 }
6d2010ae 481 DPRINTF("RuntimeServices table at 0x%qx\n", system_table->RuntimeServices);
b0d623f7
A
482 // 64-bit virtual address is OK for 64-bit EFI and 64/32-bit kernel.
483 runtime = (EFI_RUNTIME_SERVICES_64 *) (uintptr_t)system_table->RuntimeServices;
6d2010ae 484 DPRINTF("Checking runtime services table %p\n", runtime);
b0d623f7
A
485 if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
486 kprintf("Bad EFI runtime table signature\n");
487 break;
488 }
0c530ab8
A
489
490 // Verify signature of runtime services table
491 hdr_cksum = runtime->Hdr.CRC32;
492 runtime->Hdr.CRC32 = 0;
493 cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
494
6d2010ae 495 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
0c530ab8
A
496 runtime->Hdr.CRC32 = hdr_cksum;
497 if (cksum != hdr_cksum) {
498 kprintf("Bad EFI runtime table checksum\n");
499 break;
500 }
501
502 gPEEFIRuntimeServices = runtime;
503 }
504 while (FALSE);
505}
506
507static void
b0d623f7 508efi_set_tables_32(EFI_SYSTEM_TABLE_32 * system_table)
0c530ab8 509{
b0d623f7 510 EFI_RUNTIME_SERVICES_32 *runtime;
0c530ab8
A
511 uint32_t hdr_cksum;
512 uint32_t cksum;
513
6d2010ae 514 DPRINTF("Processing 32-bit EFI tables at %p\n", system_table);
0c530ab8 515 do {
6d2010ae
A
516 DPRINTF("Header:\n");
517 DPRINTF(" Signature: 0x%016llx\n", system_table->Hdr.Signature);
518 DPRINTF(" Revision: 0x%08x\n", system_table->Hdr.Revision);
519 DPRINTF(" HeaderSize: 0x%08x\n", system_table->Hdr.HeaderSize);
520 DPRINTF(" CRC32: 0x%08x\n", system_table->Hdr.CRC32);
521 DPRINTF("RuntimeServices: 0x%08x\n", system_table->RuntimeServices);
0c530ab8 522 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
b0d623f7 523 kprintf("Bad EFI system table signature\n");
0c530ab8
A
524 break;
525 }
526 // Verify signature of the system table
527 hdr_cksum = system_table->Hdr.CRC32;
528 system_table->Hdr.CRC32 = 0;
6d2010ae 529 DPRINTF("System table at %p HeaderSize 0x%x\n", system_table, system_table->Hdr.HeaderSize);
0c530ab8
A
530 cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
531
6d2010ae 532 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
0c530ab8
A
533 system_table->Hdr.CRC32 = hdr_cksum;
534 if (cksum != hdr_cksum) {
535 kprintf("Bad EFI system table checksum\n");
536 break;
537 }
538
b0d623f7 539 gPEEFISystemTable = system_table;
0c530ab8 540
b0d623f7
A
541 if(system_table->RuntimeServices == 0) {
542 kprintf("No runtime table present\n");
543 break;
544 }
6d2010ae 545 DPRINTF("RuntimeServices table at 0x%x\n", system_table->RuntimeServices);
b0d623f7 546 // 32-bit virtual address is OK for 32-bit EFI and 32-bit kernel.
6d2010ae
A
547 // For a 64-bit kernel, booter provides a virtual address mod 4G
548 runtime = (EFI_RUNTIME_SERVICES_32 *)
6d2010ae 549 (system_table->RuntimeServices | VM_MIN_KERNEL_ADDRESS);
6d2010ae 550 DPRINTF("Runtime table addressed at %p\n", runtime);
b0d623f7
A
551 if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
552 kprintf("Bad EFI runtime table signature\n");
553 break;
554 }
0c530ab8
A
555
556 // Verify signature of runtime services table
557 hdr_cksum = runtime->Hdr.CRC32;
558 runtime->Hdr.CRC32 = 0;
559 cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
560
6d2010ae 561 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
0c530ab8
A
562 runtime->Hdr.CRC32 = hdr_cksum;
563 if (cksum != hdr_cksum) {
564 kprintf("Bad EFI runtime table checksum\n");
565 break;
566 }
567
6d2010ae
A
568 DPRINTF("Runtime functions\n");
569 DPRINTF(" GetTime : 0x%x\n", runtime->GetTime);
570 DPRINTF(" SetTime : 0x%x\n", runtime->SetTime);
571 DPRINTF(" GetWakeupTime : 0x%x\n", runtime->GetWakeupTime);
572 DPRINTF(" SetWakeupTime : 0x%x\n", runtime->SetWakeupTime);
573 DPRINTF(" SetVirtualAddressMap : 0x%x\n", runtime->SetVirtualAddressMap);
574 DPRINTF(" ConvertPointer : 0x%x\n", runtime->ConvertPointer);
575 DPRINTF(" GetVariable : 0x%x\n", runtime->GetVariable);
576 DPRINTF(" GetNextVariableName : 0x%x\n", runtime->GetNextVariableName);
577 DPRINTF(" SetVariable : 0x%x\n", runtime->SetVariable);
578 DPRINTF(" GetNextHighMonotonicCount: 0x%x\n", runtime->GetNextHighMonotonicCount);
579 DPRINTF(" ResetSystem : 0x%x\n", runtime->ResetSystem);
580
0c530ab8
A
581 gPEEFIRuntimeServices = runtime;
582 }
583 while (FALSE);
584}
585
586
587/* Map in EFI runtime areas. */
588static void
589efi_init(void)
590{
591 boot_args *args = (boot_args *)PE_state.bootArgs;
592
593 kprintf("Initializing EFI runtime services\n");
594
595 do
596 {
2d21ac55 597 vm_offset_t vm_size, vm_addr;
0c530ab8
A
598 vm_map_offset_t phys_addr;
599 EfiMemoryRange *mptr;
600 unsigned int msize, mcount;
601 unsigned int i;
602
603 msize = args->MemoryMapDescriptorSize;
604 mcount = args->MemoryMapSize / msize;
605
6d2010ae
A
606 DPRINTF("efi_init() kernel base: 0x%x size: 0x%x\n",
607 args->kaddr, args->ksize);
608 DPRINTF(" efiSystemTable physical: 0x%x virtual: %p\n",
609 args->efiSystemTable,
610 (void *) ml_static_ptovirt(args->efiSystemTable));
611 DPRINTF(" efiRuntimeServicesPageStart: 0x%x\n",
612 args->efiRuntimeServicesPageStart);
613 DPRINTF(" efiRuntimeServicesPageCount: 0x%x\n",
614 args->efiRuntimeServicesPageCount);
615 DPRINTF(" efiRuntimeServicesVirtualPageStart: 0x%016llx\n",
616 args->efiRuntimeServicesVirtualPageStart);
b0d623f7 617 mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
0c530ab8
A
618 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
619 if (((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) ) {
b0d623f7 620 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
0c530ab8 621 vm_addr = (vm_offset_t) mptr->VirtualStart;
6d2010ae
A
622 /* For K64 on EFI32, shadow-map into high KVA */
623 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
624 vm_addr |= VM_MIN_KERNEL_ADDRESS;
6d2010ae
A
625 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
626 DPRINTF(" Type: %x phys: %p EFIv: %p kv: %p size: %p\n",
627 mptr->Type,
628 (void *) (uintptr_t) phys_addr,
629 (void *) (uintptr_t) mptr->VirtualStart,
630 (void *) vm_addr,
631 (void *) vm_size);
7ddcb079 632 pmap_map_bd(vm_addr, phys_addr, phys_addr + round_page(vm_size),
0c530ab8
A
633 (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
634 (mptr->Type == EfiMemoryMappedIO) ? VM_WIMG_IO : VM_WIMG_USE_DEFAULT);
635 }
636 }
637
6d2010ae 638 if (args->Version != kBootArgsVersion2)
b0d623f7 639 panic("Incompatible boot args version %d revision %d\n", args->Version, args->Revision);
0c530ab8 640
7ddcb079 641 DPRINTF("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
b0d623f7
A
642 if (args->efiMode == kBootArgsEfiMode64) {
643 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) ml_static_ptovirt(args->efiSystemTable));
0c530ab8 644 } else {
b0d623f7 645 efi_set_tables_32((EFI_SYSTEM_TABLE_32 *) ml_static_ptovirt(args->efiSystemTable));
0c530ab8
A
646 }
647 }
648 while (FALSE);
649
650 return;
651}
652
653/* Remap EFI runtime areas. */
654void
655hibernate_newruntime_map(void * map, vm_size_t map_size, uint32_t system_table_offset)
656{
657 boot_args *args = (boot_args *)PE_state.bootArgs;
658
659 kprintf("Reinitializing EFI runtime services\n");
660
0c530ab8
A
661 do
662 {
2d21ac55 663 vm_offset_t vm_size, vm_addr;
0c530ab8
A
664 vm_map_offset_t phys_addr;
665 EfiMemoryRange *mptr;
666 unsigned int msize, mcount;
667 unsigned int i;
668
669 gPEEFISystemTable = 0;
670 gPEEFIRuntimeServices = 0;
671
672 system_table_offset += ptoa_32(args->efiRuntimeServicesPageStart);
673
2d21ac55
A
674 kprintf("Old system table 0x%x, new 0x%x\n",
675 (uint32_t)args->efiSystemTable, system_table_offset);
0c530ab8 676
2d21ac55 677 args->efiSystemTable = system_table_offset;
0c530ab8
A
678
679 kprintf("Old map:\n");
680 msize = args->MemoryMapDescriptorSize;
681 mcount = args->MemoryMapSize / msize;
b0d623f7 682 mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
0c530ab8
A
683 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
684 if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
685
b0d623f7 686 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
0c530ab8 687 vm_addr = (vm_offset_t) mptr->VirtualStart;
6d2010ae
A
688 /* K64 on EFI32 */
689 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
690 vm_addr |= VM_MIN_KERNEL_ADDRESS;
0c530ab8
A
691 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
692
b0d623f7 693 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr->Type, phys_addr, (unsigned long)vm_addr, mptr->NumberOfPages);
0c530ab8
A
694 }
695 }
696
697 pmap_remove(kernel_pmap, i386_ptob(args->efiRuntimeServicesPageStart),
698 i386_ptob(args->efiRuntimeServicesPageStart + args->efiRuntimeServicesPageCount));
699
700 kprintf("New map:\n");
701 msize = args->MemoryMapDescriptorSize;
b0d623f7 702 mcount = (unsigned int )(map_size / msize);
0c530ab8
A
703 mptr = map;
704 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
705 if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
706
b0d623f7 707 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
0c530ab8 708 vm_addr = (vm_offset_t) mptr->VirtualStart;
6d2010ae
A
709 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
710 vm_addr |= VM_MIN_KERNEL_ADDRESS;
0c530ab8
A
711 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
712
b0d623f7 713 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr->Type, phys_addr, (unsigned long)vm_addr, mptr->NumberOfPages);
0c530ab8 714
6d2010ae 715 pmap_map(vm_addr, phys_addr, phys_addr + round_page(vm_size),
0c530ab8
A
716 (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
717 (mptr->Type == EfiMemoryMappedIO) ? VM_WIMG_IO : VM_WIMG_USE_DEFAULT);
718 }
719 }
720
6d2010ae 721 if (args->Version != kBootArgsVersion2)
b0d623f7 722 panic("Incompatible boot args version %d revision %d\n", args->Version, args->Revision);
0c530ab8
A
723
724 kprintf("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
b0d623f7
A
725 if (args->efiMode == kBootArgsEfiMode64) {
726 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) ml_static_ptovirt(args->efiSystemTable));
0c530ab8 727 } else {
b0d623f7 728 efi_set_tables_32((EFI_SYSTEM_TABLE_32 *) ml_static_ptovirt(args->efiSystemTable));
0c530ab8
A
729 }
730 }
731 while (FALSE);
732
733 kprintf("Done reinitializing EFI runtime services\n");
734
735 return;
736}
737
1c79356b
A
738/*
739 * Find devices. The system is alive.
740 */
741void
742machine_init(void)
743{
316670eb
A
744 /* Now with VM up, switch to dynamically allocated cpu data */
745 cpu_data_realloc();
316670eb 746
0c530ab8
A
747 /* Ensure panic buffer is initialized. */
748 debug_log_init();
749
1c79356b
A
750 /*
751 * Display CPU identification
752 */
0c530ab8
A
753 cpuid_cpu_display("CPU identification");
754 cpuid_feature_display("CPU features");
755 cpuid_extfeature_display("CPU extended features");
1c79356b 756
0c530ab8
A
757 /*
758 * Initialize EFI runtime services.
759 */
760 efi_init();
55e303ae 761
55e303ae 762 smp_init();
1c79356b
A
763
764 /*
765 * Set up to use floating point.
766 */
767 init_fpu();
768
1c79356b
A
769 /*
770 * Configure clock devices.
771 */
772 clock_config();
91447636 773
6d2010ae 774#if CONFIG_MTRR
91447636
A
775 /*
776 * Initialize MTRR from boot processor.
777 */
778 mtrr_init();
779
780 /*
781 * Set up PAT for boot processor.
782 */
783 pat_init();
6d2010ae 784#endif
91447636
A
785
786 /*
b0d623f7 787 * Free lowmem pages and complete other setup
91447636 788 */
b0d623f7 789 pmap_lowmem_finalize();
1c79356b
A
790}
791
792/*
793 * Halt a cpu.
794 */
795void
796halt_cpu(void)
797{
798 halt_all_cpus(FALSE);
799}
800
801int reset_mem_on_reboot = 1;
802
803/*
804 * Halt the system or reboot.
805 */
806void
9bccf70c 807halt_all_cpus(boolean_t reboot)
1c79356b 808{
55e303ae 809 if (reboot) {
55e303ae
A
810 printf("MACH Reboot\n");
811 PEHaltRestart( kPERestartCPU );
812 } else {
813 printf("CPU halted\n");
814 PEHaltRestart( kPEHaltCPU );
1c79356b 815 }
55e303ae 816 while(1);
1c79356b
A
817}
818
2d21ac55 819
0c530ab8
A
820/* Issue an I/O port read if one has been requested - this is an event logic
821 * analyzers can use as a trigger point.
822 */
823
824void
825panic_io_port_read(void) {
826 if (panic_io_port)
827 (void)inb(panic_io_port);
828}
829
830/* For use with the MP rendezvous mechanism
831 */
832
6d2010ae
A
833uint64_t panic_restart_timeout = ~(0ULL);
834
13f56ec4
A
835#define PANIC_RESTART_TIMEOUT (3ULL * NSEC_PER_SEC)
836
0c530ab8 837static void
6d2010ae 838machine_halt_cpu(void) {
13f56ec4
A
839 uint64_t deadline;
840
0c530ab8 841 panic_io_port_read();
6d2010ae 842
13f56ec4
A
843 /* Halt here forever if we're not rebooting */
844 if (!PE_reboot_on_panic() && panic_restart_timeout == ~(0ULL)) {
845 pmCPUHalt(PM_HALT_DEBUG);
846 return;
6d2010ae 847 }
13f56ec4
A
848
849 if (PE_reboot_on_panic())
850 deadline = mach_absolute_time() + PANIC_RESTART_TIMEOUT;
851 else
852 deadline = mach_absolute_time() + panic_restart_timeout;
853
854 while (mach_absolute_time() < deadline)
855 cpu_pause();
856
857 kprintf("Invoking PE_halt_restart\n");
858 /* Attempt restart via ACPI RESET_REG; at the time of this
859 * writing, this is routine is chained through AppleSMC->
860 * AppleACPIPlatform
861 */
13f56ec4
A
862 if (PE_halt_restart)
863 (*PE_halt_restart)(kPERestartCPU);
2d21ac55 864 pmCPUHalt(PM_HALT_DEBUG);
1c79356b
A
865}
866
04b8595b
A
867static int pid_from_task(task_t task)
868{
869 int pid = -1;
870
871 if (task->bsd_info)
872 pid = proc_pid(task->bsd_info);
873
874 return pid;
875}
876
316670eb
A
877void
878DebuggerWithContext(
879 __unused unsigned int reason,
880 __unused void *ctx,
881 const char *message)
882{
883 Debugger(message);
884}
885
1c79356b
A
886void
887Debugger(
888 const char *message)
889{
0c530ab8
A
890 unsigned long pi_size = 0;
891 void *stackptr;
6d2010ae 892 int cn = cpu_number();
04b8595b
A
893 task_t task = current_task();
894 int task_pid = pid_from_task(task);
895
91447636 896
0c530ab8 897 hw_atomic_add(&debug_mode, 1);
91447636
A
898 if (!panic_is_inited) {
899 postcode(PANIC_HLT);
900 asm("hlt");
901 }
902
1c79356b 903 printf("Debugger called: <%s>\n", message);
91447636 904 kprintf("Debugger called: <%s>\n", message);
1c79356b 905
0c530ab8
A
906 /*
907 * Skip the graphical panic box if no panic string.
908 * This is the case if we're being called from
909 * host_reboot(,HOST_REBOOT_DEBUGGER)
910 * as a quiet way into the debugger.
911 */
912
913 if (panicstr) {
914 disable_preemption();
915
916/* Issue an I/O port read if one has been requested - this is an event logic
917 * analyzers can use as a trigger point.
918 */
919 panic_io_port_read();
920
921 /* Obtain current frame pointer */
b0d623f7 922 __asm__ volatile("movq %%rbp, %0" : "=m" (stackptr));
0c530ab8
A
923
924 /* Print backtrace - callee is internally synchronized */
04b8595b
A
925 if ((task_pid == 1) && (init_task_died)) {
926 /* Special handling of launchd died panics */
927 print_launchd_info();
928 } else {
929 panic_i386_backtrace(stackptr, ((panic_double_fault_cpu == cn) ? 80: 48), NULL, FALSE, NULL);
930 }
0c530ab8
A
931
932 /* everything should be printed now so copy to NVRAM
933 */
934
935 if( debug_buf_size > 0) {
2d21ac55
A
936 /* Optionally sync the panic log, if any, to NVRAM
937 * This is the default.
938 */
939 if (commit_paniclog_to_nvram) {
0c530ab8 940 unsigned int bufpos;
935ed37a 941 uintptr_t cr0;
b0d623f7
A
942
943 debug_putc(0);
0c530ab8
A
944
945 /* Now call the compressor */
946 /* XXX Consider using the WKdm compressor in the
947 * future, rather than just packing - would need to
948 * be co-ordinated with crashreporter, which decodes
2d21ac55
A
949 * this post-restart. The compressor should be
950 * capable of in-place compression.
0c530ab8 951 */
2d21ac55
A
952 bufpos = packA(debug_buf,
953 (unsigned int) (debug_buf_ptr - debug_buf), debug_buf_size);
0c530ab8
A
954 /* If compression was successful,
955 * use the compressed length
956 */
2d21ac55
A
957 pi_size = bufpos ? bufpos : (unsigned) (debug_buf_ptr - debug_buf);
958
0c530ab8
A
959 /* Save panic log to non-volatile store
960 * Panic info handler must truncate data that is
961 * too long for this platform.
962 * This call must save data synchronously,
963 * since we can subsequently halt the system.
964 */
b0d623f7 965
6d2010ae 966
935ed37a
A
967/* The following sequence is a workaround for:
968 * <rdar://problem/5915669> SnowLeopard10A67: AppleEFINVRAM should not invoke
969 * any routines that use floating point (MMX in this case) when saving panic
970 * logs to nvram/flash.
971 */
972 cr0 = get_cr0();
973 clear_ts();
6d2010ae
A
974
975 kprintf("Attempting to commit panic log to NVRAM\n");
b0d623f7
A
976 pi_size = PESavePanicInfo((unsigned char *)debug_buf,
977 (uint32_t)pi_size );
935ed37a 978 set_cr0(cr0);
6d2010ae 979
2d21ac55
A
980 /* Uncompress in-place, to permit examination of
981 * the panic log by debuggers.
982 */
983
984 if (bufpos) {
985 unpackA(debug_buf, bufpos);
986 }
0c530ab8
A
987 }
988 }
b7266188 989
0c530ab8 990 if (!panicDebugging) {
6d2010ae 991 unsigned cnum;
0c530ab8
A
992 /* Clear the MP rendezvous function lock, in the event
993 * that a panic occurred while in that codepath.
994 */
995 mp_rendezvous_break_lock();
b7266188 996
6d2010ae
A
997 /* Non-maskably interrupt all other processors
998 * If a restart timeout is specified, this processor
999 * will attempt a restart.
0c530ab8 1000 */
6d2010ae
A
1001 kprintf("Invoking machine_halt_cpu on CPU %d\n", cn);
1002 for (cnum = 0; cnum < real_ncpus; cnum++) {
1003 if (cnum != (unsigned) cn) {
1004 cpu_NMI_interrupt(cnum);
1005 }
1006 }
1007 machine_halt_cpu();
0c530ab8
A
1008 /* NOT REACHED */
1009 }
1010 }
55e303ae 1011
1c79356b 1012 __asm__("int3");
0c530ab8 1013 hw_atomic_sub(&debug_mode, 1);
1c79356b
A
1014}
1015
1c79356b 1016char *
91447636 1017machine_boot_info(char *buf, __unused vm_size_t size)
1c79356b
A
1018{
1019 *buf ='\0';
1020 return buf;
1021}
1022
0c530ab8
A
1023/* Routines for address - symbol translation. Not called unless the "keepsyms"
1024 * boot-arg is supplied.
1025 */
1026
1027static int
6d2010ae 1028panic_print_macho_symbol_name(kernel_mach_header_t *mh, vm_address_t search, const char *module_name)
0c530ab8 1029{
b0d623f7 1030 kernel_nlist_t *sym = NULL;
0c530ab8 1031 struct load_command *cmd;
b0d623f7 1032 kernel_segment_command_t *orig_ts = NULL, *orig_le = NULL;
0c530ab8
A
1033 struct symtab_command *orig_st = NULL;
1034 unsigned int i;
1035 char *strings, *bestsym = NULL;
1036 vm_address_t bestaddr = 0, diff, curdiff;
b0d623f7
A
1037
1038 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
0c530ab8
A
1039
1040 cmd = (struct load_command *) &mh[1];
1041 for (i = 0; i < mh->ncmds; i++) {
b0d623f7
A
1042 if (cmd->cmd == LC_SEGMENT_KERNEL) {
1043 kernel_segment_command_t *orig_sg = (kernel_segment_command_t *) cmd;
0c530ab8 1044
2d21ac55
A
1045 if (strncmp(SEG_TEXT, orig_sg->segname,
1046 sizeof(orig_sg->segname)) == 0)
0c530ab8 1047 orig_ts = orig_sg;
2d21ac55
A
1048 else if (strncmp(SEG_LINKEDIT, orig_sg->segname,
1049 sizeof(orig_sg->segname)) == 0)
0c530ab8 1050 orig_le = orig_sg;
2d21ac55
A
1051 else if (strncmp("", orig_sg->segname,
1052 sizeof(orig_sg->segname)) == 0)
7ee9d059 1053 orig_ts = orig_sg; /* pre-Lion i386 kexts have a single unnamed segment */
0c530ab8
A
1054 }
1055 else if (cmd->cmd == LC_SYMTAB)
1056 orig_st = (struct symtab_command *) cmd;
1057
b0d623f7 1058 cmd = (struct load_command *) ((uintptr_t) cmd + cmd->cmdsize);
0c530ab8
A
1059 }
1060
1061 if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL))
1062 return 0;
1063
0c530ab8
A
1064 if ((search < orig_ts->vmaddr) ||
1065 (search >= orig_ts->vmaddr + orig_ts->vmsize)) {
1066 /* search out of range for this mach header */
1067 return 0;
1068 }
1069
b0d623f7
A
1070 sym = (kernel_nlist_t *)(uintptr_t)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff);
1071 strings = (char *)(uintptr_t)(orig_le->vmaddr + orig_st->stroff - orig_le->fileoff);
0c530ab8
A
1072 diff = search;
1073
1074 for (i = 0; i < orig_st->nsyms; i++) {
b0d623f7
A
1075 if (sym[i].n_type & N_STAB) continue;
1076
0c530ab8
A
1077 if (sym[i].n_value <= search) {
1078 curdiff = search - (vm_address_t)sym[i].n_value;
1079 if (curdiff < diff) {
1080 diff = curdiff;
1081 bestaddr = sym[i].n_value;
1082 bestsym = strings + sym[i].n_un.n_strx;
1083 }
1084 }
1085 }
1086
1087 if (bestsym != NULL) {
1088 if (diff != 0) {
6d2010ae 1089 kdb_printf("%s : %s + 0x%lx", module_name, bestsym, (unsigned long)diff);
0c530ab8 1090 } else {
6d2010ae 1091 kdb_printf("%s : %s", module_name, bestsym);
0c530ab8
A
1092 }
1093 return 1;
1094 }
1095 return 0;
1096}
1097
1098extern kmod_info_t * kmod; /* the list of modules */
1099
1100static void
1101panic_print_kmod_symbol_name(vm_address_t search)
1102{
6d2010ae
A
1103 u_int i;
1104
1105 if (gLoadedKextSummaries == NULL)
1106 return;
1107 for (i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
1108 OSKextLoadedKextSummary *summary = gLoadedKextSummaries->summaries + i;
1109
1110 if ((search >= summary->address) &&
1111 (search < (summary->address + summary->size)))
1112 {
1113 kernel_mach_header_t *header = (kernel_mach_header_t *)(uintptr_t) summary->address;
1114 if (panic_print_macho_symbol_name(header, search, summary->name) == 0) {
1115 kdb_printf("%s + %llu", summary->name, (unsigned long)search - summary->address);
1116 }
0c530ab8 1117 break;
6d2010ae 1118 }
0c530ab8
A
1119 }
1120}
1121
04b8595b 1122void
0c530ab8
A
1123panic_print_symbol_name(vm_address_t search)
1124{
1125 /* try searching in the kernel */
6d2010ae 1126 if (panic_print_macho_symbol_name(&_mh_execute_header, search, "mach_kernel") == 0) {
0c530ab8
A
1127 /* that failed, now try to search for the right kext */
1128 panic_print_kmod_symbol_name(search);
1129 }
1130}
1131
1132/* Generate a backtrace, given a frame pointer - this routine
1133 * should walk the stack safely. The trace is appended to the panic log
1134 * and conditionally, to the console. If the trace contains kernel module
1135 * addresses, display the module name, load address and dependencies.
1136 */
1137
1138#define DUMPFRAMES 32
1139#define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
1140void
935ed37a 1141panic_i386_backtrace(void *_frame, int nframes, const char *msg, boolean_t regdump, x86_saved_state_t *regs)
0c530ab8
A
1142{
1143 cframe_t *frame = (cframe_t *)_frame;
1144 vm_offset_t raddrs[DUMPFRAMES];
935ed37a 1145 vm_offset_t PC = 0;
0c530ab8
A
1146 int frame_index;
1147 volatile uint32_t *ppbtcnt = &pbtcnt;
1148 uint64_t bt_tsc_timeout;
1149 boolean_t keepsyms = FALSE;
6d2010ae 1150 int cn = cpu_number();
0c530ab8 1151
6d2010ae 1152 if(pbtcpu != cn) {
0c530ab8
A
1153 hw_atomic_add(&pbtcnt, 1);
1154 /* Spin on print backtrace lock, which serializes output
1155 * Continue anyway if a timeout occurs.
1156 */
39236c6e 1157 hw_lock_to(&pbtlock, ~0U);
6d2010ae 1158 pbtcpu = cn;
0c530ab8
A
1159 }
1160
fe8ab488
A
1161 panic_check_hook();
1162
593a1d5f 1163 PE_parse_boot_argn("keepsyms", &keepsyms, sizeof (keepsyms));
0c530ab8 1164
935ed37a 1165 if (msg != NULL) {
b0d623f7 1166 kdb_printf("%s", msg);
935ed37a
A
1167 }
1168
1169 if ((regdump == TRUE) && (regs != NULL)) {
b0d623f7
A
1170 x86_saved_state64_t *ss64p = saved_state64(regs);
1171 kdb_printf(
1172 "RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1173 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1174 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1175 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1176 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n",
1177 ss64p->rax, ss64p->rbx, ss64p->rcx, ss64p->rdx,
1178 ss64p->isf.rsp, ss64p->rbp, ss64p->rsi, ss64p->rdi,
1179 ss64p->r8, ss64p->r9, ss64p->r10, ss64p->r11,
1180 ss64p->r12, ss64p->r13, ss64p->r14, ss64p->r15,
1181 ss64p->isf.rflags, ss64p->isf.rip, ss64p->isf.cs,
1182 ss64p->isf.ss);
1183 PC = ss64p->isf.rip;
935ed37a
A
1184 }
1185
1186 kdb_printf("Backtrace (CPU %d), "
b0d623f7 1187#if PRINT_ARGS_FROM_STACK_FRAME
6d2010ae 1188 "Frame : Return Address (4 potential args on stack)\n", cn);
b0d623f7 1189#else
6d2010ae 1190 "Frame : Return Address\n", cn);
b0d623f7 1191#endif
0c530ab8
A
1192
1193 for (frame_index = 0; frame_index < nframes; frame_index++) {
1194 vm_offset_t curframep = (vm_offset_t) frame;
1195
1196 if (!curframep)
1197 break;
1198
1199 if (curframep & 0x3) {
1200 kdb_printf("Unaligned frame\n");
1201 goto invalid;
1202 }
1203
1204 if (!kvtophys(curframep) ||
6d2010ae 1205 !kvtophys(curframep + sizeof(cframe_t) - 1)) {
0c530ab8
A
1206 kdb_printf("No mapping exists for frame pointer\n");
1207 goto invalid;
1208 }
1209
b0d623f7 1210 kdb_printf("%p : 0x%lx ", frame, frame->caller);
0c530ab8
A
1211 if (frame_index < DUMPFRAMES)
1212 raddrs[frame_index] = frame->caller;
1213
b0d623f7 1214#if PRINT_ARGS_FROM_STACK_FRAME
0c530ab8 1215 if (kvtophys((vm_offset_t)&(frame->args[3])))
b0d623f7 1216 kdb_printf("(0x%x 0x%x 0x%x 0x%x) ",
0c530ab8
A
1217 frame->args[0], frame->args[1],
1218 frame->args[2], frame->args[3]);
b0d623f7 1219#endif
0c530ab8
A
1220
1221 /* Display address-symbol translation only if the "keepsyms"
1222 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1223 * This routine is potentially unsafe; also, function
1224 * boundary identification is unreliable after a strip -x.
1225 */
1226 if (keepsyms)
1227 panic_print_symbol_name((vm_address_t)frame->caller);
1228
b0d623f7
A
1229 kdb_printf("\n");
1230
0c530ab8
A
1231 frame = frame->prev;
1232 }
1233
1234 if (frame_index >= nframes)
1235 kdb_printf("\tBacktrace continues...\n");
1236
1237 goto out;
1238
1239invalid:
2d21ac55 1240 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame);
0c530ab8
A
1241out:
1242
1243 /* Identify kernel modules in the backtrace and display their
1244 * load addresses and dependencies. This routine should walk
1245 * the kmod list safely.
1246 */
1247 if (frame_index)
b0d623f7 1248 kmod_panic_dump((vm_offset_t *)&raddrs[0], frame_index);
0c530ab8 1249
935ed37a 1250 if (PC != 0)
b0d623f7 1251 kmod_panic_dump(&PC, 1);
935ed37a 1252
2d21ac55 1253 panic_display_system_configuration();
c910b4d9 1254
0c530ab8
A
1255 /* Release print backtrace lock, to permit other callers in the
1256 * event of panics on multiple processors.
1257 */
1258 hw_lock_unlock(&pbtlock);
1259 hw_atomic_sub(&pbtcnt, 1);
1260 /* Wait for other processors to complete output
1261 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1262 */
1263 bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
1264 while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
1265}
04b8595b
A
1266
1267static boolean_t
1268debug_copyin(pmap_t p, uint64_t uaddr, void *dest, size_t size)
1269{
1270 size_t rem = size;
1271 char *kvaddr = dest;
1272
1273 while (rem) {
1274 ppnum_t upn = pmap_find_phys(p, uaddr);
1275 uint64_t phys_src = ptoa_64(upn) | (uaddr & PAGE_MASK);
1276 uint64_t phys_dest = kvtophys((vm_offset_t)kvaddr);
1277 uint64_t src_rem = PAGE_SIZE - (phys_src & PAGE_MASK);
1278 uint64_t dst_rem = PAGE_SIZE - (phys_dest & PAGE_MASK);
1279 size_t cur_size = (uint32_t) MIN(src_rem, dst_rem);
1280 cur_size = MIN(cur_size, rem);
1281
1282 if (upn && pmap_valid_page(upn) && phys_dest) {
1283 bcopy_phys(phys_src, phys_dest, cur_size);
1284 }
1285 else
1286 break;
1287 uaddr += cur_size;
1288 kvaddr += cur_size;
1289 rem -= cur_size;
1290 }
1291 return (rem == 0);
1292}
1293
1294void
1295print_threads_registers(thread_t thread)
1296{
1297 x86_saved_state_t *savestate;
1298
1299 savestate = get_user_regs(thread);
1300 kdb_printf(
1301 "\nRAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1302 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1303 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1304 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1305 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n\n",
1306 savestate->ss_64.rax, savestate->ss_64.rbx, savestate->ss_64.rcx, savestate->ss_64.rdx,
1307 savestate->ss_64.isf.rsp, savestate->ss_64.rbp, savestate->ss_64.rsi, savestate->ss_64.rdi,
1308 savestate->ss_64.r8, savestate->ss_64.r9, savestate->ss_64.r10, savestate->ss_64.r11,
1309 savestate->ss_64.r12, savestate->ss_64.r13, savestate->ss_64.r14, savestate->ss_64.r15,
1310 savestate->ss_64.isf.rflags, savestate->ss_64.isf.rip, savestate->ss_64.isf.cs,
1311 savestate->ss_64.isf.ss);
1312}
1313
1314void
1315print_tasks_user_threads(task_t task)
1316{
1317 thread_t thread = current_thread();
1318 x86_saved_state_t *savestate;
1319 pmap_t pmap = 0;
1320 uint64_t rbp;
1321 const char *cur_marker = 0;
1322 int j;
1323
1324 for (j = 0, thread = (thread_t) queue_first(&task->threads); j < task->thread_count;
1325 ++j, thread = (thread_t) queue_next(&thread->task_threads)) {
1326
1327 kdb_printf("Thread %p\n", thread);
1328 pmap = get_task_pmap(task);
1329 savestate = get_user_regs(thread);
1330 rbp = savestate->ss_64.rbp;
1331 print_one_backtrace(pmap, (vm_offset_t)rbp, cur_marker, TRUE, TRUE);
1332 kdb_printf("\n");
1333 }
1334}
1335
1336#define PANICLOG_UUID_BUF_SIZE 256
1337
1338void print_uuid_info(task_t task)
1339{
1340 uint32_t uuid_info_count = 0;
1341 mach_vm_address_t uuid_info_addr = 0;
1342 boolean_t have_map = (task->map != NULL) && (ml_validate_nofault((vm_offset_t)(task->map), sizeof(struct _vm_map)));
1343 boolean_t have_pmap = have_map && (task->map->pmap != NULL) && (ml_validate_nofault((vm_offset_t)(task->map->pmap), sizeof(struct pmap)));
1344 int task_pid = pid_from_task(task);
1345 char uuidbuf[PANICLOG_UUID_BUF_SIZE] = {0};
1346 char *uuidbufptr = uuidbuf;
1347 uint32_t k;
1348
1349 if (have_pmap && task->active && task_pid > 0) {
1350 /* Read dyld_all_image_infos struct from task memory to get UUID array count & location */
1351 struct user64_dyld_all_image_infos task_image_infos;
1352 if (debug_copyin(task->map->pmap, task->all_image_info_addr,
1353 &task_image_infos, sizeof(struct user64_dyld_all_image_infos))) {
1354 uuid_info_count = (uint32_t)task_image_infos.uuidArrayCount;
1355 uuid_info_addr = task_image_infos.uuidArray;
1356 }
1357
1358 /* If we get a NULL uuid_info_addr (which can happen when we catch dyld
1359 * in the middle of updating this data structure), we zero the
1360 * uuid_info_count so that we won't even try to save load info for this task
1361 */
1362 if (!uuid_info_addr) {
1363 uuid_info_count = 0;
1364 }
1365 }
1366
1367 if (task_pid > 0 && uuid_info_count > 0) {
1368 uint32_t uuid_info_size = sizeof(struct user64_dyld_uuid_info);
1369 uint32_t uuid_array_size = uuid_info_count * uuid_info_size;
1370 uint32_t uuid_copy_size = 0;
1371 uint32_t uuid_image_count = 0;
1372 char *current_uuid_buffer = NULL;
1373 /* Copy in the UUID info array. It may be nonresident, in which case just fix up nloadinfos to 0 */
1374
1375 kdb_printf("\nuuid info:\n");
1376 while (uuid_array_size) {
1377 if (uuid_array_size <= PANICLOG_UUID_BUF_SIZE) {
1378 uuid_copy_size = uuid_array_size;
1379 uuid_image_count = uuid_array_size/uuid_info_size;
1380 } else {
1381 uuid_image_count = PANICLOG_UUID_BUF_SIZE/uuid_info_size;
1382 uuid_copy_size = uuid_image_count * uuid_info_size;
1383 }
1384 if (have_pmap && !debug_copyin(task->map->pmap, uuid_info_addr, uuidbufptr,
1385 uuid_copy_size)) {
1386 kdb_printf("Error!! Failed to copy UUID info for task %p pid %d\n", task, task_pid);
1387 uuid_image_count = 0;
1388 break;
1389 }
1390
1391 if (uuid_image_count > 0) {
1392 current_uuid_buffer = uuidbufptr;
1393 for (k = 0; k < uuid_image_count; k++) {
1394 kdb_printf(" %#llx", *(uint64_t *)current_uuid_buffer);
1395 current_uuid_buffer += sizeof(uint64_t);
1396 uint8_t *uuid = (uint8_t *)current_uuid_buffer;
1397 kdb_printf("\tuuid = <%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x>\n",
1398 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8],
1399 uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
1400 current_uuid_buffer += 16;
1401 }
1402 bzero(&uuidbuf, sizeof(uuidbuf));
1403 }
1404 uuid_info_addr += uuid_copy_size;
1405 uuid_array_size -= uuid_copy_size;
1406 }
1407 }
1408}
1409
1410void print_launchd_info(void)
1411{
1412 task_t task = current_task();
1413 thread_t thread = current_thread();
1414 volatile uint32_t *ppbtcnt = &pbtcnt;
1415 uint64_t bt_tsc_timeout;
1416 int cn = cpu_number();
1417
1418 if(pbtcpu != cn) {
1419 hw_atomic_add(&pbtcnt, 1);
1420 /* Spin on print backtrace lock, which serializes output
1421 * Continue anyway if a timeout occurs.
1422 */
1423 hw_lock_to(&pbtlock, ~0U);
1424 pbtcpu = cn;
1425 }
1426
1427 print_uuid_info(task);
1428 print_threads_registers(thread);
1429 print_tasks_user_threads(task);
1430 kdb_printf("Mac OS version: %s\n", (osversion[0] != 0) ? osversion : "Not yet set");
1431 kdb_printf("Kernel version: %s\n", version);
1432 panic_display_kernel_uuid();
1433 panic_display_model_name();
1434
1435 /* Release print backtrace lock, to permit other callers in the
1436 * event of panics on multiple processors.
1437 */
1438 hw_lock_unlock(&pbtlock);
1439 hw_atomic_sub(&pbtcnt, 1);
1440 /* Wait for other processors to complete output
1441 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1442 */
1443 bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
1444 while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
1445
1446}