X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..6601e61aa18bf4f09af135ff61fc7f4771d23b06:/osfmk/i386/AT386/model_dep.c diff --git a/osfmk/i386/AT386/model_dep.c b/osfmk/i386/AT386/model_dep.c index 1e43a8458..588e59611 100644 --- a/osfmk/i386/AT386/model_dep.c +++ b/osfmk/i386/AT386/model_dep.c @@ -60,12 +60,9 @@ * Basic initialization for I386 - ISA bus machines. */ -#include #include -#include #include #include -#include #include @@ -74,348 +71,165 @@ #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 +#include +#include +#include #if MACH_KDB #include #endif /* MACH_KDB */ -#include -#ifdef __MACHO__ -#include -#include -#include -#endif -#if NCPUS > 1 #include -#endif /* NCPUS */ - -#if MP_V1_1 -#include -#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 +#include -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 -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 - 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(); } /* @@ -433,189 +247,29 @@ int reset_mem_on_reboot = 1; * 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 -#include extern kern_return_t sysclk_gettime( mach_timespec_t *cur_time); void fc_get(mach_timespec_t *ts) { @@ -626,40 +280,31 @@ void 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;