X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..593a1d5fd87cdf5b46dd5fcb84467b432cea0f91:/osfmk/i386/i386_init.c diff --git a/osfmk/i386/i386_init.c b/osfmk/i386/i386_init.c index 45034034c..8005189dd 100644 --- a/osfmk/i386/i386_init.c +++ b/osfmk/i386/i386_init.c @@ -1,31 +1,29 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2008 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the - * License may not be used to create, or enable the creation or - * redistribution of, unlawful or unlicensed copies of an Apple operating - * system, or to circumvent, violate, or enable the circumvention or - * violation of, any terms of an Apple operating system software license - * agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -58,7 +56,6 @@ #include #include -#include #include @@ -73,147 +70,169 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include +#include #include +#include #include +#include +#include +#include +#include /* LcksOpts */ #if MACH_KDB #include #endif /* MACH_KDB */ #include -#ifdef __MACHO__ -#include - -static KernelBootArgs_t *kernelBootArgs; -#endif - -vm_offset_t boot_args_start = 0; /* pointer to kernel arguments, set in start.s */ -#ifdef __MACHO__ -#include -vm_offset_t edata, etext, end; - -/* operations only against currently loaded 32 bit mach kernel */ -extern struct segment_command *getsegbyname(const char *); -extern struct section *firstsect(struct segment_command *); -extern struct section *nextsect(struct segment_command *, struct section *); - -/* - * Called first for a mach-o kernel before paging is set up. - * Returns the first available physical address in memory. - */ - -void -i386_preinit(void) -{ - struct segment_command *sgp; - struct section *sp; - struct KernelBootArgs *pp; - int i; - - sgp = getsegbyname("__DATA"); - if (sgp) { - sp = firstsect(sgp); - if (sp) { - do { - if ((sp->flags & S_ZEROFILL)) - bzero((char *) sp->addr, sp->size); - } while ((sp = nextsect(sgp, sp))); - } - } +static boot_args *kernelBootArgs; - kernelBootArgs = (KernelBootArgs_t *) - ml_static_ptovirt(boot_args_start); - pp = (struct KernelBootArgs *) kernelBootArgs; - pp->configEnd = (char *) - ml_static_ptovirt((vm_offset_t) pp->configEnd); - for (i = 0; i < pp->numBootDrivers; i++) { - pp->driverConfig[i].address = (unsigned) - ml_static_ptovirt(pp->driverConfig[i].address); - } - return; -} -#endif +int debug_task; +extern int disableConsoleOutput; extern const char version[]; extern const char version_variant[]; +extern int nx_enabled; + +extern int noVMX; /* if set, rosetta should not emulate altivec */ /* * Cpu initialization. Running virtual, but without MACH VM - * set up. First C routine called, unless i386_preinit() was called first. + * set up. First C routine called. */ void -i386_init(void) +i386_init(vm_offset_t boot_args_start) { unsigned int maxmem; + uint64_t maxmemtouse; unsigned int cpus; + boolean_t legacy_mode; + boolean_t fidn; postcode(I386_INIT_ENTRY); - master_cpu = 0; - cpu_data_alloc(TRUE); - cpu_init(); - postcode(CPU_INIT_D); + i386_macho_zerofill(); + + /* Initialize machine-check handling */ + mca_cpu_init(); /* - * Setup some processor related structures to satisfy funnels. - * Must be done before using unparallelized device drivers. + * Setup boot args given the physical start address. */ - processor_bootstrap(); + kernelBootArgs = (boot_args *) + ml_static_ptovirt(boot_args_start); + kernelBootArgs->MemoryMap = (uint32_t) + ml_static_ptovirt((vm_offset_t)kernelBootArgs->MemoryMap); + kernelBootArgs->deviceTreeP = (uint32_t) + ml_static_ptovirt((vm_offset_t)kernelBootArgs->deviceTreeP); + + master_cpu = 0; + (void) cpu_data_alloc(TRUE); + cpu_init(); + postcode(CPU_INIT_D); PE_init_platform(FALSE, kernelBootArgs); postcode(PE_INIT_PLATFORM_D); - /* - * Set up initial thread so current_thread() works early on - */ - thread_bootstrap(); - postcode(THREAD_BOOTSTRAP_D); - printf_init(); /* Init this in case we need debugger */ panic_init(); /* Init this in case we need debugger */ /* setup debugging output if one has been chosen */ PE_init_kprintf(FALSE); + if (!PE_parse_boot_argn("diag", &dgWork.dgFlags, sizeof (dgWork.dgFlags))) + dgWork.dgFlags = 0; + + serialmode = 0; + if(PE_parse_boot_argn("serial", &serialmode, sizeof (serialmode))) { + /* We want a serial keyboard and/or console */ + kprintf("Serial mode specified: %08X\n", serialmode); + } + if(serialmode & 1) { + (void)switch_to_serial_console(); + disableConsoleOutput = FALSE; /* Allow printfs to happen */ + } + /* setup console output */ PE_init_printf(FALSE); kprintf("version_variant = %s\n", version_variant); kprintf("version = %s\n", version); + + if (!PE_parse_boot_argn("maxmem", &maxmem, sizeof (maxmem))) + maxmemtouse = 0; + else + maxmemtouse = ((uint64_t)maxmem) * (uint64_t)(1024 * 1024); + + if (PE_parse_boot_argn("cpus", &cpus, sizeof (cpus))) { + if ((0 < cpus) && (cpus < max_ncpus)) + max_ncpus = cpus; + } + + /* + * debug support for > 4G systems + */ + if (!PE_parse_boot_argn("himemory_mode", &vm_himemory_mode, sizeof (vm_himemory_mode))) + vm_himemory_mode = 0; + + if (!PE_parse_boot_argn("immediate_NMI", &fidn, sizeof (fidn))) + force_immediate_debugger_NMI = FALSE; + else + force_immediate_debugger_NMI = fidn; + + /* + * At this point we check whether we are a 64-bit processor + * and that we're not restricted to legacy mode, 32-bit operation. + */ + boolean_t IA32e = FALSE; + if (cpuid_extfeatures() & CPUID_EXTFEATURE_EM64T) { + kprintf("EM64T supported"); + if (PE_parse_boot_argn("-legacy", &legacy_mode, sizeof (legacy_mode))) { + kprintf(" but legacy mode forced\n"); + } else { + IA32e = TRUE; + kprintf(" and will be enabled\n"); + } + } + + if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD)) + nx_enabled = 0; + + /* Obtain "lcks" options:this currently controls lock statistics */ + if (!PE_parse_boot_argn("lcks", &LcksOpts, sizeof (LcksOpts))) + LcksOpts = 0; /* * VM initialization, after this we're using page tables... * The maximum number of cpus must be set beforehand. */ - if (!PE_parse_boot_arg("maxmem", &maxmem)) - maxmem=0; - else - maxmem = maxmem * (1024 * 1024); + i386_vm_init(maxmemtouse, IA32e, kernelBootArgs); - if (PE_parse_boot_arg("cpus", &cpus)) { - if ((0 < cpus) && (cpus < max_ncpus)) - max_ncpus = cpus; - } + if ( ! PE_parse_boot_argn("novmx", &noVMX, sizeof (noVMX))) + noVMX = 0; /* OK to support Altivec in rosetta? */ - i386_vm_init(maxmem, kernelBootArgs); + tsc_init(); + power_management_init(); PE_init_platform(TRUE, kernelBootArgs); /* create the console for verbose or pretty mode */ PE_create_console(); - machine_startup(); + processor_bootstrap(); + thread_bootstrap(); + machine_startup(); }