X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..7ddcb079202367355dddccdfa4318e57d50318be:/osfmk/i386/i386_init.c diff --git a/osfmk/i386/i386_init.c b/osfmk/i386/i386_init.c index 445c6afed..560a88ffc 100644 --- a/osfmk/i386/i386_init.c +++ b/osfmk/i386/i386_init.c @@ -78,20 +78,23 @@ #include #include #include +#include #include #include -#include #include #include #include #include #include #include +#if CONFIG_MTRR #include +#endif #include #if CONFIG_MCA #include #endif +#include #include #include #include @@ -103,6 +106,9 @@ #include #endif #endif +#if DEBUG +#include +#endif #if DEBUG #define DBG(x...) kprintf(x) @@ -122,21 +128,16 @@ extern const char version[]; extern const char version_variant[]; extern int nx_enabled; -extern int noVMX; /* if set, rosetta should not emulate altivec */ - #ifdef __x86_64__ extern void *low_eintstack; #endif -extern void serial_init(void); - void *KPTphys; pd_entry_t *IdlePTD; #ifdef __i386__ pd_entry_t *IdlePDPT64; #endif - char *physfree; /* @@ -166,7 +167,7 @@ fillkpt(pt_entry_t *base, int prot, uintptr_t src, int index, int count) } } -extern vm_offset_t first_avail; +extern pmap_paddr_t first_avail; #ifdef __x86_64__ int break_kprintf = 0; @@ -175,8 +176,8 @@ uint64_t x86_64_pre_sleep(void) { IdlePML4[0] = IdlePML4[KERNEL_PML4_INDEX]; - uint64_t oldcr3 = get_cr3(); - set_cr3((uint32_t) (uintptr_t)ID_MAP_VTOP(IdlePML4)); + uint64_t oldcr3 = get_cr3_raw(); + set_cr3_raw((uint32_t) (uintptr_t)ID_MAP_VTOP(IdlePML4)); return oldcr3; } @@ -184,7 +185,7 @@ void x86_64_post_sleep(uint64_t new_cr3) { IdlePML4[0] = 0; - set_cr3((uint32_t) new_cr3); + set_cr3_raw((uint32_t) new_cr3); } #endif @@ -194,12 +195,11 @@ x86_64_post_sleep(uint64_t new_cr3) #endif - #ifdef __x86_64__ // Set up the physical mapping - NPHYSMAP GB of memory mapped at a high address // NPHYSMAP is determined by the maximum supported RAM size plus 4GB to account // the PCI hole (which is less 4GB but not more). -#define NPHYSMAP MAX(K64_MAXMEM/GB + 4, 4) + // Compile-time guard: extern int maxphymapsupported[NPHYSMAP <= PTE_PER_PAGE ? 1 : -1]; static void @@ -227,6 +227,10 @@ physmap_init(void) IdlePML4[KERNEL_PHYSMAP_INDEX] = ((uintptr_t)ID_MAP_VTOP(physmapL3)) | INTEL_PTE_VALID | INTEL_PTE_WRITE; + if (cpuid_extfeatures() & CPUID_EXTFEATURE_XD) { + IdlePML4[KERNEL_PHYSMAP_INDEX] |= INTEL_PTE_NX; + } + DBG("physical map idlepml4[%d]: 0x%llx\n", KERNEL_PHYSMAP_INDEX, IdlePML4[KERNEL_PHYSMAP_INDEX]); } @@ -267,7 +271,7 @@ Idle_PTs_init(void) #endif // Flush the TLB now we're done rewriting the page tables.. - set_cr3(get_cr3()); + set_cr3_raw(get_cr3_raw()); } /* @@ -302,7 +306,7 @@ vstart(vm_offset_t boot_args_start) lphysfree = kernelBootArgs->kaddr + kernelBootArgs->ksize; physfree = (void *)(uintptr_t)((lphysfree + PAGE_SIZE - 1) &~ (PAGE_SIZE - 1)); #if DEBUG - serial_init(); + pal_serial_init(); #endif DBG("revision 0x%x\n", kernelBootArgs->Revision); DBG("version 0x%x\n", kernelBootArgs->Version); @@ -316,7 +320,13 @@ vstart(vm_offset_t boot_args_start) kernelBootArgs, &kernelBootArgs->ksize, &kernelBootArgs->kaddr); - +#ifdef __x86_64__ + /* enable NX/XD, boot processor */ + if (cpuid_extfeatures() & CPUID_EXTFEATURE_XD) { + wrmsr64(MSR_IA32_EFER, rdmsr64(MSR_IA32_EFER) | MSR_IA32_EFER_NXE); + DBG("vstart() NX/XD enabled\n"); + } +#endif postcode(PSTART_PAGE_TABLES); Idle_PTs_init(); @@ -324,12 +334,31 @@ vstart(vm_offset_t boot_args_start) first_avail = (vm_offset_t)ID_MAP_VTOP(physfree); cpu = 0; + cpu_data_alloc(TRUE); + + + /* + * Setup boot args given the physical start address. + */ + kernelBootArgs = (boot_args *) + ml_static_ptovirt(boot_args_start); + DBG("i386_init(0x%lx) kernelBootArgs=%p\n", + (unsigned long)boot_args_start, kernelBootArgs); + + PE_init_platform(FALSE, kernelBootArgs); + postcode(PE_INIT_PLATFORM_D); } else { /* Find our logical cpu number */ cpu = lapic_to_cpu[(LAPIC_READ(ID)>>LAPIC_ID_SHIFT) & LAPIC_ID_MASK]; + DBG("CPU: %d, GSBASE initial value: 0x%llx\n", cpu, rdmsr64(MSR_IA32_GS_BASE)); +#ifdef __x86_64__ + if (cpuid_extfeatures() & CPUID_EXTFEATURE_XD) { + wrmsr64(MSR_IA32_EFER, rdmsr64(MSR_IA32_EFER) | MSR_IA32_EFER_NXE); + DBG("vstart() NX/XD enabled, non-boot\n"); + } +#endif } - if(is_boot_cpu) cpu_data_alloc(TRUE); #ifdef __x86_64__ if(is_boot_cpu) cpu_desc_init64(cpu_datap(cpu)); @@ -339,14 +368,11 @@ vstart(vm_offset_t boot_args_start) cpu_desc_init(cpu_datap(cpu)); cpu_desc_load(cpu_datap(cpu)); #endif - cpu_mode_init(current_cpu_datap()); - - /* enable NX/XD */ - if (cpuid_extfeatures() & CPUID_EXTFEATURE_XD) - wrmsr64(MSR_IA32_EFER, rdmsr64(MSR_IA32_EFER) | MSR_IA32_EFER_NXE); - DBG("vstart() NX/XD enabled\n"); - - + if (is_boot_cpu) + cpu_mode_init(current_cpu_datap()); /* cpu_mode_init() will be + * invoked on the APs + * via i386_init_slave() + */ #ifdef __x86_64__ /* Done with identity mapping */ IdlePML4[0] = 0; @@ -354,8 +380,13 @@ vstart(vm_offset_t boot_args_start) postcode(VSTART_EXIT); #ifdef __i386__ + if (cpuid_extfeatures() & CPUID_EXTFEATURE_XD) { + wrmsr64(MSR_IA32_EFER, rdmsr64(MSR_IA32_EFER) | MSR_IA32_EFER_NXE); + DBG("vstart() NX/XD enabled, i386\n"); + } + if (is_boot_cpu) - i386_init(boot_args_start); + i386_init(); else i386_init_slave(); /*NOTREACHED*/ @@ -388,46 +419,34 @@ vstart(vm_offset_t boot_args_start) * set up. */ void -i386_init(vm_offset_t boot_args_start) +i386_init(void) { unsigned int maxmem; uint64_t maxmemtouse; unsigned int cpus = 0; boolean_t fidn; -#ifdef __i386__ - boolean_t legacy_mode; -#endif boolean_t IA32e = TRUE; postcode(I386_INIT_ENTRY); + pal_i386_init(); + #if CONFIG_MCA /* Initialize machine-check handling */ mca_cpu_init(); #endif - /* - * Setup boot args given the physical start address. - */ - kernelBootArgs = (boot_args *) - ml_static_ptovirt(boot_args_start); - DBG("i386_init(0x%lx) kernelBootArgs=%p\n", - (unsigned long)boot_args_start, kernelBootArgs); + + kernel_early_bootstrap(); master_cpu = 0; cpu_init(); postcode(CPU_INIT_D); - - PE_init_platform(FALSE, kernelBootArgs); - postcode(PE_INIT_PLATFORM_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); @@ -460,7 +479,6 @@ i386_init(vm_offset_t boot_args_start) max_ncpus = cpus; } - /* * debug support for > 4G systems */ @@ -471,12 +489,21 @@ i386_init(vm_offset_t boot_args_start) force_immediate_debugger_NMI = FALSE; else force_immediate_debugger_NMI = fidn; -#ifdef __i386__ + +#if DEBUG + nanoseconds_to_absolutetime(URGENCY_NOTIFICATION_ASSERT_NS, &urgency_notification_assert_abstime_threshold); +#endif + PE_parse_boot_argn("urgency_notification_abstime", + &urgency_notification_assert_abstime_threshold, + sizeof(urgency_notification_assert_abstime_threshold)); + +#if CONFIG_YONAH /* * At this point we check whether we are a 64-bit processor * and that we're not restricted to legacy mode, 32-bit operation. */ if (cpuid_extfeatures() & CPUID_EXTFEATURE_EM64T) { + boolean_t legacy_mode; kprintf("EM64T supported"); if (PE_parse_boot_argn("-legacy", &legacy_mode, sizeof (legacy_mode))) { kprintf(" but legacy mode forced\n"); @@ -491,27 +518,20 @@ i386_init(vm_offset_t boot_args_start) 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. */ i386_vm_init(maxmemtouse, IA32e, kernelBootArgs); - if ( ! PE_parse_boot_argn("novmx", &noVMX, sizeof (noVMX))) - noVMX = 0; /* OK to support Altivec in rosetta? */ + /* create the console for verbose or pretty mode */ + /* Note: doing this prior to tsc_init() allows for graceful panic! */ + PE_init_platform(TRUE, kernelBootArgs); + PE_create_console(); tsc_init(); power_management_init(); - PE_init_platform(TRUE, kernelBootArgs); - - /* create the console for verbose or pretty mode */ - PE_create_console(); - processor_bootstrap(); thread_bootstrap(); @@ -546,17 +566,24 @@ do_init_slave(boolean_t fast_restart) init_fpu(); +#if CONFIG_MTRR mtrr_update_cpu(); +#endif } else init_param = FAST_SLAVE_INIT; + /* update CPU microcode */ + ucode_update_wake(); + #if CONFIG_VMX /* resume VT operation */ vmx_resume(); #endif +#if CONFIG_MTRR if (!fast_restart) pat_init(); +#endif cpu_thread_init(); /* not strictly necessary */