The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/i386/AT386/model_dep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000-2006 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 <i386/trap.h>
   95 #include <i386/mp.h>            /* mp_rendezvous_break_lock */
   96 #include <architecture/i386/pio.h> /* inb() */
   97 #include <pexpert/i386/boot.h>
   98 #if     MACH_KDB
   99 #include <ddb/db_aout.h>
  100 #endif /* MACH_KDB */
  101 
  102 #include <vm/pmap.h>
  103 #include <vm/vm_map.h>
  104 #include <vm/vm_kern.h>
  105 
  106 #include <i386/mp_desc.h>
  107 #include <i386/mp.h>
  108 #include <i386/cpuid.h>
  109 
  110 #include <IOKit/IOPlatformExpert.h>
  111 #include <IOKit/IOHibernatePrivate.h>
  112 
  113 #include <pexpert/i386/efi.h>
  114 
  115 #include <kern/thread.h>
  116 #include <i386/thread.h>
  117 #include <mach-o/loader.h>
  118 #include <mach-o/nlist.h>
  119 
  120 void    enable_bluebox(void);
  121 void    disable_bluebox(void);
  122 
  123 static void machine_conf(void);
  124 
  125 extern int              default_preemption_rate;
  126 extern int              max_unsafe_quanta;
  127 extern int              max_poll_quanta;
  128 extern unsigned int     panic_is_inited;
  129 
  130 int db_run_mode;
  131 
  132 volatile int pbtcpu = -1;
  133 hw_lock_data_t pbtlock;         /* backtrace print lock */
  134 uint32_t pbtcnt = 0;
  135 
  136 typedef struct _cframe_t {
  137     struct _cframe_t    *prev;
  138     unsigned            caller;
  139     unsigned            args[0];
  140 } cframe_t;
  141 
  142 static unsigned panic_io_port;
  143 static unsigned commit_paniclog_to_nvram;
  144 
  145 void
  146 machine_startup(void)
  147 {
  148         int     boot_arg;
  149 
  150 #if 0
  151         if( PE_get_hotkey( kPEControlKey ))
  152             halt_in_debugger = halt_in_debugger ? 0 : 1;
  153 #endif
  154 
  155         if (PE_parse_boot_arg("debug", &boot_arg)) {
  156                 if (boot_arg & DB_HALT) halt_in_debugger=1;
  157                 if (boot_arg & DB_PRT) disable_debug_output=FALSE; 
  158                 if (boot_arg & DB_SLOG) systemLogDiags=TRUE; 
  159                 if (boot_arg & DB_NMI) panicDebugging=TRUE; 
  160                 if (boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE; 
  161         }
  162 
  163         if (!PE_parse_boot_arg("nvram_paniclog", &commit_paniclog_to_nvram))
  164                 commit_paniclog_to_nvram = 1;
  165 
  166         /*
  167          * Entering the debugger will put the CPUs into a "safe"
  168          * power mode.
  169          */
  170         if (PE_parse_boot_arg("pmsafe_debug", &boot_arg))
  171             pmsafe_debug = boot_arg;
  172 
  173 #if NOTYET
  174         hw_lock_init(&debugger_lock);   /* initialize debugger lock */
  175 #endif
  176         hw_lock_init(&pbtlock);         /* initialize print backtrace lock */
  177 
  178 #if     MACH_KDB
  179         /*
  180          * Initialize KDB
  181          */
  182 #if     DB_MACHINE_COMMANDS
  183         db_machine_commands_install(ppc_db_commands);
  184 #endif  /* DB_MACHINE_COMMANDS */
  185         ddb_init();
  186 
  187         if (boot_arg & DB_KDB)
  188                 current_debugger = KDB_CUR_DB;
  189 
  190         /*
  191          * Cause a breakpoint trap to the debugger before proceeding
  192          * any further if the proper option bit was specified in
  193          * the boot flags.
  194          */
  195         if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
  196                 Debugger("inline call to debugger(machine_startup)");
  197                 halt_in_debugger = 0;
  198                 active_debugger =1;
  199         }
  200 #endif /* MACH_KDB */
  201 
  202         if (PE_parse_boot_arg("preempt", &boot_arg)) {
  203                 default_preemption_rate = boot_arg;
  204         }
  205         if (PE_parse_boot_arg("unsafe", &boot_arg)) {
  206                 max_unsafe_quanta = boot_arg;
  207         }
  208         if (PE_parse_boot_arg("poll", &boot_arg)) {
  209                 max_poll_quanta = boot_arg;
  210         }
  211         if (PE_parse_boot_arg("yield", &boot_arg)) {
  212                 sched_poll_yield_shift = boot_arg;
  213         }
  214         if (PE_parse_boot_arg("idlehalt", &boot_arg)) {
  215                 idlehalt = boot_arg;
  216         }
  217 /* The I/O port to issue a read from, in the event of a panic. Useful for
  218  * triggering logic analyzers.
  219  */
  220         if (PE_parse_boot_arg("panic_io_port", &boot_arg)) {
  221                 /*I/O ports range from 0 through 0xFFFF */
  222                 panic_io_port = boot_arg & 0xffff;
  223         }
  224 
  225         machine_conf();
  226 
  227 #if NOTYET
  228         ml_thrm_init();         /* Start thermal monitoring on this processor */
  229 #endif
  230 
  231         /*
  232          * Start the system.
  233          */
  234         kernel_bootstrap();
  235         /*NOTREACHED*/
  236 }
  237 
  238 
  239 static void
  240 machine_conf(void)
  241 {
  242         machine_info.memory_size = mem_size;
  243 }
  244 
  245 
  246 extern void *gPEEFIRuntimeServices;
  247 extern void *gPEEFISystemTable;
  248 
  249 /*-
  250  *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
  251  *  code or tables extracted from it, as desired without restriction.
  252  *
  253  *  First, the polynomial itself and its table of feedback terms.  The
  254  *  polynomial is
  255  *  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
  256  *
  257  *  Note that we take it "backwards" and put the highest-order term in
  258  *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
  259  *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
  260  *  the MSB being 1
  261  *
  262  *  Note that the usual hardware shift register implementation, which
  263  *  is what we're using (we're merely optimizing it by doing eight-bit
  264  *  chunks at a time) shifts bits into the lowest-order term.  In our
  265  *  implementation, that means shifting towards the right.  Why do we
  266  *  do it this way?  Because the calculated CRC must be transmitted in
  267  *  order from highest-order term to lowest-order term.  UARTs transmit
  268  *  characters in order from LSB to MSB.  By storing the CRC this way
  269  *  we hand it to the UART in the order low-byte to high-byte; the UART
  270  *  sends each low-bit to hight-bit; and the result is transmission bit
  271  *  by bit from highest- to lowest-order term without requiring any bit
  272  *  shuffling on our part.  Reception works similarly
  273  *
  274  *  The feedback terms table consists of 256, 32-bit entries.  Notes
  275  *
  276  *      The table can be generated at runtime if desired; code to do so
  277  *      is shown later.  It might not be obvious, but the feedback
  278  *      terms simply represent the results of eight shift/xor opera
  279  *      tions for all combinations of data and CRC register values
  280  *
  281  *      The values must be right-shifted by eight bits by the "updcrc
  282  *      logic; the shift must be unsigned (bring in zeroes).  On some
  283  *      hardware you could probably optimize the shift in assembler by
  284  *      using byte-swap instructions
  285  *      polynomial $edb88320
  286  *
  287  *
  288  * CRC32 code derived from work by Gary S. Brown.
  289  */
  290 
  291 static uint32_t crc32_tab[] = {
  292         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
  293         0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
  294         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
  295         0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  296         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
  297         0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
  298         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
  299         0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  300         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
  301         0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  302         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
  303         0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  304         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
  305         0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
  306         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
  307         0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  308         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
  309         0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
  310         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
  311         0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  312         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
  313         0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
  314         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
  315         0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  316         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
  317         0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
  318         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
  319         0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  320         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
  321         0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
  322         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
  323         0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  324         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
  325         0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
  326         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
  327         0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  328         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
  329         0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
  330         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
  331         0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  332         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
  333         0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  334         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  335 };
  336 
  337 static uint32_t
  338 crc32(uint32_t crc, const void *buf, size_t size)
  339 {
  340         const uint8_t *p;
  341 
  342         p = buf;
  343         crc = crc ^ ~0U;
  344 
  345         while (size--)
  346                 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
  347 
  348         return crc ^ ~0U;
  349 }
  350 
  351 static void
  352 efi_set_tables_64(EFI_SYSTEM_TABLE_64 * system_table)
  353 {
  354     EFI_RUNTIME_SERVICES_64 *runtime;
  355     uint32_t hdr_cksum;
  356     uint32_t cksum;
  357 
  358     kprintf("Processing 64-bit EFI tables at %p\n", system_table);
  359     do {
  360         if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
  361             kprintf("Bad EFI system table signature\n");
  362             break;
  363         }
  364         // Verify signature of the system table
  365         hdr_cksum = system_table->Hdr.CRC32;
  366         system_table->Hdr.CRC32 = 0;
  367         cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
  368 
  369         //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
  370         system_table->Hdr.CRC32 = hdr_cksum;
  371         if (cksum != hdr_cksum) {
  372             kprintf("Bad EFI system table checksum\n");
  373             break;
  374         }
  375 
  376         gPEEFISystemTable     = system_table;
  377 
  378         kprintf("RuntimeServices table at 0x%qx\n", system_table->RuntimeServices);
  379         runtime = (EFI_RUNTIME_SERVICES_64 *) (uintptr_t)system_table->RuntimeServices; // XXX
  380         kprintf("Checking runtime services table %p\n", runtime);
  381         if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
  382             kprintf("Bad EFI runtime table signature\n");
  383             break;
  384         }
  385 
  386         // Verify signature of runtime services table
  387         hdr_cksum = runtime->Hdr.CRC32;
  388         runtime->Hdr.CRC32 = 0;
  389         cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
  390 
  391         //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
  392         runtime->Hdr.CRC32 = hdr_cksum;
  393         if (cksum != hdr_cksum) {
  394             kprintf("Bad EFI runtime table checksum\n");
  395             break;
  396         }
  397 
  398         gPEEFIRuntimeServices = runtime;
  399     }
  400     while (FALSE);
  401 }
  402 
  403 static void
  404 efi_set_tables_32(EFI_SYSTEM_TABLE * system_table)
  405 {
  406     EFI_RUNTIME_SERVICES *runtime;
  407     uint32_t hdr_cksum;
  408     uint32_t cksum;
  409 
  410     kprintf("Processing 32-bit EFI tables at %p\n", system_table);
  411     do {
  412         if (system_table->Hdr.Signature != EFI_SYSTEM_TABLE_SIGNATURE) {
  413             kprintf("Bad EFI system table signature\n");
  414             break;
  415         }
  416         // Verify signature of the system table
  417         hdr_cksum = system_table->Hdr.CRC32;
  418         system_table->Hdr.CRC32 = 0;
  419         cksum = crc32(0L, system_table, system_table->Hdr.HeaderSize);
  420 
  421         //kprintf("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
  422         system_table->Hdr.CRC32 = hdr_cksum;
  423         if (cksum != hdr_cksum) {
  424             kprintf("Bad EFI system table checksum\n");
  425             break;
  426         }
  427 
  428         gPEEFISystemTable     = system_table;
  429 
  430         kprintf("RuntimeServices table at %p\n", system_table->RuntimeServices);
  431         runtime = (EFI_RUNTIME_SERVICES *) system_table->RuntimeServices;
  432         if (runtime->Hdr.Signature != EFI_RUNTIME_SERVICES_SIGNATURE) {
  433             kprintf("Bad EFI runtime table signature\n");
  434             break;
  435         }
  436 
  437         // Verify signature of runtime services table
  438         hdr_cksum = runtime->Hdr.CRC32;
  439         runtime->Hdr.CRC32 = 0;
  440         cksum = crc32(0L, runtime, runtime->Hdr.HeaderSize);
  441 
  442         //kprintf("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum, hdr_cksum);
  443         runtime->Hdr.CRC32 = hdr_cksum;
  444         if (cksum != hdr_cksum) {
  445             kprintf("Bad EFI runtime table checksum\n");
  446             break;
  447         }
  448 
  449         gPEEFIRuntimeServices = runtime;
  450     }
  451     while (FALSE);
  452 }
  453 
  454 
  455 /* Map in EFI runtime areas. */
  456 static void
  457 efi_init(void)
  458 {
  459     boot_args *args = (boot_args *)PE_state.bootArgs;
  460 
  461     kprintf("Initializing EFI runtime services\n");
  462 
  463     do
  464     {
  465         vm_offset_t vm_size, vm_addr;
  466         vm_map_offset_t phys_addr;
  467         EfiMemoryRange *mptr;
  468         unsigned int msize, mcount;
  469         unsigned int i;
  470 
  471         msize = args->MemoryMapDescriptorSize;
  472         mcount = args->MemoryMapSize / msize;
  473 
  474         mptr = (EfiMemoryRange *)args->MemoryMap;
  475         for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
  476             if (((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) ) {
  477                 vm_size = i386_ptob((uint32_t)mptr->NumberOfPages);
  478                 vm_addr =   (vm_offset_t) mptr->VirtualStart;
  479                 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
  480                 pmap_map(vm_addr, phys_addr, phys_addr + round_page(vm_size),
  481                      (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
  482                      (mptr->Type == EfiMemoryMappedIO)       ? VM_WIMG_IO   : VM_WIMG_USE_DEFAULT);
  483             }
  484         }
  485 
  486         if (args->Version > 1)
  487                 panic("Incompatible boot args version %d\n", args->Version);
  488 
  489         kprintf("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
  490         if (args->Revision >= 4 && args->efiMode == kBootArgsEfiMode64) {
  491                 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) args->efiSystemTable);
  492         } else {
  493                 efi_set_tables_32((EFI_SYSTEM_TABLE *) args->efiSystemTable);
  494         }
  495     }
  496     while (FALSE);
  497 
  498     return;
  499 }
  500 
  501 /* Remap EFI runtime areas. */
  502 void
  503 hibernate_newruntime_map(void * map, vm_size_t map_size, uint32_t system_table_offset)
  504 {
  505     boot_args *args = (boot_args *)PE_state.bootArgs;
  506 
  507     kprintf("Reinitializing EFI runtime services\n");
  508 
  509     if (args->Revision < 3)
  510         return;
  511     do
  512     {
  513         vm_offset_t vm_size, vm_addr;
  514         vm_map_offset_t phys_addr;
  515         EfiMemoryRange *mptr;
  516         unsigned int msize, mcount;
  517         unsigned int i;
  518 
  519         gPEEFISystemTable     = 0;
  520         gPEEFIRuntimeServices = 0;
  521 
  522         system_table_offset += ptoa_32(args->efiRuntimeServicesPageStart);
  523 
  524         kprintf("Old system table 0x%x, new 0x%x\n",
  525             (uint32_t)args->efiSystemTable,    system_table_offset);
  526 
  527         args->efiSystemTable    = system_table_offset;
  528 
  529         kprintf("Old map:\n");
  530         msize = args->MemoryMapDescriptorSize;
  531         mcount = args->MemoryMapSize / msize;
  532         mptr = (EfiMemoryRange *)args->MemoryMap;
  533         for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
  534             if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
  535 
  536                 vm_size = i386_ptob((uint32_t)mptr->NumberOfPages);
  537                 vm_addr =   (vm_offset_t) mptr->VirtualStart;
  538                 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
  539 
  540                 kprintf("mapping[%u] %qx @ %x, %llu\n", mptr->Type, phys_addr, vm_addr, mptr->NumberOfPages);
  541             }
  542         }
  543 
  544         pmap_remove(kernel_pmap, i386_ptob(args->efiRuntimeServicesPageStart), 
  545                                  i386_ptob(args->efiRuntimeServicesPageStart + args->efiRuntimeServicesPageCount));
  546 
  547         kprintf("New map:\n");
  548         msize = args->MemoryMapDescriptorSize;
  549         mcount = map_size / msize;
  550         mptr = map;
  551         for (i=0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
  552             if ((mptr->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
  553 
  554                 vm_size = i386_ptob((uint32_t)mptr->NumberOfPages);
  555                 vm_addr =   (vm_offset_t) mptr->VirtualStart;
  556                 phys_addr = (vm_map_offset_t) mptr->PhysicalStart;
  557 
  558                 kprintf("mapping[%u] %qx @ %x, %llu\n", mptr->Type, phys_addr, vm_addr, mptr->NumberOfPages);
  559 
  560                 pmap_map(vm_addr, phys_addr, phys_addr + round_page(vm_size),
  561                          (mptr->Type == kEfiRuntimeServicesCode) ? VM_PROT_READ | VM_PROT_EXECUTE : VM_PROT_READ|VM_PROT_WRITE,
  562                          (mptr->Type == EfiMemoryMappedIO)       ? VM_WIMG_IO   : VM_WIMG_USE_DEFAULT);
  563             }
  564         }
  565 
  566         if (args->Version > 1)
  567                 panic("Incompatible boot args version %d\n", args->Version);
  568 
  569         kprintf("Boot args version %d revision %d mode %d\n", args->Version, args->Revision, args->efiMode);
  570         if (args->Revision >= 4 && args->efiMode == kBootArgsEfiMode64) {
  571                 efi_set_tables_64((EFI_SYSTEM_TABLE_64 *) args->efiSystemTable);
  572         } else {
  573                 efi_set_tables_32((EFI_SYSTEM_TABLE *) args->efiSystemTable);
  574         }
  575     }
  576     while (FALSE);
  577 
  578     kprintf("Done reinitializing EFI runtime services\n");
  579 
  580     return;
  581 }
  582 
  583 /*
  584  * Find devices.  The system is alive.
  585  */
  586 void
  587 machine_init(void)
  588 {
  589         /* Ensure panic buffer is initialized. */
  590         debug_log_init();
  591 
  592         /*
  593          * Display CPU identification
  594          */
  595         cpuid_cpu_display("CPU identification");
  596         cpuid_feature_display("CPU features");
  597         cpuid_extfeature_display("CPU extended features");
  598 
  599         /*
  600          * Initialize EFI runtime services.
  601          */
  602         efi_init();
  603 
  604         smp_init();
  605 
  606         /*
  607          * Set up to use floating point.
  608          */
  609         init_fpu();
  610 
  611         /*
  612          * Configure clock devices.
  613          */
  614         clock_config();
  615 
  616         /*
  617          * Initialize MTRR from boot processor.
  618          */
  619         mtrr_init();
  620 
  621         /*
  622          * Set up PAT for boot processor.
  623          */
  624         pat_init();
  625 
  626         /*
  627          * Free lowmem pages
  628          */
  629         x86_lowmem_free();
  630 }
  631 
  632 /*
  633  * Halt a cpu.
  634  */
  635 void
  636 halt_cpu(void)
  637 {
  638         halt_all_cpus(FALSE);
  639 }
  640 
  641 int reset_mem_on_reboot = 1;
  642 
  643 /*
  644  * Halt the system or reboot.
  645  */
  646 void
  647 halt_all_cpus(boolean_t reboot)
  648 {
  649         if (reboot) {
  650                 printf("MACH Reboot\n");
  651                 PEHaltRestart( kPERestartCPU );
  652         } else {
  653                 printf("CPU halted\n");
  654                 PEHaltRestart( kPEHaltCPU );
  655         }
  656         while(1);
  657 }
  658 
  659  
  660 /* Issue an I/O port read if one has been requested - this is an event logic
  661  * analyzers can use as a trigger point.
  662  */
  663 
  664 void
  665 panic_io_port_read(void) {
  666         if (panic_io_port)
  667                 (void)inb(panic_io_port);
  668 }
  669 
  670 /* For use with the MP rendezvous mechanism
  671  */
  672 
  673 static void
  674 machine_halt_cpu(__unused void *arg) {
  675         panic_io_port_read();
  676         pmCPUHalt(PM_HALT_DEBUG);
  677 }
  678 
  679 void
  680 Debugger(
  681         const char      *message)
  682 {
  683         unsigned long pi_size = 0;
  684         void *stackptr;
  685 
  686         hw_atomic_add(&debug_mode, 1);   
  687         if (!panic_is_inited) {
  688                 postcode(PANIC_HLT);
  689                 asm("hlt");
  690         }
  691 
  692 
  693         printf("Debugger called: <%s>\n", message);
  694         kprintf("Debugger called: <%s>\n", message);
  695 
  696         /*
  697          * Skip the graphical panic box if no panic string.
  698          * This is the case if we're being called from
  699          *   host_reboot(,HOST_REBOOT_DEBUGGER)
  700          * as a quiet way into the debugger.
  701          */
  702 
  703         if (panicstr) {
  704                 disable_preemption();
  705 
  706 /* Issue an I/O port read if one has been requested - this is an event logic
  707  * analyzers can use as a trigger point.
  708  */
  709                 panic_io_port_read();
  710 
  711                 /* Obtain current frame pointer */
  712                 __asm__ volatile("movl %%ebp, %0" : "=m" (stackptr));
  713 
  714                 /* Print backtrace - callee is internally synchronized */
  715                 panic_i386_backtrace(stackptr, 16);
  716 
  717                 /* everything should be printed now so copy to NVRAM
  718                  */
  719 
  720                 if( debug_buf_size > 0) {
  721                   /* Optionally sync the panic log, if any, to NVRAM
  722                    * This is the default.
  723                    */
  724                     if (commit_paniclog_to_nvram) {
  725                         unsigned int bufpos;
  726 
  727                         debug_putc(0);
  728 
  729                         /* Now call the compressor */
  730                         /* XXX Consider using the WKdm compressor in the
  731                          * future, rather than just packing - would need to
  732                          * be co-ordinated with crashreporter, which decodes
  733                          * this post-restart. The compressor should be
  734                          * capable of in-place compression.
  735                          */
  736                         bufpos = packA(debug_buf,
  737                             (unsigned int) (debug_buf_ptr - debug_buf), debug_buf_size);
  738                         /* If compression was successful,
  739                          * use the compressed length
  740                          */
  741                         pi_size = bufpos ? bufpos : (unsigned) (debug_buf_ptr - debug_buf);
  742 
  743                         /* Save panic log to non-volatile store
  744                          * Panic info handler must truncate data that is 
  745                          * too long for this platform.
  746                          * This call must save data synchronously,
  747                          * since we can subsequently halt the system.
  748                          */
  749                         kprintf("Attempting to commit panic log to NVRAM\n");
  750                         pi_size = PESavePanicInfo((unsigned char *)debug_buf,
  751                             pi_size );
  752 
  753                         /* Uncompress in-place, to permit examination of
  754                          * the panic log by debuggers.
  755                          */
  756 
  757                         if (bufpos) {
  758                           unpackA(debug_buf, bufpos);
  759                         }
  760                     }
  761                 }
  762                 draw_panic_dialog();
  763 
  764                 if (!panicDebugging) {
  765                         /* Clear the MP rendezvous function lock, in the event
  766                          * that a panic occurred while in that codepath.
  767                          */
  768                         mp_rendezvous_break_lock();
  769 #if CONFIG_EMBEDDED
  770                         PEHaltRestart(kPEPanicRestartCPU);
  771 #else
  772                         /* Force all CPUs to disable interrupts and HLT.
  773                          * We've panicked, and shouldn't depend on the
  774                          * PEHaltRestart() mechanism, which relies on several
  775                          * bits of infrastructure.
  776                          */
  777                         mp_rendezvous_no_intrs(machine_halt_cpu, NULL);
  778 #endif
  779                         /* NOT REACHED */
  780                 }
  781         }
  782 
  783         __asm__("int3");
  784         hw_atomic_sub(&debug_mode, 1);   
  785 }
  786 
  787 void
  788 enable_bluebox(void)
  789 {
  790 }
  791 
  792 void
  793 disable_bluebox(void)
  794 {
  795 }
  796 
  797 char *
  798 machine_boot_info(char *buf, __unused vm_size_t size)
  799 {
  800         *buf ='\0';
  801         return buf;
  802 }
  803 
  804 
  805 struct pasc {
  806     unsigned a: 7;
  807     unsigned b: 7;
  808     unsigned c: 7;
  809     unsigned d: 7;
  810     unsigned e: 7;
  811     unsigned f: 7;
  812     unsigned g: 7;
  813     unsigned h: 7;
  814 }  __attribute__((packed));
  815 
  816 typedef struct pasc pasc_t;
  817 
  818 /* Routines for address - symbol translation. Not called unless the "keepsyms"
  819  * boot-arg is supplied.
  820  */
  821 
  822 static int
  823 panic_print_macho_symbol_name(struct mach_header *mh, vm_address_t search)
  824 {
  825     struct nlist                        *sym = NULL;
  826     struct load_command         *cmd;
  827     struct segment_command      *orig_ts = NULL, *orig_le = NULL;
  828     struct symtab_command       *orig_st = NULL;
  829     unsigned int                        i;
  830     char                                        *strings, *bestsym = NULL;
  831     vm_address_t                        bestaddr = 0, diff, curdiff;
  832     
  833     if (mh->magic != MH_MAGIC) {
  834         /* bad magic number */
  835         return 0;
  836     }
  837     
  838     cmd = (struct load_command *) &mh[1];
  839     for (i = 0; i < mh->ncmds; i++) {
  840         if (cmd->cmd == LC_SEGMENT) {
  841             struct segment_command *orig_sg = (struct segment_command *) cmd;
  842             
  843             if (strncmp(SEG_TEXT, orig_sg->segname,
  844                                     sizeof(orig_sg->segname)) == 0)
  845                 orig_ts = orig_sg;
  846             else if (strncmp(SEG_LINKEDIT, orig_sg->segname,
  847                                     sizeof(orig_sg->segname)) == 0)
  848                 orig_le = orig_sg;
  849             else if (strncmp("", orig_sg->segname,
  850                                     sizeof(orig_sg->segname)) == 0)
  851                 orig_ts = orig_sg; /* kexts have a single unnamed segment */
  852         }
  853         else if (cmd->cmd == LC_SYMTAB)
  854             orig_st = (struct symtab_command *) cmd;
  855         
  856         cmd = (struct load_command *) ((caddr_t) cmd + cmd->cmdsize);
  857     }
  858     
  859     if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL))
  860         return 0;
  861     
  862     /* kexts don't have a LINKEDIT segment for now, so we'll never get this far for kexts */
  863     
  864     vm_address_t slide = ((vm_address_t)mh) - orig_ts->vmaddr;
  865     if (slide != 0)
  866         search -= slide; /* adjusting search since the binary has slid */
  867     
  868     if ((search < orig_ts->vmaddr) ||
  869         (search >= orig_ts->vmaddr + orig_ts->vmsize)) {
  870         /* search out of range for this mach header */
  871         return 0;
  872     }
  873     
  874     sym = (struct nlist *)orig_le->vmaddr;
  875     strings = ((char *)sym) + orig_st->nsyms * sizeof(struct nlist);
  876     diff = search;
  877     
  878     for (i = 0; i < orig_st->nsyms; i++) {
  879         if (sym[i].n_value <= search) {
  880             curdiff = search - (vm_address_t)sym[i].n_value;
  881             if (curdiff < diff) {
  882                 diff = curdiff;
  883                 bestaddr = sym[i].n_value;
  884                 bestsym = strings + sym[i].n_un.n_strx;
  885             }
  886         }
  887     }
  888     
  889     if (bestsym != NULL) {
  890         if (diff != 0) {
  891             kdb_printf("%s + 0x%08x \n", bestsym, diff);
  892         } else {
  893             kdb_printf("%s \n", bestsym);
  894         }
  895         return 1;
  896     }
  897     return 0;
  898 }
  899 
  900 extern kmod_info_t * kmod; /* the list of modules */
  901 
  902 static void
  903 panic_print_kmod_symbol_name(vm_address_t search)
  904 {
  905     kmod_info_t *                       current_kmod = kmod;
  906     
  907     while (current_kmod != NULL) {
  908         if ((current_kmod->address <= search) &&
  909             (current_kmod->address + current_kmod->size > search))
  910             break;
  911         current_kmod = current_kmod->next;
  912     }
  913     if (current_kmod != NULL) {
  914         /* if kexts had symbol table loaded, we'd call search_symbol_name again; alas, they don't */
  915         kdb_printf("%s + %d \n", current_kmod->name, search - current_kmod->address);
  916     }
  917 }
  918 
  919 extern struct mach_header _mh_execute_header; /* the kernel's mach header */
  920 
  921 static void
  922 panic_print_symbol_name(vm_address_t search)
  923 {
  924     /* try searching in the kernel */
  925     if (panic_print_macho_symbol_name(&_mh_execute_header, search) == 0) {
  926         /* that failed, now try to search for the right kext */
  927         panic_print_kmod_symbol_name(search);
  928     }
  929 }
  930 
  931 /* Generate a backtrace, given a frame pointer - this routine
  932  * should walk the stack safely. The trace is appended to the panic log
  933  * and conditionally, to the console. If the trace contains kernel module
  934  * addresses, display the module name, load address and dependencies.
  935  */
  936 
  937 #define DUMPFRAMES 32
  938 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
  939 void
  940 panic_i386_backtrace(void *_frame, int nframes)
  941 {
  942         cframe_t        *frame = (cframe_t *)_frame;
  943         vm_offset_t raddrs[DUMPFRAMES];
  944         int frame_index;
  945         volatile uint32_t *ppbtcnt = &pbtcnt;
  946         uint64_t bt_tsc_timeout;
  947         boolean_t keepsyms = FALSE;
  948 
  949         if(pbtcpu != cpu_number()) {
  950                 hw_atomic_add(&pbtcnt, 1);
  951                 /* Spin on print backtrace lock, which serializes output
  952                  * Continue anyway if a timeout occurs.
  953                  */
  954                 hw_lock_to(&pbtlock, LockTimeOutTSC);
  955                 pbtcpu = cpu_number();
  956         }
  957 
  958         PE_parse_boot_arg("keepsyms", &keepsyms);
  959 
  960         kdb_printf("Backtrace, "
  961             "Format - Frame : Return Address (4 potential args on stack) \n");
  962 
  963         for (frame_index = 0; frame_index < nframes; frame_index++) {
  964                 vm_offset_t curframep = (vm_offset_t) frame;
  965 
  966                 if (!curframep)
  967                         break;
  968 
  969                 if (curframep & 0x3) {
  970                         kdb_printf("Unaligned frame\n");
  971                         goto invalid;
  972                 }
  973 
  974                 if (!kvtophys(curframep) ||
  975                     !kvtophys(curframep + sizeof(cframe_t))) {
  976                         kdb_printf("No mapping exists for frame pointer\n");
  977                         goto invalid;
  978                 }
  979 
  980                 kdb_printf("%p : 0x%x ", frame, frame->caller);
  981                 if (frame_index < DUMPFRAMES)
  982                         raddrs[frame_index] = frame->caller;
  983 
  984                 if (kvtophys((vm_offset_t)&(frame->args[3])))
  985                         kdb_printf("(0x%x 0x%x 0x%x 0x%x) \n",
  986                             frame->args[0], frame->args[1],
  987                             frame->args[2], frame->args[3]);
  988 
  989                 /* Display address-symbol translation only if the "keepsyms"
  990                  * boot-arg is suppplied, since we unload LINKEDIT otherwise.
  991                  * This routine is potentially unsafe; also, function
  992                  * boundary identification is unreliable after a strip -x.
  993                  */
  994                 if (keepsyms)
  995                         panic_print_symbol_name((vm_address_t)frame->caller);
  996                 
  997                 /* Stack grows downward */
  998                 if (frame->prev < frame) {
  999                         frame = frame->prev;
 1000                         goto invalid;
 1001                 }
 1002                 frame = frame->prev;
 1003         }
 1004 
 1005         if (frame_index >= nframes)
 1006                 kdb_printf("\tBacktrace continues...\n");
 1007 
 1008         goto out;
 1009 
 1010 invalid:
 1011         kdb_printf("Backtrace terminated-invalid frame pointer %p\n",frame);
 1012 out:
 1013 
 1014         /* Identify kernel modules in the backtrace and display their
 1015          * load addresses and dependencies. This routine should walk
 1016          * the kmod list safely.
 1017          */
 1018         if (frame_index)
 1019                 kmod_dump((vm_offset_t *)&raddrs[0], frame_index);
 1020 
 1021         panic_display_system_configuration();
 1022         /* Release print backtrace lock, to permit other callers in the
 1023          * event of panics on multiple processors.
 1024          */
 1025         hw_lock_unlock(&pbtlock);
 1026         hw_atomic_sub(&pbtcnt, 1);
 1027         /* Wait for other processors to complete output
 1028          * Timeout and continue after PBT_TIMEOUT_CYCLES.
 1029          */
 1030         bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
 1031         while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
 1032 }

Cache object: ec472e1b4d4805342085773798b51f29


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.