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

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      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.
                     11:  * 
                     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.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     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: 
                     30: 
                     31: #include <xpr_debug.h>
                     32: #include <cpus.h>
                     33: #include <mach_host.h>
                     34: #include <norma_ipc.h>
                     35: #include <norma_vm.h>
                     36: 
                     37: #include <mach/boolean.h>
                     38: #include <mach/machine.h>
                     39: #include <mach/task_special_ports.h>
                     40: #include <mach/vm_param.h>
                     41: #include <ipc/ipc_init.h>
                     42: #include <kern/cpu_number.h>
                     43: #include <kern/processor.h>
                     44: #include <kern/sched_prim.h>
                     45: #include <kern/task.h>
                     46: #include <kern/thread.h>
                     47: #include <kern/thread_swap.h>
                     48: #include <kern/time_out.h>
                     49: #include <kern/timer.h>
                     50: #include <kern/zalloc.h>
                     51: #include <vm/vm_kern.h>
                     52: #include <vm/vm_map.h>
                     53: #include <vm/vm_object.h>
                     54: #include <vm/vm_page.h>
                     55: #include <machine/machspl.h>
                     56: #include <machine/pmap.h>
                     57: #include <mach/version.h>
                     58: 
                     59: 
                     60: 
                     61: extern void    vm_mem_init();
                     62: extern void    vm_mem_bootstrap();
                     63: extern void    init_timeout();
                     64: extern void    machine_init();
                     65: 
                     66: extern void    idle_thread();
                     67: extern void    vm_pageout();
                     68: extern void    reaper_thread();
                     69: extern void    swapin_thread();
                     70: extern void    sched_thread();
                     71: 
                     72: extern void    bootstrap_create();
                     73: extern void    device_service_create();
                     74: 
                     75: void cpu_launch_first_thread();                /* forward */
                     76: void start_kernel_threads();   /* forward */
                     77: 
                     78: #if    NCPUS > 1
                     79: extern void    start_other_cpus();
                     80: extern void    action_thread();
                     81: #endif NCPUS > 1
                     82: 
                     83: /* XX */
                     84: extern vm_offset_t phys_first_addr, phys_last_addr;
                     85: 
                     86: /*
                     87:  *     Running in virtual memory, on the interrupt stack.
                     88:  *     Does not return.  Dispatches initial thread.
                     89:  *
                     90:  *     Assumes that master_cpu is set.
                     91:  */
                     92: void setup_main()
                     93: {
                     94:        thread_t                startup_thread;
                     95: 
                     96:        panic_init();
                     97:        printf_init();
                     98: 
                     99:        sched_init();
                    100:        vm_mem_bootstrap();
                    101:        ipc_bootstrap();
                    102:        vm_mem_init();
                    103:        ipc_init();
                    104: 
                    105:        /*
                    106:         * As soon as the virtual memory system is up, we record
                    107:         * that this CPU is using the kernel pmap.
                    108:         */
                    109:        PMAP_ACTIVATE_KERNEL(master_cpu);
                    110: 
                    111:        init_timers();
                    112:        init_timeout();
                    113: 
                    114: #if    XPR_DEBUG
                    115:        xprbootstrap();
                    116: #endif XPR_DEBUG
                    117: 
                    118:        timestamp_init();
                    119: 
                    120:        mapable_time_init();
                    121: 
                    122:        machine_init();
                    123: 
                    124:        machine_info.max_cpus = NCPUS;
                    125:        machine_info.memory_size = phys_last_addr - phys_first_addr; /* XXX mem_size */
                    126:        machine_info.avail_cpus = 0;
                    127:        machine_info.major_version = KERNEL_MAJOR_VERSION;
                    128:        machine_info.minor_version = KERNEL_MINOR_VERSION;
                    129: 
                    130:        /*
                    131:         *      Initialize the IPC, task, and thread subsystems.
                    132:         */
                    133:        task_init();
                    134:        thread_init();
                    135:        swapper_init();
                    136: #if    MACH_HOST
                    137:        pset_sys_init();
                    138: #endif MACH_HOST
                    139: 
                    140:        /*
                    141:         *      Kick off the time-out driven routines by calling
                    142:         *      them the first time.
                    143:         */
                    144:        recompute_priorities();
                    145:        compute_mach_factor();
                    146:        
                    147:        /*
                    148:         *      Create a kernel thread to start the other kernel
                    149:         *      threads.  Thread_resume (from kernel_thread) calls
                    150:         *      thread_setrun, which may look at current thread;
                    151:         *      we must avoid this, since there is no current thread.
                    152:         */
                    153: 
                    154:        /*
                    155:         * Create the thread, and point it at the routine.
                    156:         */
                    157:        (void) thread_create(kernel_task, &startup_thread);
                    158:        thread_start(startup_thread, start_kernel_threads);
                    159: 
                    160:        /*
                    161:         * Give it a kernel stack.
                    162:         */
                    163:        thread_doswapin(startup_thread);
                    164: 
                    165:        /*
                    166:         * Pretend it is already running, and resume it.
                    167:         * Since it looks as if it is running, thread_resume
                    168:         * will not try to put it on the run queues.
                    169:         *
                    170:         * We can do all of this without locking, because nothing
                    171:         * else is running yet.
                    172:         */
                    173:        startup_thread->state |= TH_RUN;
                    174:        (void) thread_resume(startup_thread);
                    175: 
                    176:        /*
                    177:         * Start the thread.
                    178:         */
                    179:        cpu_launch_first_thread(startup_thread);
                    180:        /*NOTREACHED*/
                    181: }
                    182: 
                    183: /*
                    184:  * Now running in a thread.  Create the rest of the kernel threads
                    185:  * and the bootstrap task.
                    186:  */
                    187: void start_kernel_threads()
                    188: {
                    189:        register int    i;
                    190: 
                    191:        /*
                    192:         *      Create the idle threads and the other
                    193:         *      service threads.
                    194:         */
                    195:        for (i = 0; i < NCPUS; i++) {
                    196:            if (machine_slot[i].is_cpu) {
                    197:                thread_t        th;
                    198: 
                    199:                (void) thread_create(kernel_task, &th);
                    200:                thread_bind(th, cpu_to_processor(i));
                    201:                thread_start(th, idle_thread);
                    202:                thread_doswapin(th);
                    203:                (void) thread_resume(th);
                    204:            }
                    205:        }
                    206: 
                    207:        (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
                    208:        (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
                    209:        (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
                    210: 
                    211: #if    NCPUS > 1
                    212:        /*
                    213:         *      Create the shutdown thread.
                    214:         */
                    215:        (void) kernel_thread(kernel_task, action_thread, (char *) 0);
                    216: 
                    217:        /*
                    218:         *      Allow other CPUs to run.
                    219:         */
                    220:        start_other_cpus();
                    221: #endif NCPUS > 1
                    222: 
                    223:        /*
                    224:         *      Create the device service.
                    225:         */
                    226:        device_service_create();
                    227: 
                    228:        /*
                    229:         *      Initialize NORMA ipc system.
                    230:         */
                    231: #if    NORMA_IPC
                    232:        norma_ipc_init();
                    233: #endif NORMA_IPC
                    234: 
                    235:        /*
                    236:         *      Initialize NORMA vm system.
                    237:         */
                    238: #if    NORMA_VM
                    239:        norma_vm_init();
                    240: #endif NORMA_VM
                    241: 
                    242:        /*
                    243:         *      Start the user bootstrap.
                    244:         */
                    245:        bootstrap_create();
                    246: 
                    247: #if    XPR_DEBUG
                    248:        xprinit();              /* XXX */
                    249: #endif XPR_DEBUG
                    250: 
                    251:        /*
                    252:         *      Become the pageout daemon.
                    253:         */
                    254:        (void) spl0();
                    255:        vm_pageout();
                    256:        /*NOTREACHED*/
                    257: }
                    258: 
                    259: #if    NCPUS > 1
                    260: void slave_main()
                    261: {
                    262:        cpu_launch_first_thread(THREAD_NULL);
                    263: }
                    264: #endif NCPUS > 1
                    265: 
                    266: /*
                    267:  *     Start up the first thread on a CPU.
                    268:  *     First thread is specified for the master CPU.
                    269:  */
                    270: void cpu_launch_first_thread(th)
                    271:        register thread_t       th;
                    272: {
                    273:        register int    mycpu;
                    274: 
                    275:        mycpu = cpu_number();
                    276: 
                    277:        cpu_up(mycpu);
                    278: 
                    279:        start_timer(&kernel_timer[mycpu]);
                    280: 
                    281:        /*
                    282:         * Block all interrupts for choose_thread.
                    283:         */
                    284:        (void) splhigh();
                    285: 
                    286:        if (th == THREAD_NULL)
                    287:            th = choose_thread(cpu_to_processor(mycpu));
                    288:        if (th == THREAD_NULL)
                    289:            panic("cpu_launch_first_thread");
                    290: 
                    291:        startrtclock();         /* needs an active thread */
                    292:        PMAP_ACTIVATE_KERNEL(mycpu);
                    293: 
                    294:        active_threads[mycpu] = th;
                    295:        active_stacks[mycpu] = th->kernel_stack;
                    296:        thread_lock(th);
                    297:        th->state &= ~TH_UNINT;
                    298:        thread_unlock(th);
                    299:        timer_switch(&th->system_timer);
                    300: 
                    301:        PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
                    302: 
                    303:        load_context(th);
                    304:        /*NOTREACHED*/
                    305: }

unix.superglobalmegacorp.com

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