]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/AT386/model_dep.c
xnu-792.18.15.tar.gz
[apple/xnu.git] / osfmk / i386 / AT386 / model_dep.c
1 /*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * @OSF_COPYRIGHT@
30 */
31 /*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
34 * All Rights Reserved.
35 *
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.
41 *
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.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56
57 /*
58 */
59
60 /*
61 * File: model_dep.c
62 * Author: Avadis Tevanian, Jr., Michael Wayne Young
63 *
64 * Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
65 *
66 * Basic initialization for I386 - ISA bus machines.
67 */
68
69 #include <platforms.h>
70 #include <mach_kdb.h>
71
72 #include <mach/i386/vm_param.h>
73
74 #include <string.h>
75 #include <mach/vm_param.h>
76 #include <mach/vm_prot.h>
77 #include <mach/machine.h>
78 #include <mach/time_value.h>
79 #include <kern/spl.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/fpu.h>
88 #include <i386/ipl.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>
96 #if MACH_KDB
97 #include <ddb/db_aout.h>
98 #endif /* MACH_KDB */
99
100 #include <vm/pmap.h>
101 #include <vm/vm_map.h>
102 #include <vm/vm_kern.h>
103
104 #include <i386/mp_desc.h>
105 #include <i386/mp.h>
106 #include <i386/cpuid.h>
107
108 #include <IOKit/IOPlatformExpert.h>
109 #include <IOKit/IOHibernatePrivate.h>
110
111 #include <pexpert/i386/efi.h>
112
113 #include <kern/thread.h>
114 #include <i386/thread.h>
115 #include <mach-o/loader.h>
116 #include <mach-o/nlist.h>
117
118 void enable_bluebox(void);
119 void disable_bluebox(void);
120
121 static void machine_conf(void);
122
123 extern int default_preemption_rate;
124 extern int max_unsafe_quanta;
125 extern int max_poll_quanta;
126 extern int idlehalt;
127 extern unsigned int panic_is_inited;
128
129 int db_run_mode;
130
131 static int packAsc (uint8_t *inbuf, unsigned int length);
132 extern int kdb_printf(const char *fmt, ...);
133
134 volatile int pbtcpu = -1;
135 hw_lock_data_t pbtlock; /* backtrace print lock */
136 uint32_t pbtcnt = 0;
137
138 extern const char version[];
139
140 typedef struct _cframe_t {
141 struct _cframe_t *prev;
142 unsigned caller;
143 unsigned args[0];
144 } cframe_t;
145
146 void panic_i386_backtrace(void *_frame, int nframes);
147
148 static unsigned panic_io_port = 0;
149
150 void
151 machine_startup()
152 {
153 int boot_arg;
154
155 #if 0
156 if( PE_get_hotkey( kPEControlKey ))
157 halt_in_debugger = halt_in_debugger ? 0 : 1;
158 #endif
159
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;
166 }
167
168 #if NOTYET
169 hw_lock_init(&debugger_lock); /* initialize debugger lock */
170 #endif
171 hw_lock_init(&pbtlock); /* initialize print backtrace lock */
172
173 #if MACH_KDB
174 /*
175 * Initialize KDB
176 */
177 #if DB_MACHINE_COMMANDS
178 db_machine_commands_install(ppc_db_commands);
179 #endif /* DB_MACHINE_COMMANDS */
180 ddb_init();
181
182 if (boot_arg & DB_KDB)
183 current_debugger = KDB_CUR_DB;
184
185 /*
186 * Cause a breakpoint trap to the debugger before proceeding
187 * any further if the proper option bit was specified in
188 * the boot flags.
189 */
190 if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
191 Debugger("inline call to debugger(machine_startup)");
192 halt_in_debugger = 0;
193 active_debugger =1;
194 }
195 #endif /* MACH_KDB */
196
197 if (PE_parse_boot_arg("preempt", &boot_arg)) {
198 default_preemption_rate = boot_arg;
199 }
200 if (PE_parse_boot_arg("unsafe", &boot_arg)) {
201 max_unsafe_quanta = boot_arg;
202 }
203 if (PE_parse_boot_arg("poll", &boot_arg)) {
204 max_poll_quanta = boot_arg;
205 }
206 if (PE_parse_boot_arg("yield", &boot_arg)) {
207 sched_poll_yield_shift = boot_arg;
208 }
209 if (PE_parse_boot_arg("idlehalt", &boot_arg)) {
210 idlehalt = boot_arg;
211 }
212 /* The I/O port to issue a read from, in the event of a panic. Useful for
213 * triggering logic analyzers.
214 */
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;
218 }
219
220 /*
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
227 *
228 * Note that this will take effect only when the system normally starts napping.
229 *
230 */
231
232 if (!PE_parse_boot_arg("fn", &forcenap)) forcenap = 0; /* If force nap not set, make 0 */
233 else {
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 */
236 }
237 machine_nap_policy(); /* Make sure the nap policy reflects the user's choice */
238
239 machine_conf();
240
241 #if NOTYET
242 ml_thrm_init(); /* Start thermal monitoring on this processor */
243 #endif
244
245 /*
246 * Start the system.
247 */
248 kernel_bootstrap();
249 /*NOTREACHED*/
250 }
251
252
253 static void
254 machine_conf(void)
255 {
256 machine_info.memory_size = mem_size;
257 }
258
259
260 extern void *gPEEFIRuntimeServices;
261 extern void *gPEEFISystemTable;
262
263 /*-
264 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
265 * code or tables extracted from it, as desired without restriction.
266 *
267 * First, the polynomial itself and its table of feedback terms. The
268 * polynomial is
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
270 *
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
274 * the MSB being 1
275 *
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
287 *
288 * The feedback terms table consists of 256, 32-bit entries. Notes
289 *
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
294 *
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
300 *
301 *
302 * CRC32 code derived from work by Gary S. Brown.
303 */
304
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
349 };
350
351 static uint32_t
352 crc32(uint32_t crc, const void *buf, size_t size)
353 {
354 const uint8_t *p;
355
356 p = buf;
357 crc = crc ^ ~0U;
358
359 while (size--)
360 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
361
362 return crc ^ ~0U;
363 }
364
365 static void
366 efi_set_tables_64(EFI_SYSTEM_TABLE_64 * system_table)
367 {
368 EFI_RUNTIME_SERVICES_64 *runtime;
369 uint32_t hdr_cksum;
370 uint32_t cksum;
371
372 kprintf("Processing 64-bit EFI tables at 0x%x\n", (unsigned int)system_table);
373 do {
374 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
375 kprintf("Bad EFI system table signature\n");
376 break;
377 }
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);
382
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");
387 break;
388 }
389
390 gPEEFISystemTable = system_table;
391
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");
397 break;
398 }
399
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);
404
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");
409 break;
410 }
411
412 gPEEFIRuntimeServices = runtime;
413 }
414 while (FALSE);
415 }
416
417 static void
418 efi_set_tables_32(EFI_SYSTEM_TABLE * system_table)
419 {
420 EFI_RUNTIME_SERVICES *runtime;
421 uint32_t hdr_cksum;
422 uint32_t cksum;
423
424 kprintf("Processing 32-bit EFI tables at 0x%x\n", (unsigned int)system_table);
425 do {
426 if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
427 kprintf("Bad EFI system table signature\n");
428 break;
429 }
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);
434
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");
439 break;
440 }
441
442 gPEEFISystemTable = system_table;
443
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");
447 break;
448 }
449
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);
454
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");
459 break;
460 }
461
462 gPEEFIRuntimeServices = runtime;
463 }
464 while (FALSE);
465 }
466
467
468 /* Map in EFI runtime areas. */
469 static void
470 efi_init(void)
471 {
472 boot_args *args = (boot_args *)PE_state.bootArgs;
473
474 kprintf("Initializing EFI runtime services\n");
475
476 do
477 {
478 vm_offset_t vm_size, vm_addr;
479 vm_map_offset_t phys_addr;
480 EfiMemoryRange *mptr;
481 unsigned int msize, mcount;
482 unsigned int i;
483
484 msize = args->MemoryMapDescriptorSize;
485 mcount = args->MemoryMapSize / msize;
486
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);
496 }
497 }
498
499 if (args->Version > 1)
500 panic("Incompatible boot args version %d\n", args->Version);
501
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);
505 } else {
506 efi_set_tables_32((EFI_SYSTEM_TABLE *) args->efiSystemTable);
507 }
508 }
509 while (FALSE);
510
511 return;
512 }
513
514 /* Remap EFI runtime areas. */
515 void
516 hibernate_newruntime_map(void * map, vm_size_t map_size, uint32_t system_table_offset)
517 {
518 boot_args *args = (boot_args *)PE_state.bootArgs;
519
520 kprintf("Reinitializing EFI runtime services\n");
521
522 if (args->Revision < 3)
523 return;
524 do
525 {
526 vm_offset_t vm_size, vm_addr;
527 vm_map_offset_t phys_addr;
528 EfiMemoryRange *mptr;
529 unsigned int msize, mcount;
530 unsigned int i;
531
532 gPEEFISystemTable = 0;
533 gPEEFIRuntimeServices = 0;
534
535 system_table_offset += ptoa_32(args->efiRuntimeServicesPageStart);
536
537 kprintf("Old system table %p, new %p\n",
538 args->efiSystemTable, (void *) system_table_offset);
539
540 args->efiSystemTable = (uint32_t) system_table_offset;
541
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) {
548
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;
552
553 kprintf("mapping[%d] %qx @ %x, %x\n", mptr->Type, phys_addr, vm_addr, mptr->NumberOfPages);
554 }
555 }
556
557 pmap_remove(kernel_pmap, i386_ptob(args->efiRuntimeServicesPageStart),
558 i386_ptob(args->efiRuntimeServicesPageStart + args->efiRuntimeServicesPageCount));
559
560 kprintf("New map:\n");
561 msize = args->MemoryMapDescriptorSize;
562 mcount = map_size / msize;
563 mptr = map;
564 for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
565 if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
566
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;
570
571 kprintf("mapping[%d] %qx @ %x, %x\n", mptr->Type, phys_addr, vm_addr, mptr->NumberOfPages);
572
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);
576 }
577 }
578
579 if (args->Version > 1)
580 panic("Incompatible boot args version %d\n", args->Version);
581
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);
585 } else {
586 efi_set_tables_32((EFI_SYSTEM_TABLE *) args->efiSystemTable);
587 }
588 }
589 while (FALSE);
590
591 kprintf("Done reinitializing EFI runtime services\n");
592
593 return;
594 }
595
596 /*
597 * Find devices. The system is alive.
598 */
599 void
600 machine_init(void)
601 {
602 /* Ensure panic buffer is initialized. */
603 debug_log_init();
604
605 /*
606 * Display CPU identification
607 */
608 cpuid_cpu_display("CPU identification");
609 cpuid_feature_display("CPU features");
610 cpuid_extfeature_display("CPU extended features");
611
612 /*
613 * Initialize EFI runtime services.
614 */
615 efi_init();
616
617 smp_init();
618
619 /*
620 * Set up to use floating point.
621 */
622 init_fpu();
623
624 /*
625 * Configure clock devices.
626 */
627 clock_config();
628
629 /*
630 * Initialize MTRR from boot processor.
631 */
632 mtrr_init();
633
634 /*
635 * Set up PAT for boot processor.
636 */
637 pat_init();
638
639 /*
640 * Free lowmem pages
641 */
642 x86_lowmem_free();
643 }
644
645 /*
646 * Halt a cpu.
647 */
648 void
649 halt_cpu(void)
650 {
651 halt_all_cpus(FALSE);
652 }
653
654 int reset_mem_on_reboot = 1;
655
656 /*
657 * Halt the system or reboot.
658 */
659 void
660 halt_all_cpus(boolean_t reboot)
661 {
662 if (reboot) {
663 printf("MACH Reboot\n");
664 PEHaltRestart( kPERestartCPU );
665 } else {
666 printf("CPU halted\n");
667 PEHaltRestart( kPEHaltCPU );
668 }
669 while(1);
670 }
671
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.
674 */
675
676 void
677 panic_io_port_read(void) {
678 if (panic_io_port)
679 (void)inb(panic_io_port);
680 }
681
682 /* For use with the MP rendezvous mechanism
683 */
684
685 static void
686 machine_halt_cpu(__unused void *arg) {
687 panic_io_port_read();
688 __asm__ volatile("hlt");
689 }
690
691 void
692 Debugger(
693 const char *message)
694 {
695 unsigned long pi_size = 0;
696 void *stackptr;
697
698 hw_atomic_add(&debug_mode, 1);
699 if (!panic_is_inited) {
700 postcode(PANIC_HLT);
701 asm("hlt");
702 }
703
704
705 printf("Debugger called: <%s>\n", message);
706 kprintf("Debugger called: <%s>\n", message);
707
708 /*
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.
713 */
714
715 if (panicstr) {
716 disable_preemption();
717
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.
720 */
721 panic_io_port_read();
722
723 /* Obtain current frame pointer */
724 __asm__ volatile("movl %%ebp, %0" : "=m" (stackptr));
725
726 /* Print backtrace - callee is internally synchronized */
727 panic_i386_backtrace(stackptr, 16);
728
729 /* everything should be printed now so copy to NVRAM
730 */
731
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.
737 */
738 if (!panicDebugging) {
739 unsigned int bufpos;
740
741 debug_putc(0);
742
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
747 * this post-restart.
748 */
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
753 */
754 if (bufpos) {
755 debug_buf_ptr = debug_buf + bufpos;
756 }
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.
762 */
763 pi_size = debug_buf_ptr - debug_buf;
764 pi_size = PESavePanicInfo((unsigned char *)debug_buf,
765 pi_size );
766 }
767 }
768 draw_panic_dialog();
769
770 if (!panicDebugging) {
771 /* Clear the MP rendezvous function lock, in the event
772 * that a panic occurred while in that codepath.
773 */
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.
779 */
780 mp_rendezvous_no_intrs(machine_halt_cpu, NULL);
781 /* NOT REACHED */
782 }
783 }
784
785 __asm__("int3");
786 hw_atomic_sub(&debug_mode, 1);
787 }
788
789 void
790 enable_bluebox(void)
791 {
792 }
793
794 void
795 disable_bluebox(void)
796 {
797 }
798
799 char *
800 machine_boot_info(char *buf, __unused vm_size_t size)
801 {
802 *buf ='\0';
803 return buf;
804 }
805
806
807 struct pasc {
808 unsigned a: 7;
809 unsigned b: 7;
810 unsigned c: 7;
811 unsigned d: 7;
812 unsigned e: 7;
813 unsigned f: 7;
814 unsigned g: 7;
815 unsigned h: 7;
816 } __attribute__((packed));
817
818 typedef struct pasc pasc_t;
819
820 static int packAsc (unsigned char *inbuf, unsigned int length)
821 {
822 unsigned int i, j = 0;
823 unsigned int extra;
824 pasc_t pack;
825
826 for (i = 0; i < length; i+=8)
827 {
828 pack.a = inbuf[i];
829 pack.b = inbuf[i+1];
830 pack.c = inbuf[i+2];
831 pack.d = inbuf[i+3];
832 pack.e = inbuf[i+4];
833 pack.f = inbuf[i+5];
834 pack.g = inbuf[i+6];
835 pack.h = inbuf[i+7];
836 bcopy ((char *) &pack, inbuf + j, 7);
837 j += 7;
838 }
839 extra = (i - length);
840 if (extra > 0) {
841 inbuf[j - extra] &= (0xFF << (8-extra));
842 }
843 return j-((extra == 7) ? 6 : extra);
844 }
845
846 /* Routines for address - symbol translation. Not called unless the "keepsyms"
847 * boot-arg is supplied.
848 */
849
850 static int
851 panic_print_macho_symbol_name(struct mach_header *mh, vm_address_t search)
852 {
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;
857 unsigned int i;
858 char *strings, *bestsym = NULL;
859 vm_address_t bestaddr = 0, diff, curdiff;
860
861 if (mh->magic != MH_MAGIC) {
862 /* bad magic number */
863 return 0;
864 }
865
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;
870
871 if (strcmp(SEG_TEXT, orig_sg->segname) == 0)
872 orig_ts = orig_sg;
873 else if (strcmp(SEG_LINKEDIT, orig_sg->segname) == 0)
874 orig_le = orig_sg;
875 else if (strcmp("", orig_sg->segname) == 0)
876 orig_ts = orig_sg; /* kexts have a single unnamed segment */
877 }
878 else if (cmd->cmd == LC_SYMTAB)
879 orig_st = (struct symtab_command *) cmd;
880
881 cmd = (struct load_command *) ((caddr_t) cmd + cmd->cmdsize);
882 }
883
884 if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL))
885 return 0;
886
887 /* kexts don't have a LINKEDIT segment for now, so we'll never get this far for kexts */
888
889 vm_address_t slide = ((vm_address_t)mh) - orig_ts->vmaddr;
890 if (slide != 0)
891 search -= slide; /* adjusting search since the binary has slid */
892
893 if ((search < orig_ts->vmaddr) ||
894 (search >= orig_ts->vmaddr + orig_ts->vmsize)) {
895 /* search out of range for this mach header */
896 return 0;
897 }
898
899 sym = (struct nlist *)orig_le->vmaddr;
900 strings = ((char *)sym) + orig_st->nsyms * sizeof(struct nlist);
901 diff = search;
902
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) {
907 diff = curdiff;
908 bestaddr = sym[i].n_value;
909 bestsym = strings + sym[i].n_un.n_strx;
910 }
911 }
912 }
913
914 if (bestsym != NULL) {
915 if (diff != 0) {
916 kdb_printf("%s + 0x%08x ", bestsym, diff);
917 } else {
918 kdb_printf("%s ", bestsym);
919 }
920 return 1;
921 }
922 return 0;
923 }
924
925 extern kmod_info_t * kmod; /* the list of modules */
926
927 static void
928 panic_print_kmod_symbol_name(vm_address_t search)
929 {
930 kmod_info_t * current_kmod = kmod;
931
932 while (current_kmod != NULL) {
933 if ((current_kmod->address <= search) &&
934 (current_kmod->address + current_kmod->size > search))
935 break;
936 current_kmod = current_kmod->next;
937 }
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);
941 }
942 }
943
944 extern struct mach_header _mh_execute_header; /* the kernel's mach header */
945
946 static void
947 panic_print_symbol_name(vm_address_t search)
948 {
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);
953 }
954 }
955
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.
960 */
961
962 #define DUMPFRAMES 32
963 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
964 void
965 panic_i386_backtrace(void *_frame, int nframes)
966 {
967 cframe_t *frame = (cframe_t *)_frame;
968 vm_offset_t raddrs[DUMPFRAMES];
969 int frame_index;
970 volatile uint32_t *ppbtcnt = &pbtcnt;
971 uint64_t bt_tsc_timeout;
972 boolean_t keepsyms = FALSE;
973
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.
978 */
979 hw_lock_to(&pbtlock, LockTimeOut*100);
980 pbtcpu = cpu_number();
981 }
982
983 PE_parse_boot_arg("keepsyms", &keepsyms);
984
985 kdb_printf("Backtrace, "
986 "Format - Frame : Return Address (4 potential args on stack) ");
987
988 for (frame_index = 0; frame_index < nframes; frame_index++) {
989 vm_offset_t curframep = (vm_offset_t) frame;
990
991 if (!curframep)
992 break;
993
994 if (curframep & 0x3) {
995 kdb_printf("Unaligned frame\n");
996 goto invalid;
997 }
998
999 if (!kvtophys(curframep) ||
1000 !kvtophys(curframep + sizeof(cframe_t))) {
1001 kdb_printf("No mapping exists for frame pointer\n");
1002 goto invalid;
1003 }
1004
1005 kdb_printf("\n0x%x : 0x%x ",
1006 frame, frame->caller);
1007 if (frame_index < DUMPFRAMES)
1008 raddrs[frame_index] = frame->caller;
1009
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]);
1014
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.
1019 */
1020 if (keepsyms)
1021 panic_print_symbol_name((vm_address_t)frame->caller);
1022
1023 /* Stack grows downward */
1024 if (frame->prev < frame) {
1025 frame = frame->prev;
1026 goto invalid;
1027 }
1028 frame = frame->prev;
1029 }
1030
1031 if (frame_index >= nframes)
1032 kdb_printf("\tBacktrace continues...\n");
1033
1034 goto out;
1035
1036 invalid:
1037 kdb_printf("Backtrace terminated-invalid frame pointer 0x%x\n",frame);
1038 out:
1039
1040 /* Identify kernel modules in the backtrace and display their
1041 * load addresses and dependencies. This routine should walk
1042 * the kmod list safely.
1043 */
1044 if (frame_index)
1045 kmod_dump((vm_offset_t *)&raddrs[0], frame_index);
1046
1047 kdb_printf("\nKernel version:\n%s\n\n",version);
1048
1049 /* Release print backtrace lock, to permit other callers in the
1050 * event of panics on multiple processors.
1051 */
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.
1056 */
1057 bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
1058 while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
1059 }