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