2 * Copyright (c) 2000-2006 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>
97 #include <i386/mtrr.h>
98 #include <i386/pmCPU.h>
99 #include <architecture/i386/pio.h> /* inb() */
100 #include <pexpert/i386/boot.h>
102 #include <ddb/db_aout.h>
103 #endif /* MACH_KDB */
106 #include <vm/vm_map.h>
107 #include <vm/vm_kern.h>
109 #include <IOKit/IOPlatformExpert.h>
110 #include <IOKit/IOHibernatePrivate.h>
112 #include <pexpert/i386/efi.h>
114 #include <kern/thread.h>
115 #include <mach-o/loader.h>
116 #include <mach-o/nlist.h>
118 #include <libkern/kernel_mach_header.h>
120 static void machine_conf(void);
122 extern int default_preemption_rate
;
123 extern int max_unsafe_quanta
;
124 extern int max_poll_quanta
;
125 extern unsigned int panic_is_inited
;
129 volatile int pbtcpu
= -1;
130 hw_lock_data_t pbtlock
; /* backtrace print lock */
133 #if defined (__i386__)
134 #define PRINT_ARGS_FROM_STACK_FRAME 1
135 #elif defined (__x86_64__)
136 #define PRINT_ARGS_FROM_STACK_FRAME 0
138 #error unsupported architecture
142 typedef struct nlist_64 kernel_nlist_t
;
144 typedef struct nlist kernel_nlist_t
;
147 typedef struct _cframe_t
{
148 struct _cframe_t
*prev
;
150 #if PRINT_ARGS_FROM_STACK_FRAME
155 static unsigned panic_io_port
;
156 static unsigned commit_paniclog_to_nvram
;
158 unsigned int debug_boot_arg
;
161 machine_startup(void)
166 if( PE_get_hotkey( kPEControlKey
))
167 halt_in_debugger
= halt_in_debugger
? 0 : 1;
170 if (PE_parse_boot_argn("debug", &debug_boot_arg
, sizeof (debug_boot_arg
))) {
171 if (debug_boot_arg
& DB_HALT
) halt_in_debugger
=1;
172 if (debug_boot_arg
& DB_PRT
) disable_debug_output
=FALSE
;
173 if (debug_boot_arg
& DB_SLOG
) systemLogDiags
=TRUE
;
174 if (debug_boot_arg
& DB_NMI
) panicDebugging
=TRUE
;
175 if (debug_boot_arg
& DB_LOG_PI_SCRN
) logPanicDataToScreen
=TRUE
;
180 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram
, sizeof (commit_paniclog_to_nvram
)))
181 commit_paniclog_to_nvram
= 1;
184 * Entering the debugger will put the CPUs into a "safe"
187 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg
, sizeof (boot_arg
)))
188 pmsafe_debug
= boot_arg
;
191 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
193 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
199 #if DB_MACHINE_COMMANDS
200 db_machine_commands_install(ppc_db_commands
);
201 #endif /* DB_MACHINE_COMMANDS */
204 if (boot_arg
& DB_KDB
)
205 current_debugger
= KDB_CUR_DB
;
208 * Cause a breakpoint trap to the debugger before proceeding
209 * any further if the proper option bit was specified in
212 if (halt_in_debugger
&& (current_debugger
== KDB_CUR_DB
)) {
213 Debugger("inline call to debugger(machine_startup)");
214 halt_in_debugger
= 0;
217 #endif /* MACH_KDB */
219 if (PE_parse_boot_argn("preempt", &boot_arg
, sizeof (boot_arg
))) {
220 default_preemption_rate
= boot_arg
;
222 if (PE_parse_boot_argn("unsafe", &boot_arg
, sizeof (boot_arg
))) {
223 max_unsafe_quanta
= boot_arg
;
225 if (PE_parse_boot_argn("poll", &boot_arg
, sizeof (boot_arg
))) {
226 max_poll_quanta
= boot_arg
;
228 if (PE_parse_boot_argn("yield", &boot_arg
, sizeof (boot_arg
))) {
229 sched_poll_yield_shift
= boot_arg
;
231 if (PE_parse_boot_argn("idlehalt", &boot_arg
, sizeof (boot_arg
))) {
234 /* The I/O port to issue a read from, in the event of a panic. Useful for
235 * triggering logic analyzers.
237 if (PE_parse_boot_argn("panic_io_port", &boot_arg
, sizeof (boot_arg
))) {
238 /*I/O ports range from 0 through 0xFFFF */
239 panic_io_port
= boot_arg
& 0xffff;
245 ml_thrm_init(); /* Start thermal monitoring on this processor */
259 machine_info
.memory_size
= (typeof(machine_info
.memory_size
))mem_size
;
263 extern void *gPEEFIRuntimeServices
;
264 extern void *gPEEFISystemTable
;
267 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
268 * code or tables extracted from it, as desired without restriction.
270 * First, the polynomial itself and its table of feedback terms. The
272 * 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
274 * Note that we take it "backwards" and put the highest-order term in
275 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
276 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
279 * Note that the usual hardware shift register implementation, which
280 * is what we're using (we're merely optimizing it by doing eight-bit
281 * chunks at a time) shifts bits into the lowest-order term. In our
282 * implementation, that means shifting towards the right. Why do we
283 * do it this way? Because the calculated CRC must be transmitted in
284 * order from highest-order term to lowest-order term. UARTs transmit
285 * characters in order from LSB to MSB. By storing the CRC this way
286 * we hand it to the UART in the order low-byte to high-byte; the UART
287 * sends each low-bit to hight-bit; and the result is transmission bit
288 * by bit from highest- to lowest-order term without requiring any bit
289 * shuffling on our part. Reception works similarly
291 * The feedback terms table consists of 256, 32-bit entries. Notes
293 * The table can be generated at runtime if desired; code to do so
294 * is shown later. It might not be obvious, but the feedback
295 * terms simply represent the results of eight shift/xor opera
296 * tions for all combinations of data and CRC register values
298 * The values must be right-shifted by eight bits by the "updcrc
299 * logic; the shift must be unsigned (bring in zeroes). On some
300 * hardware you could probably optimize the shift in assembler by
301 * using byte-swap instructions
302 * polynomial $edb88320
305 * CRC32 code derived from work by Gary S. Brown.
308 static uint32_t crc32_tab
[] = {
309 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
310 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
311 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
312 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
313 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
314 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
315 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
316 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
317 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
318 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
319 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
320 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
321 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
322 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
323 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
324 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
325 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
326 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
327 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
328 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
329 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
330 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
331 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
332 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
333 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
334 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
335 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
336 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
337 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
338 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
339 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
340 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
341 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
342 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
343 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
344 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
345 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
346 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
347 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
348 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
349 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
350 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
351 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
355 crc32(uint32_t crc
, const void *buf
, size_t size
)
363 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
369 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
371 EFI_RUNTIME_SERVICES_64
*runtime
;
375 kprintf("Processing 64-bit EFI tables at %p\n", system_table
);
377 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
378 kprintf("Bad EFI system table signature\n");
381 // Verify signature of the system table
382 hdr_cksum
= system_table
->Hdr
.CRC32
;
383 system_table
->Hdr
.CRC32
= 0;
384 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
386 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
387 system_table
->Hdr
.CRC32
= hdr_cksum
;
388 if (cksum
!= hdr_cksum
) {
389 kprintf("Bad EFI system table checksum\n");
393 gPEEFISystemTable
= system_table
;
396 if (!cpu_mode_is64bit()) {
397 kprintf("Skipping 64-bit EFI runtime services for 32-bit legacy mode\n");
401 if(system_table
->RuntimeServices
== 0) {
402 kprintf("No runtime table present\n");
405 kprintf("RuntimeServices table at 0x%qx\n", system_table
->RuntimeServices
);
406 // 64-bit virtual address is OK for 64-bit EFI and 64/32-bit kernel.
407 runtime
= (EFI_RUNTIME_SERVICES_64
*) (uintptr_t)system_table
->RuntimeServices
;
408 kprintf("Checking runtime services table %p\n", runtime
);
409 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
410 kprintf("Bad EFI runtime table signature\n");
414 // Verify signature of runtime services table
415 hdr_cksum
= runtime
->Hdr
.CRC32
;
416 runtime
->Hdr
.CRC32
= 0;
417 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
419 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
420 runtime
->Hdr
.CRC32
= hdr_cksum
;
421 if (cksum
!= hdr_cksum
) {
422 kprintf("Bad EFI runtime table checksum\n");
426 gPEEFIRuntimeServices
= runtime
;
432 efi_set_tables_32(EFI_SYSTEM_TABLE_32
* system_table
)
434 EFI_RUNTIME_SERVICES_32
*runtime
;
438 kprintf("Processing 32-bit EFI tables at %p\n", system_table
);
440 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
441 kprintf("Bad EFI system table signature\n");
444 // Verify signature of the system table
445 hdr_cksum
= system_table
->Hdr
.CRC32
;
446 system_table
->Hdr
.CRC32
= 0;
447 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
449 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
450 system_table
->Hdr
.CRC32
= hdr_cksum
;
451 if (cksum
!= hdr_cksum
) {
452 kprintf("Bad EFI system table checksum\n");
456 gPEEFISystemTable
= system_table
;
459 if(system_table
->RuntimeServices
== 0) {
460 kprintf("No runtime table present\n");
463 kprintf("RuntimeServices table at 0x%x\n", system_table
->RuntimeServices
);
464 // 32-bit virtual address is OK for 32-bit EFI and 32-bit kernel.
465 // For a 64-bit kernel, booter will ensure pointer is zeroed out
466 runtime
= (EFI_RUNTIME_SERVICES_32
*) (intptr_t)system_table
->RuntimeServices
;
467 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
468 kprintf("Bad EFI runtime table signature\n");
472 // Verify signature of runtime services table
473 hdr_cksum
= runtime
->Hdr
.CRC32
;
474 runtime
->Hdr
.CRC32
= 0;
475 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
477 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
478 runtime
->Hdr
.CRC32
= hdr_cksum
;
479 if (cksum
!= hdr_cksum
) {
480 kprintf("Bad EFI runtime table checksum\n");
484 gPEEFIRuntimeServices
= runtime
;
490 /* Map in EFI runtime areas. */
494 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
496 kprintf("Initializing EFI runtime services\n");
500 vm_offset_t vm_size
, vm_addr
;
501 vm_map_offset_t phys_addr
;
502 EfiMemoryRange
*mptr
;
503 unsigned int msize
, mcount
;
506 msize
= args
->MemoryMapDescriptorSize
;
507 mcount
= args
->MemoryMapSize
/ msize
;
509 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
510 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
511 if (((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) ) {
512 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
513 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
514 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
515 #if defined(__i386__)
517 #elif defined(__x86_64__)
518 pmap_map_bd
/* K64todo resolve pmap layer inconsistency */
520 (vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
521 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
522 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
526 if ((args
->Version
!= kBootArgsVersion1
) || (args
->Version
== kBootArgsVersion1
&& args
->Revision
< kBootArgsRevision1_5
))
527 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
529 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
530 if (args
->efiMode
== kBootArgsEfiMode64
) {
531 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
533 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
541 /* Remap EFI runtime areas. */
543 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
545 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
547 kprintf("Reinitializing EFI runtime services\n");
549 if (args
->Version
!= kBootArgsVersion1
)
553 vm_offset_t vm_size
, vm_addr
;
554 vm_map_offset_t phys_addr
;
555 EfiMemoryRange
*mptr
;
556 unsigned int msize
, mcount
;
559 gPEEFISystemTable
= 0;
560 gPEEFIRuntimeServices
= 0;
562 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
564 kprintf("Old system table 0x%x, new 0x%x\n",
565 (uint32_t)args
->efiSystemTable
, system_table_offset
);
567 args
->efiSystemTable
= system_table_offset
;
569 kprintf("Old map:\n");
570 msize
= args
->MemoryMapDescriptorSize
;
571 mcount
= args
->MemoryMapSize
/ msize
;
572 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
573 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
574 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
576 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
577 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
578 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
580 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
584 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
585 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
587 kprintf("New map:\n");
588 msize
= args
->MemoryMapDescriptorSize
;
589 mcount
= (unsigned int )(map_size
/ msize
);
591 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
592 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
594 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
595 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
596 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
598 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
600 #if defined(__i386__)
602 #elif defined(__x86_64__)
603 pmap_map_bd
/* K64todo resolve pmap layer inconsistency */
605 (vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
606 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
607 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
611 if ((args
->Version
!= kBootArgsVersion1
) || (args
->Version
== kBootArgsVersion1
&& args
->Revision
< kBootArgsRevision1_5
))
612 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
614 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
615 if (args
->efiMode
== kBootArgsEfiMode64
) {
616 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
618 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
623 kprintf("Done reinitializing EFI runtime services\n");
629 * Find devices. The system is alive.
634 /* Ensure panic buffer is initialized. */
638 * Display CPU identification
640 cpuid_cpu_display("CPU identification");
641 cpuid_feature_display("CPU features");
642 cpuid_extfeature_display("CPU extended features");
645 * Initialize EFI runtime services.
652 * Set up to use floating point.
657 * Configure clock devices.
662 * Initialize MTRR from boot processor.
667 * Set up PAT for boot processor.
672 * Free lowmem pages and complete other setup
674 pmap_lowmem_finalize();
683 halt_all_cpus(FALSE
);
686 int reset_mem_on_reboot
= 1;
689 * Halt the system or reboot.
692 halt_all_cpus(boolean_t reboot
)
695 printf("MACH Reboot\n");
696 PEHaltRestart( kPERestartCPU
);
698 printf("CPU halted\n");
699 PEHaltRestart( kPEHaltCPU
);
705 /* Issue an I/O port read if one has been requested - this is an event logic
706 * analyzers can use as a trigger point.
710 panic_io_port_read(void) {
712 (void)inb(panic_io_port
);
715 /* For use with the MP rendezvous mechanism
719 machine_halt_cpu(__unused
void *arg
) {
720 panic_io_port_read();
721 pmCPUHalt(PM_HALT_DEBUG
);
728 unsigned long pi_size
= 0;
731 hw_atomic_add(&debug_mode
, 1);
732 if (!panic_is_inited
) {
738 printf("Debugger called: <%s>\n", message
);
739 kprintf("Debugger called: <%s>\n", message
);
742 * Skip the graphical panic box if no panic string.
743 * This is the case if we're being called from
744 * host_reboot(,HOST_REBOOT_DEBUGGER)
745 * as a quiet way into the debugger.
749 disable_preemption();
751 /* Issue an I/O port read if one has been requested - this is an event logic
752 * analyzers can use as a trigger point.
754 panic_io_port_read();
756 /* Obtain current frame pointer */
757 #if defined (__i386__)
758 __asm__
volatile("movl %%ebp, %0" : "=m" (stackptr
));
759 #elif defined (__x86_64__)
760 __asm__
volatile("movq %%rbp, %0" : "=m" (stackptr
));
763 /* Print backtrace - callee is internally synchronized */
764 panic_i386_backtrace(stackptr
, 32, NULL
, FALSE
, NULL
);
766 /* everything should be printed now so copy to NVRAM
769 if( debug_buf_size
> 0) {
770 /* Optionally sync the panic log, if any, to NVRAM
771 * This is the default.
773 if (commit_paniclog_to_nvram
) {
779 /* Now call the compressor */
780 /* XXX Consider using the WKdm compressor in the
781 * future, rather than just packing - would need to
782 * be co-ordinated with crashreporter, which decodes
783 * this post-restart. The compressor should be
784 * capable of in-place compression.
786 bufpos
= packA(debug_buf
,
787 (unsigned int) (debug_buf_ptr
- debug_buf
), debug_buf_size
);
788 /* If compression was successful,
789 * use the compressed length
791 pi_size
= bufpos
? bufpos
: (unsigned) (debug_buf_ptr
- debug_buf
);
793 /* Save panic log to non-volatile store
794 * Panic info handler must truncate data that is
795 * too long for this platform.
796 * This call must save data synchronously,
797 * since we can subsequently halt the system.
800 kprintf("Attempting to commit panic log to NVRAM\n");
801 /* The following sequence is a workaround for:
802 * <rdar://problem/5915669> SnowLeopard10A67: AppleEFINVRAM should not invoke
803 * any routines that use floating point (MMX in this case) when saving panic
804 * logs to nvram/flash.
809 pi_size
= PESavePanicInfo((unsigned char *)debug_buf
,
812 /* Uncompress in-place, to permit examination of
813 * the panic log by debuggers.
817 unpackA(debug_buf
, bufpos
);
822 /* If the user won't be able to read the dialog,
823 * don't bother trying to show it
825 if (!PE_reboot_on_panic())
828 if (!panicDebugging
) {
829 /* Clear the MP rendezvous function lock, in the event
830 * that a panic occurred while in that codepath.
832 mp_rendezvous_break_lock();
833 if (PE_reboot_on_panic()) {
834 PEHaltRestart(kPEPanicRestartCPU
);
837 /* Force all CPUs to disable interrupts and HLT.
838 * We've panicked, and shouldn't depend on the
839 * PEHaltRestart() mechanism, which relies on several
840 * bits of infrastructure.
842 mp_rendezvous_no_intrs(machine_halt_cpu
, NULL
);
848 hw_atomic_sub(&debug_mode
, 1);
852 machine_boot_info(char *buf
, __unused vm_size_t size
)
868 } __attribute__((packed
));
870 typedef struct pasc pasc_t
;
872 /* Routines for address - symbol translation. Not called unless the "keepsyms"
873 * boot-arg is supplied.
877 panic_print_macho_symbol_name(kernel_mach_header_t
*mh
, vm_address_t search
)
879 kernel_nlist_t
*sym
= NULL
;
880 struct load_command
*cmd
;
881 kernel_segment_command_t
*orig_ts
= NULL
, *orig_le
= NULL
;
882 struct symtab_command
*orig_st
= NULL
;
884 char *strings
, *bestsym
= NULL
;
885 vm_address_t bestaddr
= 0, diff
, curdiff
;
887 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
889 cmd
= (struct load_command
*) &mh
[1];
890 for (i
= 0; i
< mh
->ncmds
; i
++) {
891 if (cmd
->cmd
== LC_SEGMENT_KERNEL
) {
892 kernel_segment_command_t
*orig_sg
= (kernel_segment_command_t
*) cmd
;
894 if (strncmp(SEG_TEXT
, orig_sg
->segname
,
895 sizeof(orig_sg
->segname
)) == 0)
897 else if (strncmp(SEG_LINKEDIT
, orig_sg
->segname
,
898 sizeof(orig_sg
->segname
)) == 0)
900 else if (strncmp("", orig_sg
->segname
,
901 sizeof(orig_sg
->segname
)) == 0)
902 orig_ts
= orig_sg
; /* kexts have a single unnamed segment */
904 else if (cmd
->cmd
== LC_SYMTAB
)
905 orig_st
= (struct symtab_command
*) cmd
;
907 cmd
= (struct load_command
*) ((uintptr_t) cmd
+ cmd
->cmdsize
);
910 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
913 /* kexts don't have a LINKEDIT segment for now, so we'll never get this far for kexts */
915 vm_offset_t slide
= ((vm_address_t
)mh
) - orig_ts
->vmaddr
;
917 search
-= slide
; /* adjusting search since the binary has slid */
919 if ((search
< orig_ts
->vmaddr
) ||
920 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
921 /* search out of range for this mach header */
925 sym
= (kernel_nlist_t
*)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->symoff
- orig_le
->fileoff
);
926 strings
= (char *)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->stroff
- orig_le
->fileoff
);
929 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
930 if (sym
[i
].n_type
& N_STAB
) continue;
932 if (sym
[i
].n_value
<= search
) {
933 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
934 if (curdiff
< diff
) {
936 bestaddr
= sym
[i
].n_value
;
937 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
942 if (bestsym
!= NULL
) {
944 kdb_printf("%s + 0x%lx", bestsym
, (unsigned long)diff
);
946 kdb_printf("%s", bestsym
);
953 extern kmod_info_t
* kmod
; /* the list of modules */
956 panic_print_kmod_symbol_name(vm_address_t search
)
958 kmod_info_t
* current_kmod
= kmod
;
960 while (current_kmod
!= NULL
) {
961 if ((current_kmod
->address
<= search
) &&
962 (current_kmod
->address
+ current_kmod
->size
> search
))
964 current_kmod
= current_kmod
->next
;
966 if (current_kmod
!= NULL
) {
967 /* if kexts had symbol table loaded, we'd call search_symbol_name again; alas, they don't */
968 kdb_printf("%s + %lu \n", current_kmod
->name
, (unsigned long)search
- current_kmod
->address
);
973 panic_print_symbol_name(vm_address_t search
)
975 /* try searching in the kernel */
976 if (panic_print_macho_symbol_name(&_mh_execute_header
, search
) == 0) {
977 /* that failed, now try to search for the right kext */
978 panic_print_kmod_symbol_name(search
);
982 /* Generate a backtrace, given a frame pointer - this routine
983 * should walk the stack safely. The trace is appended to the panic log
984 * and conditionally, to the console. If the trace contains kernel module
985 * addresses, display the module name, load address and dependencies.
988 #define DUMPFRAMES 32
989 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
991 panic_i386_backtrace(void *_frame
, int nframes
, const char *msg
, boolean_t regdump
, x86_saved_state_t
*regs
)
993 cframe_t
*frame
= (cframe_t
*)_frame
;
994 vm_offset_t raddrs
[DUMPFRAMES
];
997 volatile uint32_t *ppbtcnt
= &pbtcnt
;
998 uint64_t bt_tsc_timeout
;
999 boolean_t keepsyms
= FALSE
;
1001 if(pbtcpu
!= cpu_number()) {
1002 hw_atomic_add(&pbtcnt
, 1);
1003 /* Spin on print backtrace lock, which serializes output
1004 * Continue anyway if a timeout occurs.
1006 hw_lock_to(&pbtlock
, LockTimeOutTSC
);
1007 pbtcpu
= cpu_number();
1010 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1013 kdb_printf("%s", msg
);
1016 if ((regdump
== TRUE
) && (regs
!= NULL
)) {
1017 #if defined(__x86_64__)
1018 x86_saved_state64_t
*ss64p
= saved_state64(regs
);
1020 "RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1021 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1022 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1023 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1024 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n",
1025 ss64p
->rax
, ss64p
->rbx
, ss64p
->rcx
, ss64p
->rdx
,
1026 ss64p
->isf
.rsp
, ss64p
->rbp
, ss64p
->rsi
, ss64p
->rdi
,
1027 ss64p
->r8
, ss64p
->r9
, ss64p
->r10
, ss64p
->r11
,
1028 ss64p
->r12
, ss64p
->r13
, ss64p
->r14
, ss64p
->r15
,
1029 ss64p
->isf
.rflags
, ss64p
->isf
.rip
, ss64p
->isf
.cs
,
1031 PC
= ss64p
->isf
.rip
;
1033 x86_saved_state32_t
*ss32p
= saved_state32(regs
);
1035 "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
1036 "CR2: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
1037 "EFL: 0x%08x, EIP: 0x%08x, CS: 0x%08x, DS: 0x%08x\n",
1038 ss32p
->eax
,ss32p
->ebx
,ss32p
->ecx
,ss32p
->edx
,
1039 ss32p
->cr2
,ss32p
->ebp
,ss32p
->esi
,ss32p
->edi
,
1040 ss32p
->efl
,ss32p
->eip
,ss32p
->cs
, ss32p
->ds
);
1045 kdb_printf("Backtrace (CPU %d), "
1046 #if PRINT_ARGS_FROM_STACK_FRAME
1047 "Frame : Return Address (4 potential args on stack)\n", cpu_number());
1049 "Frame : Return Address\n", cpu_number());
1052 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
1053 vm_offset_t curframep
= (vm_offset_t
) frame
;
1058 if (curframep
& 0x3) {
1059 kdb_printf("Unaligned frame\n");
1063 if (!kvtophys(curframep
) ||
1064 !kvtophys(curframep
+ sizeof(cframe_t
))) {
1065 kdb_printf("No mapping exists for frame pointer\n");
1069 kdb_printf("%p : 0x%lx ", frame
, frame
->caller
);
1070 if (frame_index
< DUMPFRAMES
)
1071 raddrs
[frame_index
] = frame
->caller
;
1073 #if PRINT_ARGS_FROM_STACK_FRAME
1074 if (kvtophys((vm_offset_t
)&(frame
->args
[3])))
1075 kdb_printf("(0x%x 0x%x 0x%x 0x%x) ",
1076 frame
->args
[0], frame
->args
[1],
1077 frame
->args
[2], frame
->args
[3]);
1080 /* Display address-symbol translation only if the "keepsyms"
1081 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1082 * This routine is potentially unsafe; also, function
1083 * boundary identification is unreliable after a strip -x.
1086 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1090 frame
= frame
->prev
;
1093 if (frame_index
>= nframes
)
1094 kdb_printf("\tBacktrace continues...\n");
1099 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame
);
1102 /* Identify kernel modules in the backtrace and display their
1103 * load addresses and dependencies. This routine should walk
1104 * the kmod list safely.
1107 kmod_panic_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1110 kmod_panic_dump(&PC
, 1);
1112 panic_display_system_configuration();
1114 /* Release print backtrace lock, to permit other callers in the
1115 * event of panics on multiple processors.
1117 hw_lock_unlock(&pbtlock
);
1118 hw_atomic_sub(&pbtcnt
, 1);
1119 /* Wait for other processors to complete output
1120 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1122 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1123 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));
1126 void *apic_table
= NULL
;