X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..5d5c5d0d5b79ade9a973d55186ffda2638ba2b6e:/osfmk/i386/i386_init.c

diff --git a/osfmk/i386/i386_init.c b/osfmk/i386/i386_init.c
index 45034034c..887624b23 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_OSREFERENCE_HEADER_START@
  * 
@@ -58,7 +58,6 @@
 
 #include <platforms.h>
 #include <mach_kdb.h>
-#include <himem.h>
 
 #include <mach/i386/vm_param.h>
 
@@ -73,120 +72,100 @@
 #include <kern/misc_protos.h>
 #include <kern/startup.h>
 #include <kern/clock.h>
+#include <kern/pms.h>
 #include <kern/xpr.h>
 #include <kern/cpu_data.h>
 #include <kern/processor.h>
+#include <console/serial_protos.h>
 #include <vm/vm_page.h>
 #include <vm/pmap.h>
 #include <vm/vm_kern.h>
 #include <i386/fpu.h>
 #include <i386/pmap.h>
 #include <i386/ipl.h>
-#include <i386/pio.h>
 #include <i386/misc_protos.h>
 #include <i386/cpuid.h>
 #include <i386/mp.h>
+#include <i386/mp_desc.h>
 #include <i386/machine_routines.h>
 #include <i386/postcode.h>
+#include <i386/Diagnostics.h>
+#include <i386/pmCPU.h>
+#include <i386/tsc.h>
+#include <i386/hpet.h>
 #if	MACH_KDB
 #include <ddb/db_aout.h>
 #endif /* MACH_KDB */
 #include <ddb/tr.h>
-#ifdef __MACHO__
-#include <mach/thread_status.h>
 
-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	<mach-o/loader.h>
-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);
 
@@ -198,22 +177,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();
 
 }