]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/AT386/model_dep.c
xnu-1699.24.23.tar.gz
[apple/xnu.git] / osfmk / i386 / AT386 / model_dep.c
1 /*
2 * Copyright (c) 2000-2010 Apple Computer, 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,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
69 #include <platforms.h>
70 #include <mach_kdb.h>
71
72 #include <mach/i386/vm_param.h>
73
74 #include <string.h>
75 #include <mach/vm_param.h>
76 #include <mach/vm_prot.h>
77 #include <mach/machine.h>
78 #include <mach/time_value.h>
79 #include <kern/spl.h>
80 #include <kern/assert.h>
81 #include <kern/debug.h>
82 #include <kern/misc_protos.h>
83 #include <kern/startup.h>
84 #include <kern/clock.h>
85 #include <kern/cpu_data.h>
86 #include <kern/machine.h>
87 #include <i386/postcode.h>
88 #include <i386/mp_desc.h>
89 #include <i386/misc_protos.h>
90 #include <i386/thread.h>
91 #include <i386/trap.h>
92 #include <i386/machine_routines.h>
93 #include <i386/mp.h> /* mp_rendezvous_break_lock */
94 #include <i386/cpuid.h>
95 #include <i386/fpu.h>
96 #include <i386/machine_cpu.h>
97 #include <i386/pmap.h>
98 #if CONFIG_MTRR
99 #include <i386/mtrr.h>
100 #endif
101 #include <i386/ucode.h>
102 #include <i386/pmCPU.h>
103 #include <architecture/i386/pio.h> /* inb() */
104 #include <pexpert/i386/boot.h>
105 #if MACH_KDB
106 #include <ddb/db_aout.h>
107 #endif /* MACH_KDB */
108
109 #include <vm/pmap.h>
110 #include <vm/vm_map.h>
111 #include <vm/vm_kern.h>
112
113 #include <IOKit/IOPlatformExpert.h>
114 #include <IOKit/IOHibernatePrivate.h>
115
116 #include <pexpert/i386/efi.h>
117
118 #include <kern/thread.h>
119 #include <mach-o/loader.h>
120 #include <mach-o/nlist.h>
121
122 #include <libkern/kernel_mach_header.h>
123 #include <libkern/OSKextLibPrivate.h>
124
125 #define DPRINTF(x...)
126 //#define DPRINTF(x...) kprintf(x)
127
128 static void machine_conf(void);
129
130 extern int default_preemption_rate;
131 extern int max_unsafe_quanta;
132 extern int max_poll_quanta;
133 extern unsigned int panic_is_inited;
134
135 int db_run_mode;
136
137 volatile int pbtcpu = -1;
138 hw_lock_data_t pbtlock; /* backtrace print lock */
139 uint32_t pbtcnt = 0;
140
141 volatile int panic_double_fault_cpu = -1;
142
143 #if defined (__i386__)
144 #define PRINT_ARGS_FROM_STACK_FRAME 1
145 #elif defined (__x86_64__)
146 #define PRINT_ARGS_FROM_STACK_FRAME 0
147 #else
148 #error unsupported architecture
149 #endif
150
151 #ifdef __LP64__
152 typedef struct nlist_64 kernel_nlist_t;
153 #else
154 typedef struct nlist kernel_nlist_t;
155 #endif
156
157 typedef struct _cframe_t {
158 struct _cframe_t *prev;
159 uintptr_t caller;
160 #if PRINT_ARGS_FROM_STACK_FRAME
161 unsigned args[0];
162 #endif
163 } cframe_t;
164
165 static unsigned panic_io_port;
166 static unsigned commit_paniclog_to_nvram;
167
168 unsigned int debug_boot_arg;
169
170 void
171 machine_startup(void)
172 {
173 int boot_arg;
174
175 #if 0
176 if( PE_get_hotkey( kPEControlKey ))
177 halt_in_debugger = halt_in_debugger ? 0 : 1;
178 #endif
179
180 if (PE_parse_boot_argn("debug", &debug_boot_arg, sizeof (debug_boot_arg))) {
181 panicDebugging = TRUE;
182 if (debug_boot_arg & DB_HALT) halt_in_debugger=1;
183 if (debug_boot_arg & DB_PRT) disable_debug_output=FALSE;
184 if (debug_boot_arg & DB_SLOG) systemLogDiags=TRUE;
185 if (debug_boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE;
186 } else {
187 debug_boot_arg = 0;
188 }
189
190 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram, sizeof (commit_paniclog_to_nvram)))
191 commit_paniclog_to_nvram = 1;
192
193 /*
194 * Entering the debugger will put the CPUs into a "safe"
195 * power mode.
196 */
197 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg, sizeof (boot_arg)))
198 pmsafe_debug = boot_arg;
199
200 #if NOTYET
201 hw_lock_init(&debugger_lock); /* initialize debugger lock */
202 #endif
203 hw_lock_init(&pbtlock); /* initialize print backtrace lock */
204
205 #if MACH_KDB
206 /*
207 * Initialize KDB
208 */
209 #if DB_MACHINE_COMMANDS
210 db_machine_commands_install(ppc_db_commands);
211 #endif /* DB_MACHINE_COMMANDS */
212 ddb_init();
213
214 if (boot_arg & DB_KDB)
215 current_debugger = KDB_CUR_DB;
216
217 /*
218 * Cause a breakpoint trap to the debugger before proceeding
219 * any further if the proper option bit was specified in
220 * the boot flags.
221 */
222 if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
223 Debugger("inline call to debugger(machine_startup)");
224 halt_in_debugger = 0;
225 active_debugger =1;
226 }
227 #endif /* MACH_KDB */
228
229 if (PE_parse_boot_argn("preempt", &boot_arg, sizeof (boot_arg))) {
230 default_preemption_rate = boot_arg;
231 }
232 if (PE_parse_boot_argn("unsafe", &boot_arg, sizeof (boot_arg))) {
233 max_unsafe_quanta = boot_arg;
234 }
235 if (PE_parse_boot_argn("poll", &boot_arg, sizeof (boot_arg))) {
236 max_poll_quanta = boot_arg;
237 }
238 if (PE_parse_boot_argn("yield", &boot_arg, sizeof (boot_arg))) {
239 sched_poll_yield_shift = boot_arg;
240 }
241 /* The I/O port to issue a read from, in the event of a panic. Useful for
242 * triggering logic analyzers.
243 */
244 if (PE_parse_boot_argn("panic_io_port", &boot_arg, sizeof (boot_arg))) {
245 /*I/O ports range from 0 through 0xFFFF */
246 panic_io_port = boot_arg & 0xffff;
247 }
248
249 machine_conf();
250
251 #if NOTYET
252 ml_thrm_init(); /* Start thermal monitoring on this processor */
253 #endif
254
255 /*
256 * Start the system.
257 */
258 kernel_bootstrap();
259 /*NOTREACHED*/
260 }
261
262
263 static void
264 machine_conf(void)
265 {
266 machine_info.memory_size = (typeof(machine_info.memory_size))mem_size;
267 }
268
269
270 extern void *gPEEFIRuntimeServices;
271 extern void *gPEEFISystemTable;
272
273 /*-
274 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
275 * code or tables extracted from it, as desired without restriction.
276 *
277 * First, the polynomial itself and its table of feedback terms. The
278 * polynomial is
279 * 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
280 *
281 * Note that we take it "backwards" and put the highest-order term in
282 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
283 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
284 * the MSB being 1
285 *
286 * Note that the usual hardware shift register implementation, which
287 * is what we're using (we're merely optimizing it by doing eight-bit
288 * chunks at a time) shifts bits into the lowest-order term. In our
289 * implementation, that means shifting towards the right. Why do we
290 * do it this way? Because the calculated CRC must be transmitted in
291 * order from highest-order term to lowest-order term. UARTs transmit
292 * characters in order from LSB to MSB. By storing the CRC this way
293 * we hand it to the UART in the order low-byte to high-byte; the UART
294 * sends each low-bit to hight-bit; and the result is transmission bit
295 * by bit from highest- to lowest-order term without requiring any bit
296 * shuffling on our part. Reception works similarly
297 *
298 * The feedback terms table consists of 256, 32-bit entries. Notes
299 *
300 * The table can be generated at runtime if desired; code to do so
301 * is shown later. It might not be obvious, but the feedback
302 * terms simply represent the results of eight shift/xor opera
303 * tions for all combinations of data and CRC register values
304 *
305 * The values must be right-shifted by eight bits by the "updcrc
306 * logic; the shift must be unsigned (bring in zeroes). On some
307 * hardware you could probably optimize the shift in assembler by
308 * using byte-swap instructions
309 * polynomial $edb88320
310 *
311 *
312 * CRC32 code derived from work by Gary S. Brown.
313 */
314
315 static uint32_t crc32_tab[] = {
316 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
317 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
318 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
319 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
320 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
321 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
322 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
323 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
324 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
325 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
326 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
327 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
328 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
329 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
330 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
331 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
332 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
333 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
334 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
335 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
336 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
337 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
338 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
339 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
340 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
341 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
342 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
343 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
344 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
345 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
346 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
347 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
348 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
349 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
350 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
351 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
352 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
353 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
354 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
355 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
356 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
357 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
358 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
359 };
360
361 static uint32_t
362 crc32(uint32_t crc, const void *buf, size_t size)
363 {
364 const uint8_t *p;
365
366 p = buf;
367 crc = crc ^ ~0U;
368
369 while (size--)
370 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
371
372 return crc ^ ~0U;
373 }
374
375 static void
376 efi_set_tables_64(EFI_SYSTEM_TABLE_64 * system_table)
377 {
378 EFI_RUNTIME_SERVICES_64 *runtime;
379 uint32_t hdr_cksum;
380 uint32_t cksum;
381
382 DPRINTF("Processing 64-bit EFI tables at %p\n", system_table);
383 do {
384 DPRINTF("Header:\n");
385 DPRINTF(" Signature: 0x%016llx\n", system_table->Hdr.Signature);
386 DPRINTF(" Revision: 0x%08x\n", system_table->Hdr.Revision);
387 DPRINTF(" HeaderSize: 0x%08x\n", system_table->Hdr.HeaderSize);
388 DPRINTF(" CRC32: 0x%08x\n", system_table->Hdr.CRC32);
389 DPRINTF("RuntimeServices: 0x%016llx\n", system_table->RuntimeServices);
390 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
391 kprintf("Bad EFI system table signature\n");
392 break;
393 }
394 // Verify signature of the system table
395 hdr_cksum = system_table->Hdr.CRC32;
396 system_table->Hdr.CRC32 = 0;
397 cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
398
399 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
400 system_table->Hdr.CRC32 = hdr_cksum;
401 if (cksum != hdr_cksum) {
402 kprintf("Bad EFI system table checksum\n");
403 break;
404 }
405
406 gPEEFISystemTable = system_table;
407
408 if (!cpu_mode_is64bit()) {
409 kprintf("Skipping 64-bit EFI runtime services for 32-bit legacy mode\n");
410 break;
411 }
412
413 if(system_table->RuntimeServices == 0) {
414 kprintf("No runtime table present\n");
415 break;
416 }
417 DPRINTF("RuntimeServices table at 0x%qx\n", system_table->RuntimeServices);
418 // 64-bit virtual address is OK for 64-bit EFI and 64/32-bit kernel.
419 runtime = (EFI_RUNTIME_SERVICES_64 *) (uintptr_t)system_table->RuntimeServices;
420 DPRINTF("Checking runtime services table %p\n", runtime);
421 if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
422 kprintf("Bad EFI runtime table signature\n");
423 break;
424 }
425
426 // Verify signature of runtime services table
427 hdr_cksum = runtime->Hdr.CRC32;
428 runtime->Hdr.CRC32 = 0;
429 cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
430
431 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
432 runtime->Hdr.CRC32 = hdr_cksum;
433 if (cksum != hdr_cksum) {
434 kprintf("Bad EFI runtime table checksum\n");
435 break;
436 }
437
438 gPEEFIRuntimeServices = runtime;
439 }
440 while (FALSE);
441 }
442
443 static void
444 efi_set_tables_32(EFI_SYSTEM_TABLE_32 * system_table)
445 {
446 EFI_RUNTIME_SERVICES_32 *runtime;
447 uint32_t hdr_cksum;
448 uint32_t cksum;
449
450 DPRINTF("Processing 32-bit EFI tables at %p\n", system_table);
451 do {
452 DPRINTF("Header:\n");
453 DPRINTF(" Signature: 0x%016llx\n", system_table->Hdr.Signature);
454 DPRINTF(" Revision: 0x%08x\n", system_table->Hdr.Revision);
455 DPRINTF(" HeaderSize: 0x%08x\n", system_table->Hdr.HeaderSize);
456 DPRINTF(" CRC32: 0x%08x\n", system_table->Hdr.CRC32);
457 DPRINTF("RuntimeServices: 0x%08x\n", system_table->RuntimeServices);
458 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
459 kprintf("Bad EFI system table signature\n");
460 break;
461 }
462 // Verify signature of the system table
463 hdr_cksum = system_table->Hdr.CRC32;
464 system_table->Hdr.CRC32 = 0;
465 DPRINTF("System table at %p HeaderSize 0x%x\n", system_table, system_table->Hdr.HeaderSize);
466 cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
467
468 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
469 system_table->Hdr.CRC32 = hdr_cksum;
470 if (cksum != hdr_cksum) {
471 kprintf("Bad EFI system table checksum\n");
472 break;
473 }
474
475 gPEEFISystemTable = system_table;
476
477 if(system_table->RuntimeServices == 0) {
478 kprintf("No runtime table present\n");
479 break;
480 }
481 DPRINTF("RuntimeServices table at 0x%x\n", system_table->RuntimeServices);
482 // 32-bit virtual address is OK for 32-bit EFI and 32-bit kernel.
483 // For a 64-bit kernel, booter provides a virtual address mod 4G
484 runtime = (EFI_RUNTIME_SERVICES_32 *)
485 #ifdef __x86_64__
486 (system_table->RuntimeServices | VM_MIN_KERNEL_ADDRESS);
487 #else
488 system_table->RuntimeServices;
489 #endif
490 DPRINTF("Runtime table addressed at %p\n", runtime);
491 if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
492 kprintf("Bad EFI runtime table signature\n");
493 break;
494 }
495
496 // Verify signature of runtime services table
497 hdr_cksum = runtime->Hdr.CRC32;
498 runtime->Hdr.CRC32 = 0;
499 cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
500
501 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
502 runtime->Hdr.CRC32 = hdr_cksum;
503 if (cksum != hdr_cksum) {
504 kprintf("Bad EFI runtime table checksum\n");
505 break;
506 }
507
508 DPRINTF("Runtime functions\n");
509 DPRINTF(" GetTime : 0x%x\n", runtime->GetTime);
510 DPRINTF(" SetTime : 0x%x\n", runtime->SetTime);
511 DPRINTF(" GetWakeupTime : 0x%x\n", runtime->GetWakeupTime);
512 DPRINTF(" SetWakeupTime : 0x%x\n", runtime->SetWakeupTime);
513 DPRINTF(" SetVirtualAddressMap : 0x%x\n", runtime->SetVirtualAddressMap);
514 DPRINTF(" ConvertPointer : 0x%x\n", runtime->ConvertPointer);
515 DPRINTF(" GetVariable : 0x%x\n", runtime->GetVariable);
516 DPRINTF(" GetNextVariableName : 0x%x\n", runtime->GetNextVariableName);
517 DPRINTF(" SetVariable : 0x%x\n", runtime->SetVariable);
518 DPRINTF(" GetNextHighMonotonicCount: 0x%x\n", runtime->GetNextHighMonotonicCount);
519 DPRINTF(" ResetSystem : 0x%x\n", runtime->ResetSystem);
520
521 gPEEFIRuntimeServices = runtime;
522 }
523 while (FALSE);
524 }
525
526
527 /* Map in EFI runtime areas. */
528 static void
529 efi_init(void)
530 {
531 boot_args *args = (boot_args *)PE_state.bootArgs;
532
533 kprintf("Initializing EFI runtime services\n");
534
535 do
536 {
537 vm_offset_t vm_size, vm_addr;
538 vm_map_offset_t phys_addr;
539 EfiMemoryRange *mptr;
540 unsigned int msize, mcount;
541 unsigned int i;
542
543 msize = args->MemoryMapDescriptorSize;
544 mcount = args->MemoryMapSize / msize;
545
546 DPRINTF("efi_init() kernel base: 0x%x size: 0x%x\n",
547 args->kaddr, args->ksize);
548 DPRINTF(" efiSystemTable physical: 0x%x virtual: %p\n",
549 args->efiSystemTable,
550 (void *) ml_static_ptovirt(args->efiSystemTable));
551 DPRINTF(" efiRuntimeServicesPageStart: 0x%x\n",
552 args->efiRuntimeServicesPageStart);
553 DPRINTF(" efiRuntimeServicesPageCount: 0x%x\n",
554 args->efiRuntimeServicesPageCount);
555 DPRINTF(" efiRuntimeServicesVirtualPageStart: 0x%016llx\n",
556 args->efiRuntimeServicesVirtualPageStart);
557 mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
558 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
559 if (((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) ) {
560 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
561 vm_addr = (vm_offset_t) mptr->VirtualStart;
562 #ifdef __x86_64__
563 /* For K64 on EFI32, shadow-map into high KVA */
564 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
565 vm_addr |= VM_MIN_KERNEL_ADDRESS;
566 #endif
567 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
568 DPRINTF(" Type: %x phys: %p EFIv: %p kv: %p size: %p\n",
569 mptr->Type,
570 (void *) (uintptr_t) phys_addr,
571 (void *) (uintptr_t) mptr->VirtualStart,
572 (void *) vm_addr,
573 (void *) vm_size);
574 pmap_map(vm_addr, phys_addr, phys_addr + round_page(vm_size),
575 (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
576 (mptr->Type == EfiMemoryMappedIO) ? VM_WIMG_IO : VM_WIMG_USE_DEFAULT);
577 }
578 }
579
580 if (args->Version != kBootArgsVersion2)
581 panic("Incompatible boot args version %d revision %d\n", args->Version, args->Revision);
582
583 kprintf("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
584 if (args->efiMode == kBootArgsEfiMode64) {
585 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) ml_static_ptovirt(args->efiSystemTable));
586 } else {
587 efi_set_tables_32((EFI_SYSTEM_TABLE_32 *) ml_static_ptovirt(args->efiSystemTable));
588 }
589 }
590 while (FALSE);
591
592 return;
593 }
594
595 /* Remap EFI runtime areas. */
596 void
597 hibernate_newruntime_map(void * map, vm_size_t map_size, uint32_t system_table_offset)
598 {
599 boot_args *args = (boot_args *)PE_state.bootArgs;
600
601 kprintf("Reinitializing EFI runtime services\n");
602
603 do
604 {
605 vm_offset_t vm_size, vm_addr;
606 vm_map_offset_t phys_addr;
607 EfiMemoryRange *mptr;
608 unsigned int msize, mcount;
609 unsigned int i;
610
611 gPEEFISystemTable = 0;
612 gPEEFIRuntimeServices = 0;
613
614 system_table_offset += ptoa_32(args->efiRuntimeServicesPageStart);
615
616 kprintf("Old system table 0x%x, new 0x%x\n",
617 (uint32_t)args->efiSystemTable, system_table_offset);
618
619 args->efiSystemTable = system_table_offset;
620
621 kprintf("Old map:\n");
622 msize = args->MemoryMapDescriptorSize;
623 mcount = args->MemoryMapSize / msize;
624 mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
625 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
626 if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
627
628 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
629 vm_addr = (vm_offset_t) mptr->VirtualStart;
630 #ifdef __x86_64__
631 /* K64 on EFI32 */
632 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
633 vm_addr |= VM_MIN_KERNEL_ADDRESS;
634 #endif
635 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
636
637 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr->Type, phys_addr, (unsigned long)vm_addr, mptr->NumberOfPages);
638 }
639 }
640
641 pmap_remove(kernel_pmap, i386_ptob(args->efiRuntimeServicesPageStart),
642 i386_ptob(args->efiRuntimeServicesPageStart + args->efiRuntimeServicesPageCount));
643
644 kprintf("New map:\n");
645 msize = args->MemoryMapDescriptorSize;
646 mcount = (unsigned int )(map_size / msize);
647 mptr = map;
648 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
649 if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
650
651 vm_size = (vm_offset_t)i386_ptob((uint32_t)mptr->NumberOfPages);
652 vm_addr = (vm_offset_t) mptr->VirtualStart;
653 #ifdef __x86_64__
654 if (vm_addr < VM_MIN_KERNEL_ADDRESS)
655 vm_addr |= VM_MIN_KERNEL_ADDRESS;
656 #endif
657 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
658
659 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr->Type, phys_addr, (unsigned long)vm_addr, mptr->NumberOfPages);
660
661 pmap_map(vm_addr, phys_addr, phys_addr + round_page(vm_size),
662 (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
663 (mptr->Type == EfiMemoryMappedIO) ? VM_WIMG_IO : VM_WIMG_USE_DEFAULT);
664 }
665 }
666
667 if (args->Version != kBootArgsVersion2)
668 panic("Incompatible boot args version %d revision %d\n", args->Version, args->Revision);
669
670 kprintf("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
671 if (args->efiMode == kBootArgsEfiMode64) {
672 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) ml_static_ptovirt(args->efiSystemTable));
673 } else {
674 efi_set_tables_32((EFI_SYSTEM_TABLE_32 *) ml_static_ptovirt(args->efiSystemTable));
675 }
676 }
677 while (FALSE);
678
679 kprintf("Done reinitializing EFI runtime services\n");
680
681 return;
682 }
683
684 /*
685 * Find devices. The system is alive.
686 */
687 void
688 machine_init(void)
689 {
690 /* Ensure panic buffer is initialized. */
691 debug_log_init();
692
693 /*
694 * Display CPU identification
695 */
696 cpuid_cpu_display("CPU identification");
697 cpuid_feature_display("CPU features");
698 cpuid_extfeature_display("CPU extended features");
699
700 /*
701 * Initialize EFI runtime services.
702 */
703 efi_init();
704
705 smp_init();
706
707 /*
708 * Set up to use floating point.
709 */
710 init_fpu();
711
712 /*
713 * Configure clock devices.
714 */
715 clock_config();
716
717 #if CONFIG_MTRR
718 /*
719 * Initialize MTRR from boot processor.
720 */
721 mtrr_init();
722
723 /*
724 * Set up PAT for boot processor.
725 */
726 pat_init();
727 #endif
728
729 /*
730 * Free lowmem pages and complete other setup
731 */
732 pmap_lowmem_finalize();
733 }
734
735 /*
736 * Halt a cpu.
737 */
738 void
739 halt_cpu(void)
740 {
741 halt_all_cpus(FALSE);
742 }
743
744 int reset_mem_on_reboot = 1;
745
746 /*
747 * Halt the system or reboot.
748 */
749 void
750 halt_all_cpus(boolean_t reboot)
751 {
752 if (reboot) {
753 printf("MACH Reboot\n");
754 PEHaltRestart( kPERestartCPU );
755 } else {
756 printf("CPU halted\n");
757 PEHaltRestart( kPEHaltCPU );
758 }
759 while(1);
760 }
761
762
763 /* Issue an I/O port read if one has been requested - this is an event logic
764 * analyzers can use as a trigger point.
765 */
766
767 void
768 panic_io_port_read(void) {
769 if (panic_io_port)
770 (void)inb(panic_io_port);
771 }
772
773 /* For use with the MP rendezvous mechanism
774 */
775
776 uint64_t panic_restart_timeout = ~(0ULL);
777
778 static void
779 machine_halt_cpu(void) {
780 panic_io_port_read();
781
782 if (panic_restart_timeout != ~(0ULL)) {
783 uint64_t deadline = mach_absolute_time() + panic_restart_timeout;
784 while (mach_absolute_time() < deadline) {
785 cpu_pause();
786 }
787 kprintf("Invoking PE_halt_restart\n");
788 /* Attempt restart via ACPI RESET_REG; at the time of this
789 * writing, this is routine is chained through AppleSMC->
790 * AppleACPIPlatform
791 */
792 if (PE_halt_restart)
793 (*PE_halt_restart)(kPERestartCPU);
794 }
795 pmCPUHalt(PM_HALT_DEBUG);
796 }
797
798 void
799 Debugger(
800 const char *message)
801 {
802 unsigned long pi_size = 0;
803 void *stackptr;
804 int cn = cpu_number();
805
806 hw_atomic_add(&debug_mode, 1);
807 if (!panic_is_inited) {
808 postcode(PANIC_HLT);
809 asm("hlt");
810 }
811
812 printf("Debugger called: <%s>\n", message);
813 kprintf("Debugger called: <%s>\n", message);
814
815 /*
816 * Skip the graphical panic box if no panic string.
817 * This is the case if we're being called from
818 * host_reboot(,HOST_REBOOT_DEBUGGER)
819 * as a quiet way into the debugger.
820 */
821
822 if (panicstr) {
823 disable_preemption();
824
825 /* Issue an I/O port read if one has been requested - this is an event logic
826 * analyzers can use as a trigger point.
827 */
828 panic_io_port_read();
829
830 /* Obtain current frame pointer */
831 #if defined (__i386__)
832 __asm__ volatile("movl %%ebp, %0" : "=m" (stackptr));
833 #elif defined (__x86_64__)
834 __asm__ volatile("movq %%rbp, %0" : "=m" (stackptr));
835 #endif
836
837 /* Print backtrace - callee is internally synchronized */
838 panic_i386_backtrace(stackptr, ((panic_double_fault_cpu == cn) ? 80: 48), NULL, FALSE, NULL);
839
840 /* everything should be printed now so copy to NVRAM
841 */
842
843 if( debug_buf_size > 0) {
844 /* Optionally sync the panic log, if any, to NVRAM
845 * This is the default.
846 */
847 if (commit_paniclog_to_nvram) {
848 unsigned int bufpos;
849 uintptr_t cr0;
850
851 debug_putc(0);
852
853 /* Now call the compressor */
854 /* XXX Consider using the WKdm compressor in the
855 * future, rather than just packing - would need to
856 * be co-ordinated with crashreporter, which decodes
857 * this post-restart. The compressor should be
858 * capable of in-place compression.
859 */
860 bufpos = packA(debug_buf,
861 (unsigned int) (debug_buf_ptr - debug_buf), debug_buf_size);
862 /* If compression was successful,
863 * use the compressed length
864 */
865 pi_size = bufpos ? bufpos : (unsigned) (debug_buf_ptr - debug_buf);
866
867 /* Save panic log to non-volatile store
868 * Panic info handler must truncate data that is
869 * too long for this platform.
870 * This call must save data synchronously,
871 * since we can subsequently halt the system.
872 */
873
874
875 /* The following sequence is a workaround for:
876 * <rdar://problem/5915669> SnowLeopard10A67: AppleEFINVRAM should not invoke
877 * any routines that use floating point (MMX in this case) when saving panic
878 * logs to nvram/flash.
879 */
880 cr0 = get_cr0();
881 clear_ts();
882
883 kprintf("Attempting to commit panic log to NVRAM\n");
884 pi_size = PESavePanicInfo((unsigned char *)debug_buf,
885 (uint32_t)pi_size );
886 set_cr0(cr0);
887
888 /* Uncompress in-place, to permit examination of
889 * the panic log by debuggers.
890 */
891
892 if (bufpos) {
893 unpackA(debug_buf, bufpos);
894 }
895 }
896 }
897
898 /* If the user won't be able to read the dialog,
899 * don't bother trying to show it
900 */
901 if (!PE_reboot_on_panic())
902 draw_panic_dialog();
903
904 if (!panicDebugging) {
905 unsigned cnum;
906 /* Clear the MP rendezvous function lock, in the event
907 * that a panic occurred while in that codepath.
908 */
909 mp_rendezvous_break_lock();
910 if (PE_reboot_on_panic()) {
911 if (PE_halt_restart)
912 (*PE_halt_restart)(kPERestartCPU);
913 }
914
915 /* Non-maskably interrupt all other processors
916 * If a restart timeout is specified, this processor
917 * will attempt a restart.
918 */
919 kprintf("Invoking machine_halt_cpu on CPU %d\n", cn);
920 for (cnum = 0; cnum < real_ncpus; cnum++) {
921 if (cnum != (unsigned) cn) {
922 cpu_NMI_interrupt(cnum);
923 }
924 }
925 machine_halt_cpu();
926 /* NOT REACHED */
927 }
928 }
929
930 __asm__("int3");
931 hw_atomic_sub(&debug_mode, 1);
932 }
933
934 char *
935 machine_boot_info(char *buf, __unused vm_size_t size)
936 {
937 *buf ='\0';
938 return buf;
939 }
940
941 /* Routines for address - symbol translation. Not called unless the "keepsyms"
942 * boot-arg is supplied.
943 */
944
945 static int
946 panic_print_macho_symbol_name(kernel_mach_header_t *mh, vm_address_t search, const char *module_name)
947 {
948 kernel_nlist_t *sym = NULL;
949 struct load_command *cmd;
950 kernel_segment_command_t *orig_ts = NULL, *orig_le = NULL;
951 struct symtab_command *orig_st = NULL;
952 unsigned int i;
953 char *strings, *bestsym = NULL;
954 vm_address_t bestaddr = 0, diff, curdiff;
955
956 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
957
958 cmd = (struct load_command *) &mh[1];
959 for (i = 0; i < mh->ncmds; i++) {
960 if (cmd->cmd == LC_SEGMENT_KERNEL) {
961 kernel_segment_command_t *orig_sg = (kernel_segment_command_t *) cmd;
962
963 if (strncmp(SEG_TEXT, orig_sg->segname,
964 sizeof(orig_sg->segname)) == 0)
965 orig_ts = orig_sg;
966 else if (strncmp(SEG_LINKEDIT, orig_sg->segname,
967 sizeof(orig_sg->segname)) == 0)
968 orig_le = orig_sg;
969 else if (strncmp("", orig_sg->segname,
970 sizeof(orig_sg->segname)) == 0)
971 orig_ts = orig_sg; /* pre-Lion i386 kexts have a single unnamed segment */
972 }
973 else if (cmd->cmd == LC_SYMTAB)
974 orig_st = (struct symtab_command *) cmd;
975
976 cmd = (struct load_command *) ((uintptr_t) cmd + cmd->cmdsize);
977 }
978
979 if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL))
980 return 0;
981
982 if ((search < orig_ts->vmaddr) ||
983 (search >= orig_ts->vmaddr + orig_ts->vmsize)) {
984 /* search out of range for this mach header */
985 return 0;
986 }
987
988 sym = (kernel_nlist_t *)(uintptr_t)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff);
989 strings = (char *)(uintptr_t)(orig_le->vmaddr + orig_st->stroff - orig_le->fileoff);
990 diff = search;
991
992 for (i = 0; i < orig_st->nsyms; i++) {
993 if (sym[i].n_type & N_STAB) continue;
994
995 if (sym[i].n_value <= search) {
996 curdiff = search - (vm_address_t)sym[i].n_value;
997 if (curdiff < diff) {
998 diff = curdiff;
999 bestaddr = sym[i].n_value;
1000 bestsym = strings + sym[i].n_un.n_strx;
1001 }
1002 }
1003 }
1004
1005 if (bestsym != NULL) {
1006 if (diff != 0) {
1007 kdb_printf("%s : %s + 0x%lx", module_name, bestsym, (unsigned long)diff);
1008 } else {
1009 kdb_printf("%s : %s", module_name, bestsym);
1010 }
1011 return 1;
1012 }
1013 return 0;
1014 }
1015
1016 extern kmod_info_t * kmod; /* the list of modules */
1017
1018 static void
1019 panic_print_kmod_symbol_name(vm_address_t search)
1020 {
1021 u_int i;
1022
1023 if (gLoadedKextSummaries == NULL)
1024 return;
1025 for (i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
1026 OSKextLoadedKextSummary *summary = gLoadedKextSummaries->summaries + i;
1027
1028 if ((search >= summary->address) &&
1029 (search < (summary->address + summary->size)))
1030 {
1031 kernel_mach_header_t *header = (kernel_mach_header_t *)(uintptr_t) summary->address;
1032 if (panic_print_macho_symbol_name(header, search, summary->name) == 0) {
1033 kdb_printf("%s + %llu", summary->name, (unsigned long)search - summary->address);
1034 }
1035 break;
1036 }
1037 }
1038 }
1039
1040 static void
1041 panic_print_symbol_name(vm_address_t search)
1042 {
1043 /* try searching in the kernel */
1044 if (panic_print_macho_symbol_name(&_mh_execute_header, search, "mach_kernel") == 0) {
1045 /* that failed, now try to search for the right kext */
1046 panic_print_kmod_symbol_name(search);
1047 }
1048 }
1049
1050 /* Generate a backtrace, given a frame pointer - this routine
1051 * should walk the stack safely. The trace is appended to the panic log
1052 * and conditionally, to the console. If the trace contains kernel module
1053 * addresses, display the module name, load address and dependencies.
1054 */
1055
1056 #define DUMPFRAMES 32
1057 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
1058 void
1059 panic_i386_backtrace(void *_frame, int nframes, const char *msg, boolean_t regdump, x86_saved_state_t *regs)
1060 {
1061 cframe_t *frame = (cframe_t *)_frame;
1062 vm_offset_t raddrs[DUMPFRAMES];
1063 vm_offset_t PC = 0;
1064 int frame_index;
1065 volatile uint32_t *ppbtcnt = &pbtcnt;
1066 uint64_t bt_tsc_timeout;
1067 boolean_t keepsyms = FALSE;
1068 int cn = cpu_number();
1069
1070 if(pbtcpu != cn) {
1071 hw_atomic_add(&pbtcnt, 1);
1072 /* Spin on print backtrace lock, which serializes output
1073 * Continue anyway if a timeout occurs.
1074 */
1075 hw_lock_to(&pbtlock, LockTimeOutTSC*2);
1076 pbtcpu = cn;
1077 }
1078
1079 PE_parse_boot_argn("keepsyms", &keepsyms, sizeof (keepsyms));
1080
1081 if (msg != NULL) {
1082 kdb_printf("%s", msg);
1083 }
1084
1085 if ((regdump == TRUE) && (regs != NULL)) {
1086 #if defined(__x86_64__)
1087 x86_saved_state64_t *ss64p = saved_state64(regs);
1088 kdb_printf(
1089 "RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1090 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1091 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1092 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1093 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n",
1094 ss64p->rax, ss64p->rbx, ss64p->rcx, ss64p->rdx,
1095 ss64p->isf.rsp, ss64p->rbp, ss64p->rsi, ss64p->rdi,
1096 ss64p->r8, ss64p->r9, ss64p->r10, ss64p->r11,
1097 ss64p->r12, ss64p->r13, ss64p->r14, ss64p->r15,
1098 ss64p->isf.rflags, ss64p->isf.rip, ss64p->isf.cs,
1099 ss64p->isf.ss);
1100 PC = ss64p->isf.rip;
1101 #else
1102 x86_saved_state32_t *ss32p = saved_state32(regs);
1103 kdb_printf(
1104 "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
1105 "CR2: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
1106 "EFL: 0x%08x, EIP: 0x%08x, CS: 0x%08x, DS: 0x%08x\n",
1107 ss32p->eax,ss32p->ebx,ss32p->ecx,ss32p->edx,
1108 ss32p->cr2,ss32p->ebp,ss32p->esi,ss32p->edi,
1109 ss32p->efl,ss32p->eip,ss32p->cs, ss32p->ds);
1110 PC = ss32p->eip;
1111 #endif
1112 }
1113
1114 kdb_printf("Backtrace (CPU %d), "
1115 #if PRINT_ARGS_FROM_STACK_FRAME
1116 "Frame : Return Address (4 potential args on stack)\n", cn);
1117 #else
1118 "Frame : Return Address\n", cn);
1119 #endif
1120
1121 for (frame_index = 0; frame_index < nframes; frame_index++) {
1122 vm_offset_t curframep = (vm_offset_t) frame;
1123
1124 if (!curframep)
1125 break;
1126
1127 if (curframep & 0x3) {
1128 kdb_printf("Unaligned frame\n");
1129 goto invalid;
1130 }
1131
1132 if (!kvtophys(curframep) ||
1133 !kvtophys(curframep + sizeof(cframe_t) - 1)) {
1134 kdb_printf("No mapping exists for frame pointer\n");
1135 goto invalid;
1136 }
1137
1138 kdb_printf("%p : 0x%lx ", frame, frame->caller);
1139 if (frame_index < DUMPFRAMES)
1140 raddrs[frame_index] = frame->caller;
1141
1142 #if PRINT_ARGS_FROM_STACK_FRAME
1143 if (kvtophys((vm_offset_t)&(frame->args[3])))
1144 kdb_printf("(0x%x 0x%x 0x%x 0x%x) ",
1145 frame->args[0], frame->args[1],
1146 frame->args[2], frame->args[3]);
1147 #endif
1148
1149 /* Display address-symbol translation only if the "keepsyms"
1150 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1151 * This routine is potentially unsafe; also, function
1152 * boundary identification is unreliable after a strip -x.
1153 */
1154 if (keepsyms)
1155 panic_print_symbol_name((vm_address_t)frame->caller);
1156
1157 kdb_printf("\n");
1158
1159 frame = frame->prev;
1160 }
1161
1162 if (frame_index >= nframes)
1163 kdb_printf("\tBacktrace continues...\n");
1164
1165 goto out;
1166
1167 invalid:
1168 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame);
1169 out:
1170
1171 /* Identify kernel modules in the backtrace and display their
1172 * load addresses and dependencies. This routine should walk
1173 * the kmod list safely.
1174 */
1175 if (frame_index)
1176 kmod_panic_dump((vm_offset_t *)&raddrs[0], frame_index);
1177
1178 if (PC != 0)
1179 kmod_panic_dump(&PC, 1);
1180
1181 panic_display_system_configuration();
1182
1183 /* Release print backtrace lock, to permit other callers in the
1184 * event of panics on multiple processors.
1185 */
1186 hw_lock_unlock(&pbtlock);
1187 hw_atomic_sub(&pbtcnt, 1);
1188 /* Wait for other processors to complete output
1189 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1190 */
1191 bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
1192 while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
1193 }