X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/378393581903b274cb7a4d18e0d978071a6b592d..4452a7af2eac33dbad800bcc91f2399d62c18f53:/osfmk/i386/i386_init.c diff --git a/osfmk/i386/i386_init.c b/osfmk/i386/i386_init.c index 78d4cef00..947f434dc 100644 --- a/osfmk/i386/i386_init.c +++ b/osfmk/i386/i386_init.c @@ -1,23 +1,29 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * 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_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -50,7 +56,6 @@ #include #include -#include #include @@ -65,120 +70,104 @@ #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 #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; +static boot_args *kernelBootArgs; -/* 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. - */ +extern int disableConsoleOutput; +extern const char version[]; +extern const char version_variant[]; +extern int nx_enabled; -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))); - } - } +extern int noVMX; /* if set, rosetta should not emulate altivec */ - 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 +void cpu_stack_set(void); -extern const char version[]; -extern const char version_variant[]; /* * 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; 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); + /* init processor performance control */ + pmsInit(); + 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_arg("diag", &dgWork.dgFlags)) + dgWork.dgFlags = 0; + + serialmode = 0; + if(PE_parse_boot_arg("serial", &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); @@ -190,22 +179,55 @@ i386_init(void) * The maximum number of cpus must be set beforehand. */ if (!PE_parse_boot_arg("maxmem", &maxmem)) - maxmem=0; + maxmemtouse=0; else - maxmem = maxmem * (1024 * 1024); + maxmemtouse = ((uint64_t)maxmem) * (uint64_t)(1024 * 1024); if (PE_parse_boot_arg("cpus", &cpus)) { if ((0 < cpus) && (cpus < max_ncpus)) max_ncpus = cpus; } - i386_vm_init(maxmem, kernelBootArgs); + /* + * debug support for > 4G systems + */ + if (!PE_parse_boot_arg("himemory_mode", &vm_himemory_mode)) + vm_himemory_mode = 0; + + /* + * 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_arg("-legacy", &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; + + i386_vm_init(maxmemtouse, IA32e, kernelBootArgs); + + if ( ! PE_parse_boot_arg("novmx", &noVMX)) + noVMX = 0; /* OK to support Altivec in rosetta? */ + + tsc_init(); + hpet_init(); + power_management_init(); PE_init_platform(TRUE, kernelBootArgs); /* create the console for verbose or pretty mode */ PE_create_console(); + processor_bootstrap(); + thread_bootstrap(); + machine_startup(); }