X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/13fec9890cf095cc781fdf7b8917cb03bf32dd4c..c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1:/osfmk/i386/i386_init.c diff --git a/osfmk/i386/i386_init.c b/osfmk/i386/i386_init.c index 78d4cef00..46cd0b4f7 100644 --- a/osfmk/i386/i386_init.c +++ b/osfmk/i386/i386_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -50,7 +50,6 @@ #include #include -#include #include @@ -65,120 +64,100 @@ #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 +static boot_args *kernelBootArgs; -vm_offset_t boot_args_start = 0; /* pointer to kernel arguments, set in start.s */ - -#ifdef __MACHO__ -#include -vm_offset_t edata, etext, end; +extern int disableConsoleOutput; +extern const char version[]; +extern const char version_variant[]; +extern int nx_enabled; -/* 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 *); +extern int noVMX; /* if set, rosetta should not emulate altivec */ -/* - * Called first for a mach-o kernel before paging is set up. - * Returns the first available physical address in memory. - */ +void cpu_stack_set(void); -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))); - } - } - - 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 - -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(); /* - * 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 +169,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(); }