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>
126 #define DPRINTF(x...) kprintf(x)
128 #define DPRINTF(x...)
131 static void machine_conf(void);
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
;
140 volatile int pbtcpu
= -1;
141 hw_lock_data_t pbtlock
; /* backtrace print lock */
144 volatile int panic_double_fault_cpu
= -1;
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
151 #error unsupported architecture
155 typedef struct nlist_64 kernel_nlist_t
;
157 typedef struct nlist kernel_nlist_t
;
160 typedef struct _cframe_t
{
161 struct _cframe_t
*prev
;
163 #if PRINT_ARGS_FROM_STACK_FRAME
168 static unsigned panic_io_port
;
169 static unsigned commit_paniclog_to_nvram
;
171 unsigned int debug_boot_arg
;
174 machine_startup(void)
179 if( PE_get_hotkey( kPEControlKey
))
180 halt_in_debugger
= halt_in_debugger
? 0 : 1;
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
;
193 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram
, sizeof (commit_paniclog_to_nvram
)))
194 commit_paniclog_to_nvram
= 1;
197 * Entering the debugger will put the CPUs into a "safe"
200 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg
, sizeof (boot_arg
)))
201 pmsafe_debug
= boot_arg
;
204 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
206 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
212 #if DB_MACHINE_COMMANDS
213 db_machine_commands_install(ppc_db_commands
);
214 #endif /* DB_MACHINE_COMMANDS */
217 if (boot_arg
& DB_KDB
)
218 current_debugger
= KDB_CUR_DB
;
221 * Cause a breakpoint trap to the debugger before proceeding
222 * any further if the proper option bit was specified in
225 if (halt_in_debugger
&& (current_debugger
== KDB_CUR_DB
)) {
226 Debugger("inline call to debugger(machine_startup)");
227 halt_in_debugger
= 0;
230 #endif /* MACH_KDB */
232 if (PE_parse_boot_argn("preempt", &boot_arg
, sizeof (boot_arg
))) {
233 default_preemption_rate
= boot_arg
;
235 if (PE_parse_boot_argn("unsafe", &boot_arg
, sizeof (boot_arg
))) {
236 max_unsafe_quanta
= boot_arg
;
238 if (PE_parse_boot_argn("poll", &boot_arg
, sizeof (boot_arg
))) {
239 max_poll_quanta
= boot_arg
;
241 if (PE_parse_boot_argn("yield", &boot_arg
, sizeof (boot_arg
))) {
242 sched_poll_yield_shift
= boot_arg
;
244 /* The I/O port to issue a read from, in the event of a panic. Useful for
245 * triggering logic analyzers.
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;
255 ml_thrm_init(); /* Start thermal monitoring on this processor */
269 machine_info
.memory_size
= (typeof(machine_info
.memory_size
))mem_size
;
273 extern void *gPEEFIRuntimeServices
;
274 extern void *gPEEFISystemTable
;
277 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
278 * code or tables extracted from it, as desired without restriction.
280 * First, the polynomial itself and its table of feedback terms. The
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
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
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
301 * The feedback terms table consists of 256, 32-bit entries. Notes
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
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
315 * CRC32 code derived from work by Gary S. Brown.
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
365 crc32(uint32_t crc
, const void *buf
, size_t size
)
373 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
379 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
381 EFI_RUNTIME_SERVICES_64
*runtime
;
385 DPRINTF("Processing 64-bit EFI tables at %p\n", system_table
);
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");
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
);
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");
409 gPEEFISystemTable
= system_table
;
411 if (!cpu_mode_is64bit()) {
412 kprintf("Skipping 64-bit EFI runtime services for 32-bit legacy mode\n");
416 if(system_table
->RuntimeServices
== 0) {
417 kprintf("No runtime table present\n");
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");
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
);
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");
441 gPEEFIRuntimeServices
= runtime
;
447 efi_set_tables_32(EFI_SYSTEM_TABLE_32
* system_table
)
449 EFI_RUNTIME_SERVICES_32
*runtime
;
453 DPRINTF("Processing 32-bit EFI tables at %p\n", system_table
);
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");
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
);
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");
478 gPEEFISystemTable
= system_table
;
480 if(system_table
->RuntimeServices
== 0) {
481 kprintf("No runtime table present\n");
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
*)
489 (system_table
->RuntimeServices
| VM_MIN_KERNEL_ADDRESS
);
491 system_table
->RuntimeServices
;
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");
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
);
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");
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
);
524 gPEEFIRuntimeServices
= runtime
;
530 /* Map in EFI runtime areas. */
534 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
536 kprintf("Initializing EFI runtime services\n");
540 vm_offset_t vm_size
, vm_addr
;
541 vm_map_offset_t phys_addr
;
542 EfiMemoryRange
*mptr
;
543 unsigned int msize
, mcount
;
546 msize
= args
->MemoryMapDescriptorSize
;
547 mcount
= args
->MemoryMapSize
/ msize
;
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
;
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
;
570 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
571 DPRINTF(" Type: %x phys: %p EFIv: %p kv: %p size: %p\n",
573 (void *) (uintptr_t) phys_addr
,
574 (void *) (uintptr_t) mptr
->VirtualStart
,
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
);
583 if (args
->Version
!= kBootArgsVersion2
)
584 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
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
));
590 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
598 /* Remap EFI runtime areas. */
600 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
602 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
604 kprintf("Reinitializing EFI runtime services\n");
608 vm_offset_t vm_size
, vm_addr
;
609 vm_map_offset_t phys_addr
;
610 EfiMemoryRange
*mptr
;
611 unsigned int msize
, mcount
;
614 gPEEFISystemTable
= 0;
615 gPEEFIRuntimeServices
= 0;
617 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
619 kprintf("Old system table 0x%x, new 0x%x\n",
620 (uint32_t)args
->efiSystemTable
, system_table_offset
);
622 args
->efiSystemTable
= system_table_offset
;
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
) {
631 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
632 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
635 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
636 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
638 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
640 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
644 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
645 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
647 kprintf("New map:\n");
648 msize
= args
->MemoryMapDescriptorSize
;
649 mcount
= (unsigned int )(map_size
/ msize
);
651 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
652 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
654 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
655 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
657 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
658 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
660 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
662 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
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
);
670 if (args
->Version
!= kBootArgsVersion2
)
671 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
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
));
677 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
682 kprintf("Done reinitializing EFI runtime services\n");
688 * Find devices. The system is alive.
693 /* Ensure panic buffer is initialized. */
697 * Display CPU identification
699 cpuid_cpu_display("CPU identification");
700 cpuid_feature_display("CPU features");
701 cpuid_extfeature_display("CPU extended features");
704 * Initialize EFI runtime services.
711 * Set up to use floating point.
716 * Configure clock devices.
722 * Initialize MTRR from boot processor.
727 * Set up PAT for boot processor.
733 * Free lowmem pages and complete other setup
735 pmap_lowmem_finalize();
744 halt_all_cpus(FALSE
);
747 int reset_mem_on_reboot
= 1;
750 * Halt the system or reboot.
753 halt_all_cpus(boolean_t reboot
)
756 printf("MACH Reboot\n");
757 PEHaltRestart( kPERestartCPU
);
759 printf("CPU halted\n");
760 PEHaltRestart( kPEHaltCPU
);
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.
771 panic_io_port_read(void) {
773 (void)inb(panic_io_port
);
776 /* For use with the MP rendezvous mechanism
779 uint64_t panic_restart_timeout
= ~(0ULL);
782 machine_halt_cpu(void) {
783 panic_io_port_read();
785 if (panic_restart_timeout
!= ~(0ULL)) {
786 uint64_t deadline
= mach_absolute_time() + panic_restart_timeout
;
787 while (mach_absolute_time() < deadline
) {
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->
796 (*PE_halt_restart
)(kPERestartCPU
);
798 pmCPUHalt(PM_HALT_DEBUG
);
805 unsigned long pi_size
= 0;
807 int cn
= cpu_number();
809 hw_atomic_add(&debug_mode
, 1);
810 if (!panic_is_inited
) {
815 printf("Debugger called: <%s>\n", message
);
816 kprintf("Debugger called: <%s>\n", message
);
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.
826 disable_preemption();
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.
831 panic_io_port_read();
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
));
840 /* Print backtrace - callee is internally synchronized */
841 panic_i386_backtrace(stackptr
, ((panic_double_fault_cpu
== cn
) ? 80: 48), NULL
, FALSE
, NULL
);
843 /* everything should be printed now so copy to NVRAM
846 if( debug_buf_size
> 0) {
847 /* Optionally sync the panic log, if any, to NVRAM
848 * This is the default.
850 if (commit_paniclog_to_nvram
) {
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.
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
868 pi_size
= bufpos
? bufpos
: (unsigned) (debug_buf_ptr
- debug_buf
);
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.
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.
886 kprintf("Attempting to commit panic log to NVRAM\n");
887 pi_size
= PESavePanicInfo((unsigned char *)debug_buf
,
891 /* Uncompress in-place, to permit examination of
892 * the panic log by debuggers.
896 unpackA(debug_buf
, bufpos
);
901 /* If the user won't be able to read the dialog,
902 * don't bother trying to show it
904 if (!PE_reboot_on_panic())
907 if (!panicDebugging
) {
909 /* Clear the MP rendezvous function lock, in the event
910 * that a panic occurred while in that codepath.
912 mp_rendezvous_break_lock();
913 if (PE_reboot_on_panic()) {
915 (*PE_halt_restart
)(kPERestartCPU
);
918 /* Non-maskably interrupt all other processors
919 * If a restart timeout is specified, this processor
920 * will attempt a restart.
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
);
934 hw_atomic_sub(&debug_mode
, 1);
938 machine_boot_info(char *buf
, __unused vm_size_t size
)
944 /* Routines for address - symbol translation. Not called unless the "keepsyms"
945 * boot-arg is supplied.
949 panic_print_macho_symbol_name(kernel_mach_header_t
*mh
, vm_address_t search
, const char *module_name
)
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
;
956 char *strings
, *bestsym
= NULL
;
957 vm_address_t bestaddr
= 0, diff
, curdiff
;
959 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
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
;
966 if (strncmp(SEG_TEXT
, orig_sg
->segname
,
967 sizeof(orig_sg
->segname
)) == 0)
969 else if (strncmp(SEG_LINKEDIT
, orig_sg
->segname
,
970 sizeof(orig_sg
->segname
)) == 0)
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 */
976 else if (cmd
->cmd
== LC_SYMTAB
)
977 orig_st
= (struct symtab_command
*) cmd
;
979 cmd
= (struct load_command
*) ((uintptr_t) cmd
+ cmd
->cmdsize
);
982 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
985 if ((search
< orig_ts
->vmaddr
) ||
986 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
987 /* search out of range for this mach header */
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
);
995 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
996 if (sym
[i
].n_type
& N_STAB
) continue;
998 if (sym
[i
].n_value
<= search
) {
999 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
1000 if (curdiff
< diff
) {
1002 bestaddr
= sym
[i
].n_value
;
1003 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
1008 if (bestsym
!= NULL
) {
1010 kdb_printf("%s : %s + 0x%lx", module_name
, bestsym
, (unsigned long)diff
);
1012 kdb_printf("%s : %s", module_name
, bestsym
);
1019 extern kmod_info_t
* kmod
; /* the list of modules */
1022 panic_print_kmod_symbol_name(vm_address_t search
)
1026 if (gLoadedKextSummaries
== NULL
)
1028 for (i
= 0; i
< gLoadedKextSummaries
->numSummaries
; ++i
) {
1029 OSKextLoadedKextSummary
*summary
= gLoadedKextSummaries
->summaries
+ i
;
1031 if ((search
>= summary
->address
) &&
1032 (search
< (summary
->address
+ summary
->size
)))
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
);
1044 panic_print_symbol_name(vm_address_t search
)
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
);
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.
1059 #define DUMPFRAMES 32
1060 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
1062 panic_i386_backtrace(void *_frame
, int nframes
, const char *msg
, boolean_t regdump
, x86_saved_state_t
*regs
)
1064 cframe_t
*frame
= (cframe_t
*)_frame
;
1065 vm_offset_t raddrs
[DUMPFRAMES
];
1068 volatile uint32_t *ppbtcnt
= &pbtcnt
;
1069 uint64_t bt_tsc_timeout
;
1070 boolean_t keepsyms
= FALSE
;
1071 int cn
= cpu_number();
1074 hw_atomic_add(&pbtcnt
, 1);
1075 /* Spin on print backtrace lock, which serializes output
1076 * Continue anyway if a timeout occurs.
1078 hw_lock_to(&pbtlock
, LockTimeOutTSC
*2);
1082 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1085 kdb_printf("%s", msg
);
1088 if ((regdump
== TRUE
) && (regs
!= NULL
)) {
1089 #if defined(__x86_64__)
1090 x86_saved_state64_t
*ss64p
= saved_state64(regs
);
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
,
1103 PC
= ss64p
->isf
.rip
;
1105 x86_saved_state32_t
*ss32p
= saved_state32(regs
);
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
);
1117 kdb_printf("Backtrace (CPU %d), "
1118 #if PRINT_ARGS_FROM_STACK_FRAME
1119 "Frame : Return Address (4 potential args on stack)\n", cn
);
1121 "Frame : Return Address\n", cn
);
1124 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
1125 vm_offset_t curframep
= (vm_offset_t
) frame
;
1130 if (curframep
& 0x3) {
1131 kdb_printf("Unaligned frame\n");
1135 if (!kvtophys(curframep
) ||
1136 !kvtophys(curframep
+ sizeof(cframe_t
) - 1)) {
1137 kdb_printf("No mapping exists for frame pointer\n");
1141 kdb_printf("%p : 0x%lx ", frame
, frame
->caller
);
1142 if (frame_index
< DUMPFRAMES
)
1143 raddrs
[frame_index
] = frame
->caller
;
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]);
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.
1158 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1162 frame
= frame
->prev
;
1165 if (frame_index
>= nframes
)
1166 kdb_printf("\tBacktrace continues...\n");
1171 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame
);
1174 /* Identify kernel modules in the backtrace and display their
1175 * load addresses and dependencies. This routine should walk
1176 * the kmod list safely.
1179 kmod_panic_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1182 kmod_panic_dump(&PC
, 1);
1184 panic_display_system_configuration();
1186 /* Release print backtrace lock, to permit other callers in the
1187 * event of panics on multiple processors.
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.
1194 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1195 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));