2 * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
34 * All Rights Reserved.
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.
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.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
62 * Author: Avadis Tevanian, Jr., Michael Wayne Young
64 * Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
66 * Basic initialization for I386 - ISA bus machines.
69 #include <platforms.h>
72 #include <mach/i386/vm_param.h>
75 #include <mach/vm_param.h>
76 #include <mach/vm_prot.h>
77 #include <mach/machine.h>
78 #include <mach/time_value.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>
96 #include <i386/machine_cpu.h>
97 #include <i386/pmap.h>
99 #include <i386/mtrr.h>
101 #include <i386/ucode.h>
102 #include <i386/pmCPU.h>
103 #include <architecture/i386/pio.h> /* inb() */
104 #include <pexpert/i386/boot.h>
106 #include <ddb/db_aout.h>
107 #endif /* MACH_KDB */
110 #include <vm/vm_map.h>
111 #include <vm/vm_kern.h>
113 #include <IOKit/IOPlatformExpert.h>
114 #include <IOKit/IOHibernatePrivate.h>
116 #include <pexpert/i386/efi.h>
118 #include <kern/thread.h>
119 #include <mach-o/loader.h>
120 #include <mach-o/nlist.h>
122 #include <libkern/kernel_mach_header.h>
123 #include <libkern/OSKextLibPrivate.h>
125 #define DPRINTF(x...)
126 //#define DPRINTF(x...) kprintf(x)
128 static void machine_conf(void);
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
;
137 volatile int pbtcpu
= -1;
138 hw_lock_data_t pbtlock
; /* backtrace print lock */
141 volatile int panic_double_fault_cpu
= -1;
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
148 #error unsupported architecture
152 typedef struct nlist_64 kernel_nlist_t
;
154 typedef struct nlist kernel_nlist_t
;
157 typedef struct _cframe_t
{
158 struct _cframe_t
*prev
;
160 #if PRINT_ARGS_FROM_STACK_FRAME
165 static unsigned panic_io_port
;
166 static unsigned commit_paniclog_to_nvram
;
168 unsigned int debug_boot_arg
;
171 machine_startup(void)
176 if( PE_get_hotkey( kPEControlKey
))
177 halt_in_debugger
= halt_in_debugger
? 0 : 1;
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
;
190 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram
, sizeof (commit_paniclog_to_nvram
)))
191 commit_paniclog_to_nvram
= 1;
194 * Entering the debugger will put the CPUs into a "safe"
197 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg
, sizeof (boot_arg
)))
198 pmsafe_debug
= boot_arg
;
201 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
203 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
209 #if DB_MACHINE_COMMANDS
210 db_machine_commands_install(ppc_db_commands
);
211 #endif /* DB_MACHINE_COMMANDS */
214 if (boot_arg
& DB_KDB
)
215 current_debugger
= KDB_CUR_DB
;
218 * Cause a breakpoint trap to the debugger before proceeding
219 * any further if the proper option bit was specified in
222 if (halt_in_debugger
&& (current_debugger
== KDB_CUR_DB
)) {
223 Debugger("inline call to debugger(machine_startup)");
224 halt_in_debugger
= 0;
227 #endif /* MACH_KDB */
229 if (PE_parse_boot_argn("preempt", &boot_arg
, sizeof (boot_arg
))) {
230 default_preemption_rate
= boot_arg
;
232 if (PE_parse_boot_argn("unsafe", &boot_arg
, sizeof (boot_arg
))) {
233 max_unsafe_quanta
= boot_arg
;
235 if (PE_parse_boot_argn("poll", &boot_arg
, sizeof (boot_arg
))) {
236 max_poll_quanta
= boot_arg
;
238 if (PE_parse_boot_argn("yield", &boot_arg
, sizeof (boot_arg
))) {
239 sched_poll_yield_shift
= boot_arg
;
241 /* The I/O port to issue a read from, in the event of a panic. Useful for
242 * triggering logic analyzers.
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;
252 ml_thrm_init(); /* Start thermal monitoring on this processor */
266 machine_info
.memory_size
= (typeof(machine_info
.memory_size
))mem_size
;
270 extern void *gPEEFIRuntimeServices
;
271 extern void *gPEEFISystemTable
;
274 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
275 * code or tables extracted from it, as desired without restriction.
277 * First, the polynomial itself and its table of feedback terms. The
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
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
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
298 * The feedback terms table consists of 256, 32-bit entries. Notes
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
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
312 * CRC32 code derived from work by Gary S. Brown.
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
362 crc32(uint32_t crc
, const void *buf
, size_t size
)
370 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
376 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
378 EFI_RUNTIME_SERVICES_64
*runtime
;
382 DPRINTF("Processing 64-bit EFI tables at %p\n", system_table
);
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");
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
);
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");
406 gPEEFISystemTable
= system_table
;
408 if (!cpu_mode_is64bit()) {
409 kprintf("Skipping 64-bit EFI runtime services for 32-bit legacy mode\n");
413 if(system_table
->RuntimeServices
== 0) {
414 kprintf("No runtime table present\n");
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");
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
);
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");
438 gPEEFIRuntimeServices
= runtime
;
444 efi_set_tables_32(EFI_SYSTEM_TABLE_32
* system_table
)
446 EFI_RUNTIME_SERVICES_32
*runtime
;
450 DPRINTF("Processing 32-bit EFI tables at %p\n", system_table
);
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");
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
);
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");
475 gPEEFISystemTable
= system_table
;
477 if(system_table
->RuntimeServices
== 0) {
478 kprintf("No runtime table present\n");
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
*)
486 (system_table
->RuntimeServices
| VM_MIN_KERNEL_ADDRESS
);
488 system_table
->RuntimeServices
;
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");
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
);
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");
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
);
521 gPEEFIRuntimeServices
= runtime
;
527 /* Map in EFI runtime areas. */
531 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
533 kprintf("Initializing EFI runtime services\n");
537 vm_offset_t vm_size
, vm_addr
;
538 vm_map_offset_t phys_addr
;
539 EfiMemoryRange
*mptr
;
540 unsigned int msize
, mcount
;
543 msize
= args
->MemoryMapDescriptorSize
;
544 mcount
= args
->MemoryMapSize
/ msize
;
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
;
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
;
567 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
568 DPRINTF(" Type: %x phys: %p EFIv: %p kv: %p size: %p\n",
570 (void *) (uintptr_t) phys_addr
,
571 (void *) (uintptr_t) mptr
->VirtualStart
,
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
);
580 if (args
->Version
!= kBootArgsVersion2
)
581 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
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
));
587 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
595 /* Remap EFI runtime areas. */
597 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
599 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
601 kprintf("Reinitializing EFI runtime services\n");
605 vm_offset_t vm_size
, vm_addr
;
606 vm_map_offset_t phys_addr
;
607 EfiMemoryRange
*mptr
;
608 unsigned int msize
, mcount
;
611 gPEEFISystemTable
= 0;
612 gPEEFIRuntimeServices
= 0;
614 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
616 kprintf("Old system table 0x%x, new 0x%x\n",
617 (uint32_t)args
->efiSystemTable
, system_table_offset
);
619 args
->efiSystemTable
= system_table_offset
;
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
) {
628 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
629 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
632 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
633 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
635 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
637 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
641 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
642 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
644 kprintf("New map:\n");
645 msize
= args
->MemoryMapDescriptorSize
;
646 mcount
= (unsigned int )(map_size
/ msize
);
648 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
649 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
651 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
652 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
654 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
655 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
657 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
659 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
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
);
667 if (args
->Version
!= kBootArgsVersion2
)
668 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
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
));
674 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
679 kprintf("Done reinitializing EFI runtime services\n");
685 * Find devices. The system is alive.
690 /* Ensure panic buffer is initialized. */
694 * Display CPU identification
696 cpuid_cpu_display("CPU identification");
697 cpuid_feature_display("CPU features");
698 cpuid_extfeature_display("CPU extended features");
701 * Initialize EFI runtime services.
708 * Set up to use floating point.
713 * Configure clock devices.
719 * Initialize MTRR from boot processor.
724 * Set up PAT for boot processor.
730 * Free lowmem pages and complete other setup
732 pmap_lowmem_finalize();
741 halt_all_cpus(FALSE
);
744 int reset_mem_on_reboot
= 1;
747 * Halt the system or reboot.
750 halt_all_cpus(boolean_t reboot
)
753 printf("MACH Reboot\n");
754 PEHaltRestart( kPERestartCPU
);
756 printf("CPU halted\n");
757 PEHaltRestart( kPEHaltCPU
);
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.
768 panic_io_port_read(void) {
770 (void)inb(panic_io_port
);
773 /* For use with the MP rendezvous mechanism
776 uint64_t panic_restart_timeout
= ~(0ULL);
779 machine_halt_cpu(void) {
780 panic_io_port_read();
782 if (panic_restart_timeout
!= ~(0ULL)) {
783 uint64_t deadline
= mach_absolute_time() + panic_restart_timeout
;
784 while (mach_absolute_time() < deadline
) {
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->
793 (*PE_halt_restart
)(kPERestartCPU
);
795 pmCPUHalt(PM_HALT_DEBUG
);
802 unsigned long pi_size
= 0;
804 int cn
= cpu_number();
806 hw_atomic_add(&debug_mode
, 1);
807 if (!panic_is_inited
) {
812 printf("Debugger called: <%s>\n", message
);
813 kprintf("Debugger called: <%s>\n", message
);
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.
823 disable_preemption();
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.
828 panic_io_port_read();
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
));
837 /* Print backtrace - callee is internally synchronized */
838 panic_i386_backtrace(stackptr
, ((panic_double_fault_cpu
== cn
) ? 80: 48), NULL
, FALSE
, NULL
);
840 /* everything should be printed now so copy to NVRAM
843 if( debug_buf_size
> 0) {
844 /* Optionally sync the panic log, if any, to NVRAM
845 * This is the default.
847 if (commit_paniclog_to_nvram
) {
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.
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
865 pi_size
= bufpos
? bufpos
: (unsigned) (debug_buf_ptr
- debug_buf
);
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.
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.
883 kprintf("Attempting to commit panic log to NVRAM\n");
884 pi_size
= PESavePanicInfo((unsigned char *)debug_buf
,
888 /* Uncompress in-place, to permit examination of
889 * the panic log by debuggers.
893 unpackA(debug_buf
, bufpos
);
898 /* If the user won't be able to read the dialog,
899 * don't bother trying to show it
901 if (!PE_reboot_on_panic())
904 if (!panicDebugging
) {
906 /* Clear the MP rendezvous function lock, in the event
907 * that a panic occurred while in that codepath.
909 mp_rendezvous_break_lock();
910 if (PE_reboot_on_panic()) {
912 (*PE_halt_restart
)(kPERestartCPU
);
915 /* Non-maskably interrupt all other processors
916 * If a restart timeout is specified, this processor
917 * will attempt a restart.
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
);
931 hw_atomic_sub(&debug_mode
, 1);
935 machine_boot_info(char *buf
, __unused vm_size_t size
)
941 /* Routines for address - symbol translation. Not called unless the "keepsyms"
942 * boot-arg is supplied.
946 panic_print_macho_symbol_name(kernel_mach_header_t
*mh
, vm_address_t search
, const char *module_name
)
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
;
953 char *strings
, *bestsym
= NULL
;
954 vm_address_t bestaddr
= 0, diff
, curdiff
;
956 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
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
;
963 if (strncmp(SEG_TEXT
, orig_sg
->segname
,
964 sizeof(orig_sg
->segname
)) == 0)
966 else if (strncmp(SEG_LINKEDIT
, orig_sg
->segname
,
967 sizeof(orig_sg
->segname
)) == 0)
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 */
973 else if (cmd
->cmd
== LC_SYMTAB
)
974 orig_st
= (struct symtab_command
*) cmd
;
976 cmd
= (struct load_command
*) ((uintptr_t) cmd
+ cmd
->cmdsize
);
979 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
982 if ((search
< orig_ts
->vmaddr
) ||
983 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
984 /* search out of range for this mach header */
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
);
992 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
993 if (sym
[i
].n_type
& N_STAB
) continue;
995 if (sym
[i
].n_value
<= search
) {
996 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
997 if (curdiff
< diff
) {
999 bestaddr
= sym
[i
].n_value
;
1000 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
1005 if (bestsym
!= NULL
) {
1007 kdb_printf("%s : %s + 0x%lx", module_name
, bestsym
, (unsigned long)diff
);
1009 kdb_printf("%s : %s", module_name
, bestsym
);
1016 extern kmod_info_t
* kmod
; /* the list of modules */
1019 panic_print_kmod_symbol_name(vm_address_t search
)
1023 if (gLoadedKextSummaries
== NULL
)
1025 for (i
= 0; i
< gLoadedKextSummaries
->numSummaries
; ++i
) {
1026 OSKextLoadedKextSummary
*summary
= gLoadedKextSummaries
->summaries
+ i
;
1028 if ((search
>= summary
->address
) &&
1029 (search
< (summary
->address
+ summary
->size
)))
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
);
1041 panic_print_symbol_name(vm_address_t search
)
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
);
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.
1056 #define DUMPFRAMES 32
1057 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
1059 panic_i386_backtrace(void *_frame
, int nframes
, const char *msg
, boolean_t regdump
, x86_saved_state_t
*regs
)
1061 cframe_t
*frame
= (cframe_t
*)_frame
;
1062 vm_offset_t raddrs
[DUMPFRAMES
];
1065 volatile uint32_t *ppbtcnt
= &pbtcnt
;
1066 uint64_t bt_tsc_timeout
;
1067 boolean_t keepsyms
= FALSE
;
1068 int cn
= cpu_number();
1071 hw_atomic_add(&pbtcnt
, 1);
1072 /* Spin on print backtrace lock, which serializes output
1073 * Continue anyway if a timeout occurs.
1075 hw_lock_to(&pbtlock
, LockTimeOutTSC
*2);
1079 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1082 kdb_printf("%s", msg
);
1085 if ((regdump
== TRUE
) && (regs
!= NULL
)) {
1086 #if defined(__x86_64__)
1087 x86_saved_state64_t
*ss64p
= saved_state64(regs
);
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
,
1100 PC
= ss64p
->isf
.rip
;
1102 x86_saved_state32_t
*ss32p
= saved_state32(regs
);
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
);
1114 kdb_printf("Backtrace (CPU %d), "
1115 #if PRINT_ARGS_FROM_STACK_FRAME
1116 "Frame : Return Address (4 potential args on stack)\n", cn
);
1118 "Frame : Return Address\n", cn
);
1121 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
1122 vm_offset_t curframep
= (vm_offset_t
) frame
;
1127 if (curframep
& 0x3) {
1128 kdb_printf("Unaligned frame\n");
1132 if (!kvtophys(curframep
) ||
1133 !kvtophys(curframep
+ sizeof(cframe_t
) - 1)) {
1134 kdb_printf("No mapping exists for frame pointer\n");
1138 kdb_printf("%p : 0x%lx ", frame
, frame
->caller
);
1139 if (frame_index
< DUMPFRAMES
)
1140 raddrs
[frame_index
] = frame
->caller
;
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]);
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.
1155 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1159 frame
= frame
->prev
;
1162 if (frame_index
>= nframes
)
1163 kdb_printf("\tBacktrace continues...\n");
1168 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame
);
1171 /* Identify kernel modules in the backtrace and display their
1172 * load addresses and dependencies. This routine should walk
1173 * the kmod list safely.
1176 kmod_panic_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1179 kmod_panic_dump(&PC
, 1);
1181 panic_display_system_configuration();
1183 /* Release print backtrace lock, to permit other callers in the
1184 * event of panics on multiple processors.
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.
1191 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1192 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));