* Basic initialization for I386 - ISA bus machines.
*/
-#include <cpus.h>
#include <platforms.h>
-#include <mp_v1_1.h>
#include <mach_kdb.h>
#include <himem.h>
-#include <fast_idle.h>
#include <mach/i386/vm_param.h>
#include <mach/vm_prot.h>
#include <mach/machine.h>
#include <mach/time_value.h>
-#include <kern/etap_macros.h>
#include <kern/spl.h>
#include <kern/assert.h>
#include <kern/debug.h>
#include <kern/misc_protos.h>
#include <kern/startup.h>
#include <kern/clock.h>
-#include <kern/time_out.h>
-#include <kern/xpr.h>
#include <kern/cpu_data.h>
-#include <vm/vm_page.h>
-#include <vm/pmap.h>
-#include <vm/vm_kern.h>
+#include <kern/machine.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/rtclock_entries.h>
-#include <i386/AT386/mp/mp.h>
+#include <i386/mp.h>
+#include <i386/mtrr.h>
+#include <i386/postcode.h>
+#include <pexpert/i386/boot.h>
#if MACH_KDB
#include <ddb/db_aout.h>
#endif /* MACH_KDB */
-#include <ddb/tr.h>
-#ifdef __MACHO__
-#include <i386/AT386/kernBootStruct.h>
-#include <mach/boot_info.h>
-#include <mach/thread_status.h>
-#endif
-#if NCPUS > 1
#include <i386/mp_desc.h>
-#endif /* NCPUS */
-
-#if MP_V1_1
-#include <i386/AT386/mp/mp_v1_1.h>
-#endif /* MP_V1_1 */
-
-vm_size_t mem_size = 0;
-vm_offset_t first_addr = 0; /* set by start.s - keep out of bss */
-vm_offset_t first_avail = 0;/* first after page tables */
-vm_offset_t last_addr;
-
-vm_offset_t avail_start, avail_end;
-vm_offset_t virtual_avail, virtual_end;
-vm_offset_t hole_start, hole_end;
-vm_offset_t avail_next;
-unsigned int avail_remaining;
-
-/* parameters passed from bootstrap loader */
-int cnvmem = 0; /* must be in .data section */
-int extmem = 0;
-
-/* FIXME!! REMOVE WHEN OSFMK DEVICES ARE COMPLETELY PULLED OUT */
-int dev_name_count = 0;
-int dev_name_list = 0;
-
-#ifndef __MACHO__
-extern char edata, end;
-#endif
-
-extern char version[];
-
-int rebootflag = 0; /* exported to kdintr */
+#include <i386/mp.h>
+#include <IOKit/IOPlatformExpert.h>
-void parse_arguments(void);
-const char *getenv(const char *);
-
-#define BOOT_LINE_LENGTH 160
-char boot_string_store[BOOT_LINE_LENGTH] = {0};
-char *boot_string = (char *)0;
-int boot_string_sz = BOOT_LINE_LENGTH;
-int boottype = 0;
-
-#if __MACHO__
-#include <mach-o/loader.h>
-vm_offset_t edata, etext, end;
-
-extern struct mach_header _mh_execute_header;
-void *sectTEXTB; int sectSizeTEXT;
-void *sectDATAB; int sectSizeDATA;
-void *sectOBJCB; int sectSizeOBJC;
-void *sectLINKB; int sectSizeLINK;
-
-/* Kernel boot information */
-KERNBOOTSTRUCT kernBootStructData;
-KERNBOOTSTRUCT *kernBootStruct;
-#endif
-
-vm_offset_t kern_args_start = 0; /* kernel arguments */
-vm_size_t kern_args_size = 0; /* size of kernel arguments */
-
-#ifdef __MACHO__
-
-unsigned long
-i386_preinit()
-{
- int i;
- struct segment_command *sgp;
- struct section *sp;
-
- sgp = (struct segment_command *) getsegbyname("__DATA");
- if (sgp) {
- sp = (struct section *) firstsect(sgp);
- if (sp) {
- do {
- if (sp->flags & S_ZEROFILL)
- bzero((char *) sp->addr, sp->size);
- } while (sp = (struct section *)nextsect(sgp, sp));
- }
- }
-
+void enable_bluebox(void);
+void disable_bluebox(void);
- bcopy((char *) KERNSTRUCT_ADDR, (char *) &kernBootStructData,
- sizeof(kernBootStructData));
-
- kernBootStruct = &kernBootStructData;
-
- end = getlastaddr();
-
- for (i = 0; i < kernBootStruct->numBootDrivers; i++)
- end += kernBootStruct->driverConfig[i].size;
-
- end = round_page(end);
+static void machine_conf(void);
+#include <i386/cpuid.h>
- return end;
-}
-#endif
+extern int default_preemption_rate;
+extern int max_unsafe_quanta;
+extern int max_poll_quanta;
+extern int idlehalt;
+extern unsigned int panic_is_inited;
-/*
- * Cpu initialization. Running virtual, but without MACH VM
- * set up. First C routine called.
- */
void
-machine_startup(void)
+machine_startup()
{
+ int boot_arg;
-#ifdef __MACHO__
-
-
- /* Now copy over various bits.. */
- cnvmem = kernBootStruct->convmem;
- extmem = kernBootStruct->extmem;
- kern_args_start = (vm_offset_t) kernBootStruct->bootString;
- kern_args_size = strlen(kernBootStruct->bootString);
- boottype = kernBootStruct->rootdev;
-
- /* Now retrieve addresses for end, edata, and etext
- * from MACH-O headers.
- */
-
- sectTEXTB = (void *) getsegdatafromheader(
- &_mh_execute_header, "__TEXT", §SizeTEXT);
- sectDATAB = (void *) getsegdatafromheader(
- &_mh_execute_header, "__DATA", §SizeDATA);
- sectOBJCB = (void *) getsegdatafromheader(
- &_mh_execute_header, "__OBJC", §SizeOBJC);
- sectLINKB = (void *) getsegdatafromheader(
- &_mh_execute_header, "__LINKEDIT", §SizeLINK);
-
- etext = (vm_offset_t) sectTEXTB + sectSizeTEXT;
- edata = (vm_offset_t) sectDATAB + sectSizeDATA;
+#if 0
+ if( PE_get_hotkey( kPEControlKey ))
+ halt_in_debugger = halt_in_debugger ? 0 : 1;
#endif
- /*
- * Parse startup arguments
- */
- parse_arguments();
-
- disableDebugOuput = FALSE;
- debug_mode = TRUE;
-
- printf_init(); /* Init this in case we need debugger */
- panic_init(); /* Init this in case we need debugger */
-
- PE_init_platform(FALSE, kernBootStruct);
- PE_init_kprintf(FALSE);
- PE_init_printf(FALSE);
-
- /*
- * Do basic VM initialization
- */
- i386_init();
+ if (PE_parse_boot_arg("debug", &boot_arg)) {
+ if (boot_arg & DB_HALT) halt_in_debugger=1;
+ if (boot_arg & DB_PRT) disableDebugOuput=FALSE;
+ if (boot_arg & DB_SLOG) systemLogDiags=TRUE;
+ if (boot_arg & DB_NMI) panicDebugging=TRUE;
+ if (boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE;
+ }
- PE_init_platform(TRUE, kernBootStruct);
- PE_init_kprintf(TRUE);
- PE_init_printf(TRUE);
+#if NOTYET
+ hw_lock_init(&debugger_lock); /* initialize debugger lock */
+ hw_lock_init(&pbtlock); /* initialize print backtrace lock */
+#endif
#if MACH_KDB
-
/*
- * Initialize the kernel debugger.
+ * Initialize KDB
*/
+#if DB_MACHINE_COMMANDS
+ db_machine_commands_install(ppc_db_commands);
+#endif /* DB_MACHINE_COMMANDS */
ddb_init();
+ if (boot_arg & DB_KDB)
+ current_debugger = KDB_CUR_DB;
+
/*
* Cause a breakpoint trap to the debugger before proceeding
* any further if the proper option bit was specified in
* the boot flags.
- *
- * XXX use -a switch to invoke kdb, since there's no
- * boot-program switch to turn on RB_HALT!
*/
+ if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
+ Debugger("inline call to debugger(machine_startup)");
+ halt_in_debugger = 0;
+ active_debugger =1;
+ }
+#endif /* MACH_KDB */
- if (halt_in_debugger) {
- printf("inline call to debugger(machine_startup)\n");
- Debugger("inline call");
+ if (PE_parse_boot_arg("preempt", &boot_arg)) {
+ default_preemption_rate = boot_arg;
}
-#endif /* MACH_KDB */
- TR_INIT();
-
- printf(version);
-
- machine_slot[0].is_cpu = TRUE;
- machine_slot[0].running = TRUE;
-#ifdef MACH_BSD
- /* FIXME */
- machine_slot[0].cpu_type = CPU_TYPE_I386;
- machine_slot[0].cpu_subtype = CPU_SUBTYPE_PENTPRO;
-#else
- machine_slot[0].cpu_type = cpuid_cputype(0);
- machine_slot[0].cpu_subtype = CPU_SUBTYPE_AT386;
+ if (PE_parse_boot_arg("unsafe", &boot_arg)) {
+ max_unsafe_quanta = boot_arg;
+ }
+ if (PE_parse_boot_arg("poll", &boot_arg)) {
+ max_poll_quanta = boot_arg;
+ }
+ if (PE_parse_boot_arg("yield", &boot_arg)) {
+ sched_poll_yield_shift = boot_arg;
+ }
+ if (PE_parse_boot_arg("idlehalt", &boot_arg)) {
+ idlehalt = boot_arg;
+ }
+
+ machine_conf();
+
+#if NOTYET
+ ml_thrm_init(); /* Start thermal monitoring on this processor */
#endif
/*
* Start the system.
*/
-#if NCPUS > 1
- mp_desc_init(0);
-#endif /* NCPUS */
-
- setup_main();
+ kernel_bootstrap();
+ /*NOTREACHED*/
}
-vm_offset_t env_start = 0; /* environment */
-vm_size_t env_size = 0; /* size of environment */
-
-/*
- * Parse command line arguments.
- */
-void
-parse_arguments(void)
-{
- char *p = (char *) kern_args_start;
- char *endp = (char *) kern_args_start + kern_args_size - 1;
- char ch;
-
- if (kern_args_start == 0)
- return;
- while (p < endp) {
- if (*p++ != '-') {
- while (*p++ != '\0')
- ;
- continue;
- }
- while (ch = *p++) {
- switch (ch) {
- case 'h':
- halt_in_debugger = 1;
- break;
- case 'm': /* -m??: memory size Mbytes*/
- mem_size = atoi_term(p, &p)*1024*1024;
- break;
- case 'k': /* -k??: memory size Kbytes */
- mem_size = atoi_term(p, &p)*1024;
- break;
- default:
-#if NCPUS > 1 && AT386
- if (ch > '0' && ch <= '9')
- wncpu = ch - '0';
-#endif /* NCPUS > 1 && AT386 */
- break;
- }
- }
- }
-}
-
-const char *
-getenv(const char *name)
+static void
+machine_conf(void)
{
- int len = strlen(name);
- const char *p = (const char *)env_start;
- const char *endp = p + env_size;
-
- while (p < endp) {
- if (len >= endp - p)
- break;
- if (strncmp(name, p, len) == 0 && *(p + len) == '=')
- return p + len + 1;
- while (*p++)
- ;
- }
- return NULL;
+ machine_info.memory_size = mem_size;
}
-extern void
-calibrate_delay(void);
-
/*
* Find devices. The system is alive.
*/
void
machine_init(void)
{
- int unit;
- const char *p;
- int n;
-
- /*
- * Adjust delay count before entering drivers
- */
-
- calibrate_delay();
-
/*
* Display CPU identification
*/
cpuid_cpu_display("CPU identification", 0);
- cpuid_cache_display("CPU configuration", 0);
+ cpuid_feature_display("CPU features", 0);
+
-#if MP_V1_1
- mp_v1_1_init();
-#endif /* MP_V1_1 */
+ smp_init();
/*
* Set up to use floating point.
*/
init_fpu();
-#if 0
-#if NPCI > 0
- dma_zones_init();
-#endif /* NPCI > 0 */
-#endif
-
/*
* Configure clock devices.
*/
clock_config();
+
+ /*
+ * Initialize MTRR from boot processor.
+ */
+ mtrr_init();
+
+ /*
+ * Set up PAT for boot processor.
+ */
+ pat_init();
+
+ /*
+ * Free lowmem pages
+ */
+ x86_lowmem_free();
}
/*
* Halt the system or reboot.
*/
void
-halt_all_cpus(
- boolean_t reboot)
+halt_all_cpus(boolean_t reboot)
{
if (reboot) {
- /*
- * Tell the BIOS not to clear and test memory.
- */
- if (! reset_mem_on_reboot)
- *(unsigned short *)phystokv(0x472) = 0x1234;
-
- kdreboot();
- }
- else {
- rebootflag = 1;
- printf("In tight loop: hit ctl-alt-del to reboot\n");
- (void) spllo();
- }
- for (;;)
- continue;
-}
-
-/*
- * Basic VM initialization.
- */
-
-void
-i386_init(void)
-{
- int i,j; /* Standard index vars. */
- vm_size_t bios_hole_size;
-
-#ifndef __MACHO__
- /*
- * Zero the BSS.
- */
-
- bzero((char *)&edata,(unsigned)(&end - &edata));
-#endif
-
- boot_string = &boot_string_store[0];
-
- /*
- * Initialize the pic prior to any possible call to an spl.
- */
-
- set_cpu_model();
- vm_set_page_size();
-
- /*
- * Initialize the Event Trace Analysis Package
- * Static Phase: 1 of 2
- */
- etap_init_phase1();
-
- /*
- * Compute the memory size.
- */
-
-#if 1
- /* FIXME
- * fdisk needs to change to use a sysctl instead of
- * opening /dev/kmem and reading out the kernboot structure
- */
-
- first_addr = (char *)(KERNSTRUCT_ADDR) + sizeof(KERNBOOTSTRUCT);
-#else
-#if NCPUS > 1
- first_addr = 0x1000;
-#else
- /* First two pages are used to boot the other cpus. */
- /* TODO - reclaim pages after all cpus have booted */
-
- first_addr = 0x3000;
-#endif
-#endif
-
- /* BIOS leaves data in low memory */
- last_addr = 1024*1024 + extmem*1024;
- /* extended memory starts at 1MB */
-
- bios_hole_size = 1024*1024 - trunc_page((vm_offset_t)(1024 * cnvmem));
-
- /*
- * Initialize for pmap_free_pages and pmap_next_page.
- * These guys should be page-aligned.
- */
-
- hole_start = trunc_page((vm_offset_t)(1024 * cnvmem));
- hole_end = round_page((vm_offset_t)first_avail);
-
- /*
- * compute mem_size
- */
-
- if (mem_size != 0) {
- if (mem_size < (last_addr) - bios_hole_size)
- last_addr = mem_size + bios_hole_size;
- }
-
- first_addr = round_page(first_addr);
- last_addr = trunc_page(last_addr);
- mem_size = last_addr - bios_hole_size;
-
- avail_start = first_addr;
- avail_end = last_addr;
- avail_next = avail_start;
-
- /*
- * Initialize kernel physical map, mapping the
- * region from loadpt to avail_start.
- * Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
- */
-
-
-#if NCPUS > 1 && AT386
- /*
- * Must Allocate interrupt stacks before kdb is called and also
- * before vm is initialized. Must find out number of cpus first.
- */
- /*
- * Get number of cpus to boot, passed as an optional argument
- * boot: mach [-sah#] # from 0 to 9 is the number of cpus to boot
- */
- if (wncpu == -1) {
/*
- * "-1" check above is to allow for old boot loader to pass
- * wncpu through boothowto. New boot loader uses environment.
+ * Tell the BIOS not to clear and test memory.
*/
- const char *cpus;
- if ((cpus = getenv("cpus")) != NULL) {
- /* only a single digit for now */
- if ((*cpus > '0') && (*cpus <= '9'))
- wncpu = *cpus - '0';
- } else
- wncpu = NCPUS;
- }
- mp_probe_cpus();
- interrupt_stack_alloc();
-
-#endif /* NCPUS > 1 && AT386 */
-
- pmap_bootstrap(0);
-
- avail_remaining = atop((avail_end - avail_start) -
- (hole_end - hole_start));
-}
-
-unsigned int
-pmap_free_pages(void)
-{
- return avail_remaining;
-}
-
-boolean_t
-pmap_next_page(
- vm_offset_t *addrp)
-{
- if (avail_next == avail_end)
- return FALSE;
-
- /* skip the hole */
-
- if (avail_next == hole_start)
- avail_next = hole_end;
-
- *addrp = avail_next;
- avail_next += PAGE_SIZE;
- avail_remaining--;
-
- return TRUE;
-}
+#if 0 /* XXX fixme */
+ if (!reset_mem_on_reboot)
+ *(unsigned short *)phystokv(0x472) = 0x1234;
+#endif
-boolean_t
-pmap_valid_page(
- vm_offset_t x)
-{
- return ((avail_start <= x) && (x < avail_end));
+ printf("MACH Reboot\n");
+ PEHaltRestart( kPERestartCPU );
+ } else {
+ printf("CPU halted\n");
+ PEHaltRestart( kPEHaltCPU );
+ }
+ while(1);
}
/*XXX*/
void fc_get(mach_timespec_t *ts);
#include <kern/clock.h>
-#include <i386/rtclock_entries.h>
extern kern_return_t sysclk_gettime(
mach_timespec_t *cur_time);
void fc_get(mach_timespec_t *ts) {
Debugger(
const char *message)
{
- printf("Debugger called: <%s>\n", message);
-
- __asm__("int3");
-}
-void
-display_syscall(int syscall)
-{
- printf("System call happened %d\n", syscall);
-}
-
-#if XPR_DEBUG && (NCPUS == 1 || MP_V1_1)
+ if (!panic_is_inited) {
+ postcode(PANIC_HLT);
+ asm("hlt");
+ }
-extern kern_return_t sysclk_gettime_interrupts_disabled(
- mach_timespec_t *cur_time);
+ printf("Debugger called: <%s>\n", message);
+ kprintf("Debugger called: <%s>\n", message);
-int xpr_time(void)
-{
- mach_timespec_t time;
+ draw_panic_dialog();
- sysclk_gettime_interrupts_disabled(&time);
- return(time.tv_sec*1000000 + time.tv_nsec/1000);
+ __asm__("int3");
}
-#endif /* XPR_DEBUG && (NCPUS == 1 || MP_V1_1) */
-enable_bluebox()
+void
+enable_bluebox(void)
{
}
-disable_bluebox()
+void
+disable_bluebox(void)
{
}
char *
-machine_boot_info(char *buf, vm_size_t size)
+machine_boot_info(char *buf, __unused vm_size_t size)
{
*buf ='\0';
return buf;