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
;
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", &boot_arg
, sizeof (boot_arg
))) {
171 if (boot_arg
& DB_HALT
) halt_in_debugger
=1;
172 if (boot_arg
& DB_PRT
) disable_debug_output
=FALSE
;
173 if (boot_arg
& DB_SLOG
) systemLogDiags
=TRUE
;
174 if (boot_arg
& DB_NMI
) panicDebugging
=TRUE
;
175 if (boot_arg
& DB_LOG_PI_SCRN
) logPanicDataToScreen
=TRUE
;
176 debug_boot_arg
= boot_arg
;
179 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram
, sizeof (commit_paniclog_to_nvram
)))
180 commit_paniclog_to_nvram
= 1;
183 * Entering the debugger will put the CPUs into a "safe"
186 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg
, sizeof (boot_arg
)))
187 pmsafe_debug
= boot_arg
;
190 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
192 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
198 #if DB_MACHINE_COMMANDS
199 db_machine_commands_install(ppc_db_commands
);
200 #endif /* DB_MACHINE_COMMANDS */
203 if (boot_arg
& DB_KDB
)
204 current_debugger
= KDB_CUR_DB
;
207 * Cause a breakpoint trap to the debugger before proceeding
208 * any further if the proper option bit was specified in
211 if (halt_in_debugger
&& (current_debugger
== KDB_CUR_DB
)) {
212 Debugger("inline call to debugger(machine_startup)");
213 halt_in_debugger
= 0;
216 #endif /* MACH_KDB */
218 if (PE_parse_boot_argn("preempt", &boot_arg
, sizeof (boot_arg
))) {
219 default_preemption_rate
= boot_arg
;
221 if (PE_parse_boot_argn("unsafe", &boot_arg
, sizeof (boot_arg
))) {
222 max_unsafe_quanta
= boot_arg
;
224 if (PE_parse_boot_argn("poll", &boot_arg
, sizeof (boot_arg
))) {
225 max_poll_quanta
= boot_arg
;
227 if (PE_parse_boot_argn("yield", &boot_arg
, sizeof (boot_arg
))) {
228 sched_poll_yield_shift
= boot_arg
;
230 if (PE_parse_boot_argn("idlehalt", &boot_arg
, sizeof (boot_arg
))) {
233 /* The I/O port to issue a read from, in the event of a panic. Useful for
234 * triggering logic analyzers.
236 if (PE_parse_boot_argn("panic_io_port", &boot_arg
, sizeof (boot_arg
))) {
237 /*I/O ports range from 0 through 0xFFFF */
238 panic_io_port
= boot_arg
& 0xffff;
244 ml_thrm_init(); /* Start thermal monitoring on this processor */
258 machine_info
.memory_size
= (typeof(machine_info
.memory_size
))mem_size
;
262 extern void *gPEEFIRuntimeServices
;
263 extern void *gPEEFISystemTable
;
266 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
267 * code or tables extracted from it, as desired without restriction.
269 * First, the polynomial itself and its table of feedback terms. The
271 * 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
273 * Note that we take it "backwards" and put the highest-order term in
274 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
275 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
278 * Note that the usual hardware shift register implementation, which
279 * is what we're using (we're merely optimizing it by doing eight-bit
280 * chunks at a time) shifts bits into the lowest-order term. In our
281 * implementation, that means shifting towards the right. Why do we
282 * do it this way? Because the calculated CRC must be transmitted in
283 * order from highest-order term to lowest-order term. UARTs transmit
284 * characters in order from LSB to MSB. By storing the CRC this way
285 * we hand it to the UART in the order low-byte to high-byte; the UART
286 * sends each low-bit to hight-bit; and the result is transmission bit
287 * by bit from highest- to lowest-order term without requiring any bit
288 * shuffling on our part. Reception works similarly
290 * The feedback terms table consists of 256, 32-bit entries. Notes
292 * The table can be generated at runtime if desired; code to do so
293 * is shown later. It might not be obvious, but the feedback
294 * terms simply represent the results of eight shift/xor opera
295 * tions for all combinations of data and CRC register values
297 * The values must be right-shifted by eight bits by the "updcrc
298 * logic; the shift must be unsigned (bring in zeroes). On some
299 * hardware you could probably optimize the shift in assembler by
300 * using byte-swap instructions
301 * polynomial $edb88320
304 * CRC32 code derived from work by Gary S. Brown.
307 static uint32_t crc32_tab
[] = {
308 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
309 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
310 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
311 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
312 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
313 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
314 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
315 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
316 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
317 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
318 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
319 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
320 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
321 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
322 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
323 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
324 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
325 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
326 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
327 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
328 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
329 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
330 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
331 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
332 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
333 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
334 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
335 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
336 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
337 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
338 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
339 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
340 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
341 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
342 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
343 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
344 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
345 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
346 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
347 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
348 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
349 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
350 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
354 crc32(uint32_t crc
, const void *buf
, size_t size
)
362 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
368 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
370 EFI_RUNTIME_SERVICES_64
*runtime
;
374 kprintf("Processing 64-bit EFI tables at %p\n", system_table
);
376 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
377 kprintf("Bad EFI system table signature\n");
380 // Verify signature of the system table
381 hdr_cksum
= system_table
->Hdr
.CRC32
;
382 system_table
->Hdr
.CRC32
= 0;
383 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
385 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
386 system_table
->Hdr
.CRC32
= hdr_cksum
;
387 if (cksum
!= hdr_cksum
) {
388 kprintf("Bad EFI system table checksum\n");
392 gPEEFISystemTable
= system_table
;
395 if (!cpu_mode_is64bit()) {
396 kprintf("Skipping 64-bit EFI runtime services for 32-bit legacy mode\n");
400 if(system_table
->RuntimeServices
== 0) {
401 kprintf("No runtime table present\n");
404 kprintf("RuntimeServices table at 0x%qx\n", system_table
->RuntimeServices
);
405 // 64-bit virtual address is OK for 64-bit EFI and 64/32-bit kernel.
406 runtime
= (EFI_RUNTIME_SERVICES_64
*) (uintptr_t)system_table
->RuntimeServices
;
407 kprintf("Checking runtime services table %p\n", runtime
);
408 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
409 kprintf("Bad EFI runtime table signature\n");
413 // Verify signature of runtime services table
414 hdr_cksum
= runtime
->Hdr
.CRC32
;
415 runtime
->Hdr
.CRC32
= 0;
416 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
418 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
419 runtime
->Hdr
.CRC32
= hdr_cksum
;
420 if (cksum
!= hdr_cksum
) {
421 kprintf("Bad EFI runtime table checksum\n");
425 gPEEFIRuntimeServices
= runtime
;
431 efi_set_tables_32(EFI_SYSTEM_TABLE_32
* system_table
)
433 EFI_RUNTIME_SERVICES_32
*runtime
;
437 kprintf("Processing 32-bit EFI tables at %p\n", system_table
);
439 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
440 kprintf("Bad EFI system table signature\n");
443 // Verify signature of the system table
444 hdr_cksum
= system_table
->Hdr
.CRC32
;
445 system_table
->Hdr
.CRC32
= 0;
446 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
448 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
449 system_table
->Hdr
.CRC32
= hdr_cksum
;
450 if (cksum
!= hdr_cksum
) {
451 kprintf("Bad EFI system table checksum\n");
455 gPEEFISystemTable
= system_table
;
458 if(system_table
->RuntimeServices
== 0) {
459 kprintf("No runtime table present\n");
462 kprintf("RuntimeServices table at 0x%x\n", system_table
->RuntimeServices
);
463 // 32-bit virtual address is OK for 32-bit EFI and 32-bit kernel.
464 // For a 64-bit kernel, booter will ensure pointer is zeroed out
465 runtime
= (EFI_RUNTIME_SERVICES_32
*) (intptr_t)system_table
->RuntimeServices
;
466 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
467 kprintf("Bad EFI runtime table signature\n");
471 // Verify signature of runtime services table
472 hdr_cksum
= runtime
->Hdr
.CRC32
;
473 runtime
->Hdr
.CRC32
= 0;
474 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
476 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
477 runtime
->Hdr
.CRC32
= hdr_cksum
;
478 if (cksum
!= hdr_cksum
) {
479 kprintf("Bad EFI runtime table checksum\n");
483 gPEEFIRuntimeServices
= runtime
;
489 /* Map in EFI runtime areas. */
493 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
495 kprintf("Initializing EFI runtime services\n");
499 vm_offset_t vm_size
, vm_addr
;
500 vm_map_offset_t phys_addr
;
501 EfiMemoryRange
*mptr
;
502 unsigned int msize
, mcount
;
505 msize
= args
->MemoryMapDescriptorSize
;
506 mcount
= args
->MemoryMapSize
/ msize
;
508 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
509 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
510 if (((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) ) {
511 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
512 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
513 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
514 #if defined(__i386__)
516 #elif defined(__x86_64__)
517 pmap_map_bd
/* K64todo resolve pmap layer inconsistency */
519 (vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
520 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
521 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
525 if ((args
->Version
!= kBootArgsVersion1
) || (args
->Version
== kBootArgsVersion1
&& args
->Revision
< kBootArgsRevision1_5
))
526 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
528 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
529 if (args
->efiMode
== kBootArgsEfiMode64
) {
530 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
532 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
540 /* Remap EFI runtime areas. */
542 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
544 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
546 kprintf("Reinitializing EFI runtime services\n");
548 if (args
->Version
!= kBootArgsVersion1
)
552 vm_offset_t vm_size
, vm_addr
;
553 vm_map_offset_t phys_addr
;
554 EfiMemoryRange
*mptr
;
555 unsigned int msize
, mcount
;
558 gPEEFISystemTable
= 0;
559 gPEEFIRuntimeServices
= 0;
561 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
563 kprintf("Old system table 0x%x, new 0x%x\n",
564 (uint32_t)args
->efiSystemTable
, system_table_offset
);
566 args
->efiSystemTable
= system_table_offset
;
568 kprintf("Old map:\n");
569 msize
= args
->MemoryMapDescriptorSize
;
570 mcount
= args
->MemoryMapSize
/ msize
;
571 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
572 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
573 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
575 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
576 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
577 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
579 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
583 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
584 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
586 kprintf("New map:\n");
587 msize
= args
->MemoryMapDescriptorSize
;
588 mcount
= (unsigned int )(map_size
/ msize
);
590 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
591 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
593 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
594 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
595 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
597 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
599 #if defined(__i386__)
601 #elif defined(__x86_64__)
602 pmap_map_bd
/* K64todo resolve pmap layer inconsistency */
604 (vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
605 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
606 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
610 if ((args
->Version
!= kBootArgsVersion1
) || (args
->Version
== kBootArgsVersion1
&& args
->Revision
< kBootArgsRevision1_5
))
611 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
613 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
614 if (args
->efiMode
== kBootArgsEfiMode64
) {
615 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
617 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
622 kprintf("Done reinitializing EFI runtime services\n");
628 * Find devices. The system is alive.
633 /* Ensure panic buffer is initialized. */
637 * Display CPU identification
639 cpuid_cpu_display("CPU identification");
640 cpuid_feature_display("CPU features");
641 cpuid_extfeature_display("CPU extended features");
644 * Initialize EFI runtime services.
651 * Set up to use floating point.
656 * Configure clock devices.
661 * Initialize MTRR from boot processor.
666 * Set up PAT for boot processor.
671 * Free lowmem pages and complete other setup
673 pmap_lowmem_finalize();
682 halt_all_cpus(FALSE
);
685 int reset_mem_on_reboot
= 1;
688 * Halt the system or reboot.
691 halt_all_cpus(boolean_t reboot
)
694 printf("MACH Reboot\n");
695 PEHaltRestart( kPERestartCPU
);
697 printf("CPU halted\n");
698 PEHaltRestart( kPEHaltCPU
);
704 /* Issue an I/O port read if one has been requested - this is an event logic
705 * analyzers can use as a trigger point.
709 panic_io_port_read(void) {
711 (void)inb(panic_io_port
);
714 /* For use with the MP rendezvous mechanism
719 machine_halt_cpu(__unused
void *arg
) {
720 panic_io_port_read();
721 pmCPUHalt(PM_HALT_DEBUG
);
729 unsigned long pi_size
= 0;
732 hw_atomic_add(&debug_mode
, 1);
733 if (!panic_is_inited
) {
739 printf("Debugger called: <%s>\n", message
);
740 kprintf("Debugger called: <%s>\n", message
);
743 * Skip the graphical panic box if no panic string.
744 * This is the case if we're being called from
745 * host_reboot(,HOST_REBOOT_DEBUGGER)
746 * as a quiet way into the debugger.
750 disable_preemption();
752 /* Issue an I/O port read if one has been requested - this is an event logic
753 * analyzers can use as a trigger point.
755 panic_io_port_read();
757 /* Obtain current frame pointer */
758 #if defined (__i386__)
759 __asm__
volatile("movl %%ebp, %0" : "=m" (stackptr
));
760 #elif defined (__x86_64__)
761 __asm__
volatile("movq %%rbp, %0" : "=m" (stackptr
));
764 /* Print backtrace - callee is internally synchronized */
765 panic_i386_backtrace(stackptr
, 20, NULL
, FALSE
, NULL
);
767 /* everything should be printed now so copy to NVRAM
770 if( debug_buf_size
> 0) {
771 /* Optionally sync the panic log, if any, to NVRAM
772 * This is the default.
774 if (commit_paniclog_to_nvram
) {
780 /* Now call the compressor */
781 /* XXX Consider using the WKdm compressor in the
782 * future, rather than just packing - would need to
783 * be co-ordinated with crashreporter, which decodes
784 * this post-restart. The compressor should be
785 * capable of in-place compression.
787 bufpos
= packA(debug_buf
,
788 (unsigned int) (debug_buf_ptr
- debug_buf
), debug_buf_size
);
789 /* If compression was successful,
790 * use the compressed length
792 pi_size
= bufpos
? bufpos
: (unsigned) (debug_buf_ptr
- debug_buf
);
794 /* Save panic log to non-volatile store
795 * Panic info handler must truncate data that is
796 * too long for this platform.
797 * This call must save data synchronously,
798 * since we can subsequently halt the system.
801 kprintf("Attempting to commit panic log to NVRAM\n");
802 /* The following sequence is a workaround for:
803 * <rdar://problem/5915669> SnowLeopard10A67: AppleEFINVRAM should not invoke
804 * any routines that use floating point (MMX in this case) when saving panic
805 * logs to nvram/flash.
810 pi_size
= PESavePanicInfo((unsigned char *)debug_buf
,
813 /* Uncompress in-place, to permit examination of
814 * the panic log by debuggers.
818 unpackA(debug_buf
, bufpos
);
824 if (!panicDebugging
) {
825 /* Clear the MP rendezvous function lock, in the event
826 * that a panic occurred while in that codepath.
828 mp_rendezvous_break_lock();
830 PEHaltRestart(kPEPanicRestartCPU
);
832 /* Force all CPUs to disable interrupts and HLT.
833 * We've panicked, and shouldn't depend on the
834 * PEHaltRestart() mechanism, which relies on several
835 * bits of infrastructure.
837 mp_rendezvous_no_intrs(machine_halt_cpu
, NULL
);
844 hw_atomic_sub(&debug_mode
, 1);
848 machine_boot_info(char *buf
, __unused vm_size_t size
)
864 } __attribute__((packed
));
866 typedef struct pasc pasc_t
;
868 /* Routines for address - symbol translation. Not called unless the "keepsyms"
869 * boot-arg is supplied.
873 panic_print_macho_symbol_name(kernel_mach_header_t
*mh
, vm_address_t search
)
875 kernel_nlist_t
*sym
= NULL
;
876 struct load_command
*cmd
;
877 kernel_segment_command_t
*orig_ts
= NULL
, *orig_le
= NULL
;
878 struct symtab_command
*orig_st
= NULL
;
880 char *strings
, *bestsym
= NULL
;
881 vm_address_t bestaddr
= 0, diff
, curdiff
;
883 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
885 cmd
= (struct load_command
*) &mh
[1];
886 for (i
= 0; i
< mh
->ncmds
; i
++) {
887 if (cmd
->cmd
== LC_SEGMENT_KERNEL
) {
888 kernel_segment_command_t
*orig_sg
= (kernel_segment_command_t
*) cmd
;
890 if (strncmp(SEG_TEXT
, orig_sg
->segname
,
891 sizeof(orig_sg
->segname
)) == 0)
893 else if (strncmp(SEG_LINKEDIT
, orig_sg
->segname
,
894 sizeof(orig_sg
->segname
)) == 0)
896 else if (strncmp("", orig_sg
->segname
,
897 sizeof(orig_sg
->segname
)) == 0)
898 orig_ts
= orig_sg
; /* kexts have a single unnamed segment */
900 else if (cmd
->cmd
== LC_SYMTAB
)
901 orig_st
= (struct symtab_command
*) cmd
;
903 cmd
= (struct load_command
*) ((uintptr_t) cmd
+ cmd
->cmdsize
);
906 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
909 /* kexts don't have a LINKEDIT segment for now, so we'll never get this far for kexts */
911 vm_offset_t slide
= ((vm_address_t
)mh
) - orig_ts
->vmaddr
;
913 search
-= slide
; /* adjusting search since the binary has slid */
915 if ((search
< orig_ts
->vmaddr
) ||
916 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
917 /* search out of range for this mach header */
921 sym
= (kernel_nlist_t
*)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->symoff
- orig_le
->fileoff
);
922 strings
= (char *)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->stroff
- orig_le
->fileoff
);
925 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
926 if (sym
[i
].n_type
& N_STAB
) continue;
928 if (sym
[i
].n_value
<= search
) {
929 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
930 if (curdiff
< diff
) {
932 bestaddr
= sym
[i
].n_value
;
933 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
938 if (bestsym
!= NULL
) {
940 kdb_printf("%s + 0x%lx", bestsym
, (unsigned long)diff
);
942 kdb_printf("%s", bestsym
);
949 extern kmod_info_t
* kmod
; /* the list of modules */
952 panic_print_kmod_symbol_name(vm_address_t search
)
954 kmod_info_t
* current_kmod
= kmod
;
956 while (current_kmod
!= NULL
) {
957 if ((current_kmod
->address
<= search
) &&
958 (current_kmod
->address
+ current_kmod
->size
> search
))
960 current_kmod
= current_kmod
->next
;
962 if (current_kmod
!= NULL
) {
963 /* if kexts had symbol table loaded, we'd call search_symbol_name again; alas, they don't */
964 kdb_printf("%s + %lu \n", current_kmod
->name
, (unsigned long)search
- current_kmod
->address
);
969 panic_print_symbol_name(vm_address_t search
)
971 /* try searching in the kernel */
972 if (panic_print_macho_symbol_name(&_mh_execute_header
, search
) == 0) {
973 /* that failed, now try to search for the right kext */
974 panic_print_kmod_symbol_name(search
);
978 /* Generate a backtrace, given a frame pointer - this routine
979 * should walk the stack safely. The trace is appended to the panic log
980 * and conditionally, to the console. If the trace contains kernel module
981 * addresses, display the module name, load address and dependencies.
984 #define DUMPFRAMES 32
985 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
987 panic_i386_backtrace(void *_frame
, int nframes
, const char *msg
, boolean_t regdump
, x86_saved_state_t
*regs
)
989 cframe_t
*frame
= (cframe_t
*)_frame
;
990 vm_offset_t raddrs
[DUMPFRAMES
];
993 volatile uint32_t *ppbtcnt
= &pbtcnt
;
994 uint64_t bt_tsc_timeout
;
995 boolean_t keepsyms
= FALSE
;
997 if(pbtcpu
!= cpu_number()) {
998 hw_atomic_add(&pbtcnt
, 1);
999 /* Spin on print backtrace lock, which serializes output
1000 * Continue anyway if a timeout occurs.
1002 hw_lock_to(&pbtlock
, LockTimeOutTSC
);
1003 pbtcpu
= cpu_number();
1006 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1009 kdb_printf("%s", msg
);
1012 if ((regdump
== TRUE
) && (regs
!= NULL
)) {
1013 #if defined(__x86_64__)
1014 x86_saved_state64_t
*ss64p
= saved_state64(regs
);
1016 "RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1017 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1018 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1019 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1020 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n",
1021 ss64p
->rax
, ss64p
->rbx
, ss64p
->rcx
, ss64p
->rdx
,
1022 ss64p
->isf
.rsp
, ss64p
->rbp
, ss64p
->rsi
, ss64p
->rdi
,
1023 ss64p
->r8
, ss64p
->r9
, ss64p
->r10
, ss64p
->r11
,
1024 ss64p
->r12
, ss64p
->r13
, ss64p
->r14
, ss64p
->r15
,
1025 ss64p
->isf
.rflags
, ss64p
->isf
.rip
, ss64p
->isf
.cs
,
1027 PC
= ss64p
->isf
.rip
;
1029 x86_saved_state32_t
*ss32p
= saved_state32(regs
);
1031 "EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n"
1032 "CR2: 0x%08x, EBP: 0x%08x, ESI: 0x%08x, EDI: 0x%08x\n"
1033 "EFL: 0x%08x, EIP: 0x%08x, CS: 0x%08x, DS: 0x%08x\n",
1034 ss32p
->eax
,ss32p
->ebx
,ss32p
->ecx
,ss32p
->edx
,
1035 ss32p
->cr2
,ss32p
->ebp
,ss32p
->esi
,ss32p
->edi
,
1036 ss32p
->efl
,ss32p
->eip
,ss32p
->cs
, ss32p
->ds
);
1041 kdb_printf("Backtrace (CPU %d), "
1042 #if PRINT_ARGS_FROM_STACK_FRAME
1043 "Frame : Return Address (4 potential args on stack)\n", cpu_number());
1045 "Frame : Return Address\n", cpu_number());
1048 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
1049 vm_offset_t curframep
= (vm_offset_t
) frame
;
1054 if (curframep
& 0x3) {
1055 kdb_printf("Unaligned frame\n");
1059 if (!kvtophys(curframep
) ||
1060 !kvtophys(curframep
+ sizeof(cframe_t
))) {
1061 kdb_printf("No mapping exists for frame pointer\n");
1065 kdb_printf("%p : 0x%lx ", frame
, frame
->caller
);
1066 if (frame_index
< DUMPFRAMES
)
1067 raddrs
[frame_index
] = frame
->caller
;
1069 #if PRINT_ARGS_FROM_STACK_FRAME
1070 if (kvtophys((vm_offset_t
)&(frame
->args
[3])))
1071 kdb_printf("(0x%x 0x%x 0x%x 0x%x) ",
1072 frame
->args
[0], frame
->args
[1],
1073 frame
->args
[2], frame
->args
[3]);
1076 /* Display address-symbol translation only if the "keepsyms"
1077 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1078 * This routine is potentially unsafe; also, function
1079 * boundary identification is unreliable after a strip -x.
1082 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1086 frame
= frame
->prev
;
1089 if (frame_index
>= nframes
)
1090 kdb_printf("\tBacktrace continues...\n");
1095 kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame
);
1098 /* Identify kernel modules in the backtrace and display their
1099 * load addresses and dependencies. This routine should walk
1100 * the kmod list safely.
1103 kmod_panic_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1106 kmod_panic_dump(&PC
, 1);
1108 panic_display_system_configuration();
1110 /* Release print backtrace lock, to permit other callers in the
1111 * event of panics on multiple processors.
1113 hw_lock_unlock(&pbtlock
);
1114 hw_atomic_sub(&pbtcnt
, 1);
1115 /* Wait for other processors to complete output
1116 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1118 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1119 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));
1122 void *apic_table
= NULL
;