2 * Copyright (c) 2000-2005 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>
89 #include <i386/misc_protos.h>
90 #include <i386/mtrr.h>
91 #include <i386/machine_routines.h>
92 #include <i386/pmCPU.h>
93 #include <i386/postcode.h>
94 #include <architecture/i386/pio.h> /* inb() */
95 #include <pexpert/i386/boot.h>
97 #include <ddb/db_aout.h>
101 #include <vm/vm_map.h>
102 #include <vm/vm_kern.h>
104 #include <i386/mp_desc.h>
106 #include <i386/cpuid.h>
108 #include <IOKit/IOPlatformExpert.h>
109 #include <IOKit/IOHibernatePrivate.h>
111 #include <pexpert/i386/efi.h>
113 #include <kern/thread.h>
114 #include <i386/thread.h>
115 #include <mach-o/loader.h>
116 #include <mach-o/nlist.h>
118 void enable_bluebox(void);
119 void disable_bluebox(void);
121 static void machine_conf(void);
123 extern int default_preemption_rate
;
124 extern int max_unsafe_quanta
;
125 extern int max_poll_quanta
;
127 extern unsigned int panic_is_inited
;
131 static int packAsc (uint8_t *inbuf
, unsigned int length
);
132 extern int kdb_printf(const char *fmt
, ...);
134 volatile int pbtcpu
= -1;
135 hw_lock_data_t pbtlock
; /* backtrace print lock */
138 extern const char version
[];
140 typedef struct _cframe_t
{
141 struct _cframe_t
*prev
;
146 void panic_i386_backtrace(void *_frame
, int nframes
);
148 static unsigned panic_io_port
= 0;
156 if( PE_get_hotkey( kPEControlKey
))
157 halt_in_debugger
= halt_in_debugger
? 0 : 1;
160 if (PE_parse_boot_arg("debug", &boot_arg
)) {
161 if (boot_arg
& DB_HALT
) halt_in_debugger
=1;
162 if (boot_arg
& DB_PRT
) disableDebugOuput
=FALSE
;
163 if (boot_arg
& DB_SLOG
) systemLogDiags
=TRUE
;
164 if (boot_arg
& DB_NMI
) panicDebugging
=TRUE
;
165 if (boot_arg
& DB_LOG_PI_SCRN
) logPanicDataToScreen
=TRUE
;
169 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
171 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
177 #if DB_MACHINE_COMMANDS
178 db_machine_commands_install(ppc_db_commands
);
179 #endif /* DB_MACHINE_COMMANDS */
182 if (boot_arg
& DB_KDB
)
183 current_debugger
= KDB_CUR_DB
;
186 * Cause a breakpoint trap to the debugger before proceeding
187 * any further if the proper option bit was specified in
190 if (halt_in_debugger
&& (current_debugger
== KDB_CUR_DB
)) {
191 Debugger("inline call to debugger(machine_startup)");
192 halt_in_debugger
= 0;
195 #endif /* MACH_KDB */
197 if (PE_parse_boot_arg("preempt", &boot_arg
)) {
198 default_preemption_rate
= boot_arg
;
200 if (PE_parse_boot_arg("unsafe", &boot_arg
)) {
201 max_unsafe_quanta
= boot_arg
;
203 if (PE_parse_boot_arg("poll", &boot_arg
)) {
204 max_poll_quanta
= boot_arg
;
206 if (PE_parse_boot_arg("yield", &boot_arg
)) {
207 sched_poll_yield_shift
= boot_arg
;
209 if (PE_parse_boot_arg("idlehalt", &boot_arg
)) {
212 /* The I/O port to issue a read from, in the event of a panic. Useful for
213 * triggering logic analyzers.
215 if (PE_parse_boot_arg("panic_io_port", &boot_arg
)) {
216 /*I/O ports range from 0 through 0xFFFF */
217 panic_io_port
= boot_arg
& 0xffff;
221 * fn is used to force napping.
222 * fn=0 means no napping allowed
223 * fn=1 means forces napping on, normal C2 and C4 transitions
224 * fn=2 means forces napping on, but C4 is disabled
225 * fn=3 means forces napping on, but use halt
226 * fn=4 means forces napping on and will always use C4
228 * Note that this will take effect only when the system normally starts napping.
232 if (!PE_parse_boot_arg("fn", &forcenap
)) forcenap
= 0; /* If force nap not set, make 0 */
234 if(forcenap
< 5) forcenap
= forcenap
+ 1; /* See comments above for decode, this is set to fn + 1 */
235 else forcenap
= 0; /* Clear for error case */
237 machine_nap_policy(); /* Make sure the nap policy reflects the user's choice */
242 ml_thrm_init(); /* Start thermal monitoring on this processor */
256 machine_info
.memory_size
= mem_size
;
260 extern void *gPEEFIRuntimeServices
;
261 extern void *gPEEFISystemTable
;
264 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
265 * code or tables extracted from it, as desired without restriction.
267 * First, the polynomial itself and its table of feedback terms. The
269 * 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
271 * Note that we take it "backwards" and put the highest-order term in
272 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
273 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
276 * Note that the usual hardware shift register implementation, which
277 * is what we're using (we're merely optimizing it by doing eight-bit
278 * chunks at a time) shifts bits into the lowest-order term. In our
279 * implementation, that means shifting towards the right. Why do we
280 * do it this way? Because the calculated CRC must be transmitted in
281 * order from highest-order term to lowest-order term. UARTs transmit
282 * characters in order from LSB to MSB. By storing the CRC this way
283 * we hand it to the UART in the order low-byte to high-byte; the UART
284 * sends each low-bit to hight-bit; and the result is transmission bit
285 * by bit from highest- to lowest-order term without requiring any bit
286 * shuffling on our part. Reception works similarly
288 * The feedback terms table consists of 256, 32-bit entries. Notes
290 * The table can be generated at runtime if desired; code to do so
291 * is shown later. It might not be obvious, but the feedback
292 * terms simply represent the results of eight shift/xor opera
293 * tions for all combinations of data and CRC register values
295 * The values must be right-shifted by eight bits by the "updcrc
296 * logic; the shift must be unsigned (bring in zeroes). On some
297 * hardware you could probably optimize the shift in assembler by
298 * using byte-swap instructions
299 * polynomial $edb88320
302 * CRC32 code derived from work by Gary S. Brown.
305 static uint32_t crc32_tab
[] = {
306 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
307 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
308 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
309 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
310 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
311 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
312 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
313 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
314 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
315 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
316 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
317 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
318 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
319 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
320 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
321 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
322 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
323 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
324 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
325 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
326 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
327 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
328 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
329 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
330 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
331 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
332 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
333 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
334 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
335 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
336 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
337 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
338 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
339 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
340 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
341 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
342 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
343 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
344 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
345 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
346 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
347 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
348 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
352 crc32(uint32_t crc
, const void *buf
, size_t size
)
360 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
366 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
368 EFI_RUNTIME_SERVICES_64
*runtime
;
372 kprintf("Processing 64-bit EFI tables at 0x%x\n", (unsigned int)system_table
);
374 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
375 kprintf("Bad EFI system table signature\n");
378 // Verify signature of the system table
379 hdr_cksum
= system_table
->Hdr
.CRC32
;
380 system_table
->Hdr
.CRC32
= 0;
381 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
383 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
384 system_table
->Hdr
.CRC32
= hdr_cksum
;
385 if (cksum
!= hdr_cksum
) {
386 kprintf("Bad EFI system table checksum\n");
390 gPEEFISystemTable
= system_table
;
392 kprintf("RuntimeServices table at 0x%qx\n", system_table
->RuntimeServices
);
393 runtime
= (EFI_RUNTIME_SERVICES_64
*) (uint32_t)system_table
->RuntimeServices
; // XXX
394 kprintf("Checking runtime services table 0x%x\n", runtime
);
395 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
396 kprintf("Bad EFI runtime table signature\n");
400 // Verify signature of runtime services table
401 hdr_cksum
= runtime
->Hdr
.CRC32
;
402 runtime
->Hdr
.CRC32
= 0;
403 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
405 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
406 runtime
->Hdr
.CRC32
= hdr_cksum
;
407 if (cksum
!= hdr_cksum
) {
408 kprintf("Bad EFI runtime table checksum\n");
412 gPEEFIRuntimeServices
= runtime
;
418 efi_set_tables_32(EFI_SYSTEM_TABLE
* system_table
)
420 EFI_RUNTIME_SERVICES
*runtime
;
424 kprintf("Processing 32-bit EFI tables at 0x%x\n", (unsigned int)system_table
);
426 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
427 kprintf("Bad EFI system table signature\n");
430 // Verify signature of the system table
431 hdr_cksum
= system_table
->Hdr
.CRC32
;
432 system_table
->Hdr
.CRC32
= 0;
433 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
435 //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
436 system_table
->Hdr
.CRC32
= hdr_cksum
;
437 if (cksum
!= hdr_cksum
) {
438 kprintf("Bad EFI system table checksum\n");
442 gPEEFISystemTable
= system_table
;
444 runtime
= (EFI_RUNTIME_SERVICES
*) system_table
->RuntimeServices
;
445 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
446 kprintf("Bad EFI runtime table signature\n");
450 // Verify signature of runtime services table
451 hdr_cksum
= runtime
->Hdr
.CRC32
;
452 runtime
->Hdr
.CRC32
= 0;
453 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
455 //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
456 runtime
->Hdr
.CRC32
= hdr_cksum
;
457 if (cksum
!= hdr_cksum
) {
458 kprintf("Bad EFI runtime table checksum\n");
462 gPEEFIRuntimeServices
= runtime
;
468 /* Map in EFI runtime areas. */
472 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
474 kprintf("Initializing EFI runtime services\n");
478 vm_offset_t vm_size
, vm_addr
;
479 vm_map_offset_t phys_addr
;
480 EfiMemoryRange
*mptr
;
481 unsigned int msize
, mcount
;
484 msize
= args
->MemoryMapDescriptorSize
;
485 mcount
= args
->MemoryMapSize
/ msize
;
487 mptr
= (EfiMemoryRange
*)args
->MemoryMap
;
488 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
489 if (((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) ) {
490 vm_size
= i386_ptob((uint32_t)mptr
->NumberOfPages
);
491 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
492 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
493 pmap_map(vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
494 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
495 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
499 if (args
->Version
> 1)
500 panic("Incompatible boot args version %d\n", args
->Version
);
502 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
503 if (args
->Revision
>= 4 && args
->efiMode
== kBootArgsEfiMode64
) {
504 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) args
->efiSystemTable
);
506 efi_set_tables_32((EFI_SYSTEM_TABLE
*) args
->efiSystemTable
);
514 /* Remap EFI runtime areas. */
516 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
518 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
520 kprintf("Reinitializing EFI runtime services\n");
522 if (args
->Revision
< 3)
526 vm_offset_t vm_size
, vm_addr
;
527 vm_map_offset_t phys_addr
;
528 EfiMemoryRange
*mptr
;
529 unsigned int msize
, mcount
;
532 gPEEFISystemTable
= 0;
533 gPEEFIRuntimeServices
= 0;
535 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
537 kprintf("Old system table %p, new %p\n",
538 args
->efiSystemTable
, (void *) system_table_offset
);
540 args
->efiSystemTable
= (uint32_t) system_table_offset
;
542 kprintf("Old map:\n");
543 msize
= args
->MemoryMapDescriptorSize
;
544 mcount
= args
->MemoryMapSize
/ msize
;
545 mptr
= (EfiMemoryRange
*)args
->MemoryMap
;
546 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
547 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
549 vm_size
= i386_ptob((uint32_t)mptr
->NumberOfPages
);
550 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
551 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
553 kprintf("mapping[%d] %qx @ %x, %x\n", mptr
->Type
, phys_addr
, vm_addr
, mptr
->NumberOfPages
);
557 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
558 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
560 kprintf("New map:\n");
561 msize
= args
->MemoryMapDescriptorSize
;
562 mcount
= map_size
/ msize
;
564 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
565 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
567 vm_size
= i386_ptob((uint32_t)mptr
->NumberOfPages
);
568 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
569 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
571 kprintf("mapping[%d] %qx @ %x, %x\n", mptr
->Type
, phys_addr
, vm_addr
, mptr
->NumberOfPages
);
573 pmap_map(vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
574 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
575 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
579 if (args
->Version
> 1)
580 panic("Incompatible boot args version %d\n", args
->Version
);
582 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
583 if (args
->Revision
>= 4 && args
->efiMode
== kBootArgsEfiMode64
) {
584 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) args
->efiSystemTable
);
586 efi_set_tables_32((EFI_SYSTEM_TABLE
*) args
->efiSystemTable
);
591 kprintf("Done reinitializing EFI runtime services\n");
597 * Find devices. The system is alive.
602 /* Ensure panic buffer is initialized. */
606 * Display CPU identification
608 cpuid_cpu_display("CPU identification");
609 cpuid_feature_display("CPU features");
610 cpuid_extfeature_display("CPU extended features");
613 * Initialize EFI runtime services.
620 * Set up to use floating point.
625 * Configure clock devices.
630 * Initialize MTRR from boot processor.
635 * Set up PAT for boot processor.
651 halt_all_cpus(FALSE
);
654 int reset_mem_on_reboot
= 1;
657 * Halt the system or reboot.
660 halt_all_cpus(boolean_t reboot
)
663 printf("MACH Reboot\n");
664 PEHaltRestart( kPERestartCPU
);
666 printf("CPU halted\n");
667 PEHaltRestart( kPEHaltCPU
);
672 /* Issue an I/O port read if one has been requested - this is an event logic
673 * analyzers can use as a trigger point.
677 panic_io_port_read(void) {
679 (void)inb(panic_io_port
);
682 /* For use with the MP rendezvous mechanism
686 machine_halt_cpu(__unused
void *arg
) {
687 panic_io_port_read();
688 __asm__
volatile("hlt");
695 unsigned long pi_size
= 0;
698 hw_atomic_add(&debug_mode
, 1);
699 if (!panic_is_inited
) {
705 printf("Debugger called: <%s>\n", message
);
706 kprintf("Debugger called: <%s>\n", message
);
709 * Skip the graphical panic box if no panic string.
710 * This is the case if we're being called from
711 * host_reboot(,HOST_REBOOT_DEBUGGER)
712 * as a quiet way into the debugger.
716 disable_preemption();
718 /* Issue an I/O port read if one has been requested - this is an event logic
719 * analyzers can use as a trigger point.
721 panic_io_port_read();
723 /* Obtain current frame pointer */
724 __asm__
volatile("movl %%ebp, %0" : "=m" (stackptr
));
726 /* Print backtrace - callee is internally synchronized */
727 panic_i386_backtrace(stackptr
, 16);
729 /* everything should be printed now so copy to NVRAM
732 if( debug_buf_size
> 0) {
733 /* Do not compress the panic log
734 * or save to NVRAM unless kernel debugging
735 * is disabled. The NVRAM shim doesn't
736 * sync to the store until haltRestart is called.
738 if (!panicDebugging
) {
743 /* Now call the compressor */
744 /* XXX Consider using the WKdm compressor in the
745 * future, rather than just packing - would need to
746 * be co-ordinated with crashreporter, which decodes
749 bufpos
= packAsc ((uint8_t *)debug_buf
,
750 (unsigned int) (debug_buf_ptr
- debug_buf
) );
751 /* If compression was successful,
752 * use the compressed length
755 debug_buf_ptr
= debug_buf
+ bufpos
;
757 /* Save panic log to non-volatile store
758 * Panic info handler must truncate data that is
759 * too long for this platform.
760 * This call must save data synchronously,
761 * since we can subsequently halt the system.
763 pi_size
= debug_buf_ptr
- debug_buf
;
764 pi_size
= PESavePanicInfo((unsigned char *)debug_buf
,
770 if (!panicDebugging
) {
771 /* Clear the MP rendezvous function lock, in the event
772 * that a panic occurred while in that codepath.
774 mp_rendezvous_break_lock();
775 /* Force all CPUs to disable interrupts and HLT.
776 * We've panicked, and shouldn't depend on the
777 * PEHaltRestart() mechanism, which relies on several
778 * bits of infrastructure.
780 mp_rendezvous_no_intrs(machine_halt_cpu
, NULL
);
786 hw_atomic_sub(&debug_mode
, 1);
795 disable_bluebox(void)
800 machine_boot_info(char *buf
, __unused vm_size_t size
)
816 } __attribute__((packed
));
818 typedef struct pasc pasc_t
;
820 static int packAsc (unsigned char *inbuf
, unsigned int length
)
822 unsigned int i
, j
= 0;
826 for (i
= 0; i
< length
; i
+=8)
836 bcopy ((char *) &pack
, inbuf
+ j
, 7);
839 extra
= (i
- length
);
841 inbuf
[j
- extra
] &= (0xFF << (8-extra
));
843 return j
-((extra
== 7) ? 6 : extra
);
846 /* Routines for address - symbol translation. Not called unless the "keepsyms"
847 * boot-arg is supplied.
851 panic_print_macho_symbol_name(struct mach_header
*mh
, vm_address_t search
)
853 struct nlist
*sym
= NULL
;
854 struct load_command
*cmd
;
855 struct segment_command
*orig_ts
= NULL
, *orig_le
= NULL
;
856 struct symtab_command
*orig_st
= NULL
;
858 char *strings
, *bestsym
= NULL
;
859 vm_address_t bestaddr
= 0, diff
, curdiff
;
861 if (mh
->magic
!= MH_MAGIC
) {
862 /* bad magic number */
866 cmd
= (struct load_command
*) &mh
[1];
867 for (i
= 0; i
< mh
->ncmds
; i
++) {
868 if (cmd
->cmd
== LC_SEGMENT
) {
869 struct segment_command
*orig_sg
= (struct segment_command
*) cmd
;
871 if (strcmp(SEG_TEXT
, orig_sg
->segname
) == 0)
873 else if (strcmp(SEG_LINKEDIT
, orig_sg
->segname
) == 0)
875 else if (strcmp("", orig_sg
->segname
) == 0)
876 orig_ts
= orig_sg
; /* kexts have a single unnamed segment */
878 else if (cmd
->cmd
== LC_SYMTAB
)
879 orig_st
= (struct symtab_command
*) cmd
;
881 cmd
= (struct load_command
*) ((caddr_t
) cmd
+ cmd
->cmdsize
);
884 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
887 /* kexts don't have a LINKEDIT segment for now, so we'll never get this far for kexts */
889 vm_address_t slide
= ((vm_address_t
)mh
) - orig_ts
->vmaddr
;
891 search
-= slide
; /* adjusting search since the binary has slid */
893 if ((search
< orig_ts
->vmaddr
) ||
894 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
895 /* search out of range for this mach header */
899 sym
= (struct nlist
*)orig_le
->vmaddr
;
900 strings
= ((char *)sym
) + orig_st
->nsyms
* sizeof(struct nlist
);
903 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
904 if (sym
[i
].n_value
<= search
) {
905 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
906 if (curdiff
< diff
) {
908 bestaddr
= sym
[i
].n_value
;
909 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
914 if (bestsym
!= NULL
) {
916 kdb_printf("%s + 0x%08x ", bestsym
, diff
);
918 kdb_printf("%s ", bestsym
);
925 extern kmod_info_t
* kmod
; /* the list of modules */
928 panic_print_kmod_symbol_name(vm_address_t search
)
930 kmod_info_t
* current_kmod
= kmod
;
932 while (current_kmod
!= NULL
) {
933 if ((current_kmod
->address
<= search
) &&
934 (current_kmod
->address
+ current_kmod
->size
> search
))
936 current_kmod
= current_kmod
->next
;
938 if (current_kmod
!= NULL
) {
939 /* if kexts had symbol table loaded, we'd call search_symbol_name again; alas, they don't */
940 kdb_printf("%s + %d ", current_kmod
->name
, search
- current_kmod
->address
);
944 extern struct mach_header _mh_execute_header
; /* the kernel's mach header */
947 panic_print_symbol_name(vm_address_t search
)
949 /* try searching in the kernel */
950 if (panic_print_macho_symbol_name(&_mh_execute_header
, search
) == 0) {
951 /* that failed, now try to search for the right kext */
952 panic_print_kmod_symbol_name(search
);
956 /* Generate a backtrace, given a frame pointer - this routine
957 * should walk the stack safely. The trace is appended to the panic log
958 * and conditionally, to the console. If the trace contains kernel module
959 * addresses, display the module name, load address and dependencies.
962 #define DUMPFRAMES 32
963 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
965 panic_i386_backtrace(void *_frame
, int nframes
)
967 cframe_t
*frame
= (cframe_t
*)_frame
;
968 vm_offset_t raddrs
[DUMPFRAMES
];
970 volatile uint32_t *ppbtcnt
= &pbtcnt
;
971 uint64_t bt_tsc_timeout
;
972 boolean_t keepsyms
= FALSE
;
974 if(pbtcpu
!= cpu_number()) {
975 hw_atomic_add(&pbtcnt
, 1);
976 /* Spin on print backtrace lock, which serializes output
977 * Continue anyway if a timeout occurs.
979 hw_lock_to(&pbtlock
, LockTimeOut
*100);
980 pbtcpu
= cpu_number();
983 PE_parse_boot_arg("keepsyms", &keepsyms
);
985 kdb_printf("Backtrace, "
986 "Format - Frame : Return Address (4 potential args on stack) ");
988 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
989 vm_offset_t curframep
= (vm_offset_t
) frame
;
994 if (curframep
& 0x3) {
995 kdb_printf("Unaligned frame\n");
999 if (!kvtophys(curframep
) ||
1000 !kvtophys(curframep
+ sizeof(cframe_t
))) {
1001 kdb_printf("No mapping exists for frame pointer\n");
1005 kdb_printf("\n0x%x : 0x%x ",
1006 frame
, frame
->caller
);
1007 if (frame_index
< DUMPFRAMES
)
1008 raddrs
[frame_index
] = frame
->caller
;
1010 if (kvtophys((vm_offset_t
)&(frame
->args
[3])))
1011 kdb_printf("(0x%x 0x%x 0x%x 0x%x) ",
1012 frame
->args
[0], frame
->args
[1],
1013 frame
->args
[2], frame
->args
[3]);
1015 /* Display address-symbol translation only if the "keepsyms"
1016 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1017 * This routine is potentially unsafe; also, function
1018 * boundary identification is unreliable after a strip -x.
1021 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1023 /* Stack grows downward */
1024 if (frame
->prev
< frame
) {
1025 frame
= frame
->prev
;
1028 frame
= frame
->prev
;
1031 if (frame_index
>= nframes
)
1032 kdb_printf("\tBacktrace continues...\n");
1037 kdb_printf("Backtrace terminated-invalid frame pointer 0x%x\n",frame
);
1040 /* Identify kernel modules in the backtrace and display their
1041 * load addresses and dependencies. This routine should walk
1042 * the kmod list safely.
1045 kmod_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1047 kdb_printf("\nKernel version:\n%s\n\n",version
);
1049 /* Release print backtrace lock, to permit other callers in the
1050 * event of panics on multiple processors.
1052 hw_lock_unlock(&pbtlock
);
1053 hw_atomic_sub(&pbtcnt
, 1);
1054 /* Wait for other processors to complete output
1055 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1057 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1058 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));