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