Annotation of Gnu-Mach/kern/startup.c, revision 1.1.1.7

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.2   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Mach kernel startup.
                     28:  */
                     29: 
1.1.1.4   root       30: #include <string.h>
1.1       root       31: 
                     32: #include <mach/boolean.h>
                     33: #include <mach/machine.h>
                     34: #include <mach/task_special_ports.h>
                     35: #include <mach/vm_param.h>
                     36: #include <ipc/ipc_init.h>
                     37: #include <kern/cpu_number.h>
1.1.1.4   root       38: #include <kern/debug.h>
1.1.1.7 ! root       39: #include <kern/gsync.h>
1.1.1.4   root       40: #include <kern/machine.h>
                     41: #include <kern/mach_factor.h>
                     42: #include <kern/mach_clock.h>
1.1       root       43: #include <kern/processor.h>
1.1.1.6   root       44: #include <kern/rdxtree.h>
1.1       root       45: #include <kern/sched_prim.h>
                     46: #include <kern/task.h>
                     47: #include <kern/thread.h>
                     48: #include <kern/thread_swap.h>
                     49: #include <kern/timer.h>
1.1.1.4   root       50: #include <kern/xpr.h>
1.1.1.5   root       51: #include <kern/bootstrap.h>
1.1.1.4   root       52: #include <kern/time_stamp.h>
1.1.1.5   root       53: #include <kern/startup.h>
1.1       root       54: #include <vm/vm_kern.h>
                     55: #include <vm/vm_map.h>
                     56: #include <vm/vm_object.h>
                     57: #include <vm/vm_page.h>
1.1.1.5   root       58: #include <vm/vm_init.h>
                     59: #include <vm/vm_pageout.h>
1.1       root       60: #include <machine/machspl.h>
1.1.1.4   root       61: #include <machine/pcb.h>
1.1       root       62: #include <machine/pmap.h>
1.1.1.4   root       63: #include <machine/model_dep.h>
1.1       root       64: #include <mach/version.h>
1.1.1.5   root       65: #include <device/device_init.h>
1.1       root       66: 
1.1.1.5   root       67: #if MACH_KDB
                     68: #include <device/cons.h>
                     69: #endif /* MACH_KDB */
1.1       root       70: 
1.1.1.4   root       71: #if ! MACH_KBD
1.1.1.5   root       72: boolean_t reboot_on_panic = TRUE;
1.1.1.4   root       73: #endif
                     74: 
1.1       root       75: #if    NCPUS > 1
1.1.1.5   root       76: #include <machine/mp_desc.h>
                     77: #include <kern/machine.h>
1.1.1.3   root       78: #endif /* NCPUS > 1 */
1.1       root       79: 
                     80: /* XX */
                     81: extern vm_offset_t phys_first_addr, phys_last_addr;
1.1.1.4   root       82: extern char *kernel_cmdline;
1.1       root       83: 
                     84: /*
                     85:  *     Running in virtual memory, on the interrupt stack.
                     86:  *     Does not return.  Dispatches initial thread.
                     87:  *
                     88:  *     Assumes that master_cpu is set.
                     89:  */
1.1.1.5   root       90: void setup_main(void)
1.1       root       91: {
                     92:        thread_t                startup_thread;
                     93: 
1.1.1.4   root       94: #if    MACH_KDB
                     95:        /*
                     96:         * Cause a breakpoint trap to the debugger before proceeding
                     97:         * any further if the proper option flag was specified
                     98:         * on the kernel's command line.
                     99:         * XXX check for surrounding spaces.
                    100:         */
                    101:        if (strstr(kernel_cmdline, "-d ")) {
                    102:            cninit();           /* need console for debugger */
                    103:            SoftDebugger("init");
                    104:        }
                    105: #else  /* MACH_KDB */
                    106:        if (strstr (kernel_cmdline, "-H ")) {
1.1.1.5   root      107:            reboot_on_panic = FALSE;
1.1.1.4   root      108:        }
                    109: #endif /* MACH_KDB */
                    110: 
1.1       root      111:        panic_init();
                    112: 
                    113:        sched_init();
                    114:        vm_mem_bootstrap();
1.1.1.6   root      115:        rdxtree_cache_init();
1.1       root      116:        ipc_bootstrap();
                    117:        vm_mem_init();
                    118:        ipc_init();
                    119: 
                    120:        /*
                    121:         * As soon as the virtual memory system is up, we record
                    122:         * that this CPU is using the kernel pmap.
                    123:         */
                    124:        PMAP_ACTIVATE_KERNEL(master_cpu);
                    125: 
                    126:        init_timers();
                    127:        init_timeout();
                    128: 
                    129: #if    XPR_DEBUG
                    130:        xprbootstrap();
1.1.1.3   root      131: #endif /* XPR_DEBUG */
1.1       root      132: 
                    133:        timestamp_init();
                    134: 
                    135:        machine_init();
                    136: 
1.1.1.4   root      137:        mapable_time_init();
                    138: 
1.1       root      139:        machine_info.max_cpus = NCPUS;
1.1.1.7 ! root      140:        machine_info.memory_size = vm_page_mem_size(); /* XXX phys_addr_t -> vm_size_t */
1.1       root      141:        machine_info.avail_cpus = 0;
                    142:        machine_info.major_version = KERNEL_MAJOR_VERSION;
                    143:        machine_info.minor_version = KERNEL_MINOR_VERSION;
                    144: 
                    145:        /*
                    146:         *      Initialize the IPC, task, and thread subsystems.
                    147:         */
                    148:        task_init();
                    149:        thread_init();
                    150:        swapper_init();
                    151: #if    MACH_HOST
                    152:        pset_sys_init();
1.1.1.3   root      153: #endif /* MACH_HOST */
1.1       root      154: 
                    155:        /*
                    156:         *      Kick off the time-out driven routines by calling
                    157:         *      them the first time.
                    158:         */
1.1.1.5   root      159:        recompute_priorities(NULL);
1.1       root      160:        compute_mach_factor();
1.1.1.2   root      161: 
1.1.1.7 ! root      162:        gsync_setup ();
        !           163: 
1.1       root      164:        /*
                    165:         *      Create a kernel thread to start the other kernel
                    166:         *      threads.  Thread_resume (from kernel_thread) calls
                    167:         *      thread_setrun, which may look at current thread;
                    168:         *      we must avoid this, since there is no current thread.
                    169:         */
                    170: 
                    171:        /*
                    172:         * Create the thread, and point it at the routine.
                    173:         */
                    174:        (void) thread_create(kernel_task, &startup_thread);
                    175:        thread_start(startup_thread, start_kernel_threads);
                    176: 
                    177:        /*
                    178:         * Give it a kernel stack.
                    179:         */
                    180:        thread_doswapin(startup_thread);
                    181: 
                    182:        /*
                    183:         * Pretend it is already running, and resume it.
                    184:         * Since it looks as if it is running, thread_resume
                    185:         * will not try to put it on the run queues.
                    186:         *
                    187:         * We can do all of this without locking, because nothing
                    188:         * else is running yet.
                    189:         */
                    190:        startup_thread->state |= TH_RUN;
                    191:        (void) thread_resume(startup_thread);
                    192: 
                    193:        /*
                    194:         * Start the thread.
                    195:         */
                    196:        cpu_launch_first_thread(startup_thread);
                    197:        /*NOTREACHED*/
                    198: }
                    199: 
                    200: /*
                    201:  * Now running in a thread.  Create the rest of the kernel threads
                    202:  * and the bootstrap task.
                    203:  */
1.1.1.5   root      204: void start_kernel_threads(void)
1.1       root      205: {
1.1.1.5   root      206:        int     i;
1.1       root      207: 
                    208:        /*
                    209:         *      Create the idle threads and the other
                    210:         *      service threads.
                    211:         */
                    212:        for (i = 0; i < NCPUS; i++) {
                    213:            if (machine_slot[i].is_cpu) {
                    214:                thread_t        th;
                    215: 
                    216:                (void) thread_create(kernel_task, &th);
                    217:                thread_bind(th, cpu_to_processor(i));
                    218:                thread_start(th, idle_thread);
                    219:                thread_doswapin(th);
                    220:                (void) thread_resume(th);
                    221:            }
                    222:        }
                    223: 
                    224:        (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
                    225:        (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
                    226:        (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
                    227: 
                    228: #if    NCPUS > 1
                    229:        /*
                    230:         *      Create the shutdown thread.
                    231:         */
                    232:        (void) kernel_thread(kernel_task, action_thread, (char *) 0);
                    233: 
                    234:        /*
                    235:         *      Allow other CPUs to run.
                    236:         */
                    237:        start_other_cpus();
1.1.1.3   root      238: #endif /* NCPUS > 1 */
1.1       root      239: 
                    240:        /*
                    241:         *      Create the device service.
                    242:         */
                    243:        device_service_create();
                    244: 
                    245:        /*
1.1.1.2   root      246:         *      Initialize kernel task's creation time.
                    247:         * When we created the kernel task in task_init, the mapped
                    248:         * time was not yet available.  Now, last thing before starting
                    249:         * the user bootstrap, record the current time as the kernel
                    250:         * task's creation time.
                    251:         */
                    252:        record_time_stamp (&kernel_task->creation_time);
                    253: 
1.1       root      254:        /*
                    255:         *      Start the user bootstrap.
                    256:         */
                    257:        bootstrap_create();
                    258: 
                    259: #if    XPR_DEBUG
                    260:        xprinit();              /* XXX */
1.1.1.3   root      261: #endif /* XPR_DEBUG */
1.1       root      262: 
                    263:        /*
                    264:         *      Become the pageout daemon.
                    265:         */
                    266:        (void) spl0();
                    267:        vm_pageout();
                    268:        /*NOTREACHED*/
                    269: }
                    270: 
                    271: #if    NCPUS > 1
1.1.1.5   root      272: void slave_main(void)
1.1       root      273: {
                    274:        cpu_launch_first_thread(THREAD_NULL);
                    275: }
1.1.1.3   root      276: #endif /* NCPUS > 1 */
1.1       root      277: 
                    278: /*
                    279:  *     Start up the first thread on a CPU.
                    280:  *     First thread is specified for the master CPU.
                    281:  */
1.1.1.5   root      282: void cpu_launch_first_thread(thread_t th)
1.1       root      283: {
1.1.1.5   root      284:        int     mycpu;
1.1       root      285: 
                    286:        mycpu = cpu_number();
                    287: 
                    288:        cpu_up(mycpu);
                    289: 
                    290:        start_timer(&kernel_timer[mycpu]);
                    291: 
                    292:        /*
                    293:         * Block all interrupts for choose_thread.
                    294:         */
                    295:        (void) splhigh();
                    296: 
                    297:        if (th == THREAD_NULL)
                    298:            th = choose_thread(cpu_to_processor(mycpu));
                    299:        if (th == THREAD_NULL)
                    300:            panic("cpu_launch_first_thread");
                    301: 
                    302:        PMAP_ACTIVATE_KERNEL(mycpu);
                    303: 
                    304:        active_threads[mycpu] = th;
                    305:        active_stacks[mycpu] = th->kernel_stack;
                    306:        thread_lock(th);
                    307:        th->state &= ~TH_UNINT;
                    308:        thread_unlock(th);
                    309:        timer_switch(&th->system_timer);
                    310: 
                    311:        PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
                    312: 
1.1.1.4   root      313:        startrtclock();         /* needs an active thread */
                    314: 
1.1       root      315:        load_context(th);
                    316:        /*NOTREACHED*/
                    317: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.