Annotation of XNU/osfmk/kern/startup.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: 
                     53: /*
                     54:  *     Mach kernel startup.
                     55:  */
                     56: 
                     57: #include <debug.h>
                     58: #include <xpr_debug.h>
                     59: #include <mach_kdp.h>
                     60: #include <cpus.h>
                     61: #include <mach_host.h>
                     62: #include <norma_vm.h>
                     63: #include <etap.h>
                     64: 
                     65: #include <mach/boolean.h>
                     66: #include <mach/machine.h>
                     67: #include <mach/task_special_ports.h>
                     68: #include <mach/vm_param.h>
                     69: #include <ipc/ipc_init.h>
                     70: #include <kern/assert.h>
                     71: #include <kern/misc_protos.h>
                     72: #include <kern/clock.h>
                     73: #include <kern/cpu_number.h>
                     74: #include <kern/etap_macros.h>
                     75: #include <kern/machine.h>
                     76: #include <kern/processor.h>
                     77: #include <kern/sched_prim.h>
                     78: #include <kern/sf.h>
                     79: #include <kern/startup.h>
                     80: #include <kern/task.h>
                     81: #include <kern/thread.h>
                     82: #include <kern/timer.h>
                     83: #include <kern/xpr.h>
                     84: #include <kern/zalloc.h>
                     85: #include <vm/vm_kern.h>
                     86: #include <vm/vm_init.h>
                     87: #include <vm/vm_map.h>
                     88: #include <vm/vm_object.h>
                     89: #include <vm/vm_page.h>
                     90: #include <vm/vm_pageout.h>
                     91: #include <machine/pmap.h>
                     92: #include <sys/version.h>
                     93: 
                     94: vm_offset_t    shared_file_text_region;
                     95: vm_offset_t    shared_file_data_region;
                     96: 
                     97: #ifdef __ppc__
                     98: #include <ppc/Firmware.h>
                     99: #include <ppc/mappings.h>
                    100: #include <ppc/miscserv.h>
                    101: #endif
                    102: 
                    103: /* Externs XXX */
                    104: extern void    rtclock_reset(void);
                    105: 
                    106: /* Forwards */
                    107: void           cpu_launch_first_thread(
                    108:                        thread_t                        thread);
                    109: void           start_kernel_threads(void);
                    110: void        swapin_thread();
                    111: 
                    112: ipc_port_t     shared_text_region_handle;
                    113: ipc_port_t     shared_data_region_handle;
                    114: vm_offset_t    shared_file_mapping_array;
                    115: 
                    116: /*
                    117:  *     Running in virtual memory, on the interrupt stack.
                    118:  *     Does not return.  Dispatches initial thread.
                    119:  *
                    120:  *     Assumes that master_cpu is set.
                    121:  */
                    122: void
                    123: setup_main(void)
                    124: {
                    125:        mk_sp_attribute_struct_t        startup_thread_attributes;
                    126:        thread_t                                        startup_thread;
                    127: 
                    128:        printf_init();
                    129:        panic_init();
                    130: 
                    131:        sched_init();
                    132:        vm_mem_bootstrap();
                    133:        ipc_bootstrap();
                    134:        vm_mem_init();
                    135:        ipc_init();
                    136:        pager_mux_hash_init();
                    137: 
                    138:        /*
                    139:         * As soon as the virtual memory system is up, we record
                    140:         * that this CPU is using the kernel pmap.
                    141:         */
                    142:        PMAP_ACTIVATE_KERNEL(master_cpu);
                    143: 
                    144: #ifdef __ppc__
                    145:        mapping_free_prime();                                           /* Load up with temporary mapping blocks */
                    146: #endif
                    147: 
                    148:        machine_init();
                    149:        kmod_init();
                    150:        clock_init();
                    151: 
                    152:        init_timers();
                    153: 
                    154:        machine_info.max_cpus = NCPUS;
                    155:        machine_info.memory_size = mem_size;
                    156:        machine_info.avail_cpus = 0;
                    157:        machine_info.major_version = KERNEL_MAJOR_VERSION;
                    158:        machine_info.minor_version = KERNEL_MINOR_VERSION;
                    159: 
                    160:        /*
                    161:         *      Initialize the IPC, task, and thread subsystems.
                    162:         */
                    163:     ledger_init();
                    164:        swapper_init();
                    165:        task_init();
                    166:        act_init();
                    167:        thread_init();
                    168:        subsystem_init();
                    169: #if    MACH_HOST
                    170:        pset_sys_init();
                    171: #endif /* MACH_HOST */
                    172: 
                    173:        /*
                    174:         *      Initialize the Event Trace Analysis Package.
                    175:         *      Dynamic Phase: 2 of 2
                    176:         */
                    177:        etap_init_phase2();
                    178:        
                    179:        /*
                    180:         *      Create a kernel thread to start the other kernel
                    181:         *      threads.  Thread_resume (from kernel_thread) calls
                    182:         *      thread_setrun, which may look at current thread;
                    183:         *      we must avoid this, since there is no current thread.
                    184:         */
                    185:        startup_thread_attributes.policy_id = POLICY_FIFO;
                    186:        startup_thread_attributes.priority =
                    187:                        startup_thread_attributes.max_priority = BASEPRI_KERNEL;
                    188:        startup_thread_attributes.sched_data =
                    189:                        startup_thread_attributes.unconsumed_quantum = 0;
                    190: 
                    191:        /*
                    192:         * Create the thread, and point it at the routine.
                    193:         */
                    194:        startup_thread = kernel_thread_with_attributes(kernel_task,
                    195:                                                   (sp_attributes_t)&startup_thread_attributes,
                    196:                                                                                           start_kernel_threads, FALSE);
                    197:                                                        
                    198:        /*
                    199:         * Pretend it is already running, and resume it.
                    200:         * Since it looks as if it is running, thread_resume
                    201:         * will not try to put it on the run queues.
                    202:         *
                    203:         * We can do all of this without locking, because nothing
                    204:         * else is running yet.
                    205:         */
                    206:        startup_thread->state |= TH_RUN;
                    207:        (void) thread_resume(startup_thread->top_act);
                    208:        /*
                    209:         * Start the thread.
                    210:         */
                    211:        cpu_launch_first_thread(startup_thread);
                    212:        /*NOTREACHED*/
                    213:        panic("cpu_launch_first_thread returns!");
                    214: }
                    215: 
                    216: /*
                    217:  * Now running in a thread.  Create the rest of the kernel threads
                    218:  * and the bootstrap task.
                    219:  */
                    220: void
                    221: start_kernel_threads(void)
                    222: {
                    223:        mk_sp_attribute_struct_t        idle_thread_attributes;
                    224:        register int                            i;
                    225:        long                    shared_text_region_size;
                    226:        long                    shared_data_region_size;
                    227: 
                    228:        thread_bind(current_thread(), cpu_to_processor(cpu_number()));
                    229:        /*
                    230:         *      Create the idle threads and the other
                    231:         *      service threads.
                    232:         */
                    233:        idle_thread_attributes.policy_id = POLICY_FIFO;
                    234:        idle_thread_attributes.priority =
                    235:                        idle_thread_attributes.max_priority = BASEPRI_KERNEL;
                    236:        idle_thread_attributes.sched_data =
                    237:                        idle_thread_attributes.unconsumed_quantum = 0;
                    238: 
                    239:        for (i = 0; i < NCPUS; i++) {
                    240:          if (1 /*machine_slot[i].is_cpu*/) {
                    241:                        processor_t             processor = cpu_to_processor(i);
                    242:                        thread_t                thread;
                    243:                        sched_policy_t  *policy;
                    244:                        sf_return_t             sfr;
                    245:                        spl_t                   s;
                    246: 
                    247:                        thread = kernel_thread_with_attributes(kernel_task,
                    248:                                                        (sp_attributes_t)&idle_thread_attributes,
                    249:                                                                                                                idle_thread, FALSE);
                    250:                        s = splsched();
                    251:                        thread_lock(thread);
                    252:                        thread_bind_locked(thread, processor);
                    253:                        processor->idle_thread = thread;
                    254:                        /*(void) thread_resume(thread->top_act);*/
                    255:                        thread->state |= TH_RUN;
                    256:                        
                    257:                        /* get pointer to scheduling policy "object" */
                    258:                        policy = &sched_policy[thread->policy];
                    259:        
                    260:                        sfr = policy->sp_ops.sp_thread_unblock(policy, thread);
                    261:                        assert(sfr == SF_SUCCESS);
                    262:                        thread_unlock(thread);
                    263:                        splx(s);
                    264:            }
                    265:        }
                    266: 
                    267:        /*
                    268:         * Initialize the thread callout mechanism.
                    269:         */
                    270:        thread_call_initialize();
                    271: 
                    272:        /*
                    273:         * Invoke some black magic.
                    274:         */
                    275: #if __ppc__
                    276:        mapping_adjust();
                    277: #endif
                    278: 
                    279:        /*
                    280:         *      Invoke the thread reaper mechanism.
                    281:         */
                    282:        thread_reaper();
                    283: 
                    284:        /*
                    285:         *      Start the stack swapin thread
                    286:         */
                    287:        kernel_thread(kernel_task,swapin_thread);
                    288: 
                    289:        /*
                    290:         *      Invoke the periodic scheduler mechanism.
                    291:         */
                    292:        recompute_priorities();
                    293: 
                    294:        /*
                    295:         *      Create the clock service.
                    296:         */
                    297:        clock_service_create();
                    298: 
                    299:        /*
                    300:         *      Create the device service.
                    301:         */
                    302:        device_service_create();
                    303: 
                    304:        shared_text_region_size = 0x10000000;
                    305:        shared_data_region_size = 0x10000000;
                    306:        shared_file_init(&shared_text_region_handle,
                    307:                        shared_text_region_size, &shared_data_region_handle,
                    308:                        shared_data_region_size, &shared_file_mapping_array);
                    309: 
                    310: #ifdef IOKIT
                    311:        {
                    312:                PE_init_iokit();
                    313:        }
                    314: #endif
                    315: 
                    316:        /*
                    317:         *      Start the user bootstrap.
                    318:         */
                    319:        
                    320:        (void) spllo();                                         /* Allow interruptions */
                    321:        
                    322: #ifdef MACH_BSD
                    323:        { 
                    324:                extern void bsd_init(void);
                    325:                bsd_init();
                    326:        }
                    327: #endif
                    328: 
                    329:        /*
                    330:         *      Invoke the processor action mechanism.
                    331:         */
                    332:        processor_action();
                    333: 
                    334:        thread_bind(current_thread(), PROCESSOR_NULL);
                    335: 
                    336:        /*
                    337:         *      Become the pageout daemon.
                    338:         */
                    339: 
                    340:        vm_pageout();
                    341:        /*NOTREACHED*/
                    342: }
                    343: 
                    344: void
                    345: slave_main(void)
                    346: {
                    347:        thread_t startup_thread;
                    348: 
                    349:        startup_thread = cpu_to_processor(cpu_number())->next_thread;
                    350:        rem_runq(startup_thread);
                    351:        cpu_launch_first_thread(startup_thread);
                    352:        /*NOTREACHED*/
                    353:        panic("cpu_launch_first_thread returns!");
                    354: }
                    355: 
                    356: /*
                    357:  * Now running in a thread context
                    358:  */
                    359: void
                    360: start_cpu_thread(void)
                    361: {
                    362:        processor_t     processor;
                    363: 
                    364:        processor = cpu_to_processor(cpu_number());
                    365: 
                    366:        slave_machine_init();
                    367: 
                    368:        if (processor->processor_self == IP_NULL) {
                    369:                ipc_processor_init(processor);
                    370:                ipc_processor_enable(processor);
                    371:        }
                    372: 
                    373:        printf("start_cpu_thread done on cpu %x\n", cpu_number());
                    374: 
                    375:        /* TODO: Mark this processor ready to dispatch threads */
                    376: 
                    377:        thread_terminate_self();
                    378: }
                    379: 
                    380: /*
                    381:  *     Start up the first thread on a CPU.
                    382:  *     First thread is specified for the master CPU.
                    383:  */
                    384: void
                    385: cpu_launch_first_thread(
                    386:        thread_t                thread)
                    387: {
                    388:        register int    mycpu = cpu_number();
                    389: 
                    390:        cpu_up(mycpu);
                    391:        start_timer(&kernel_timer[mycpu]);
                    392: 
                    393:        if (thread == THREAD_NULL) {
                    394:            thread = cpu_to_processor(mycpu)->idle_thread;
                    395:                if (thread == THREAD_NULL || !rem_runq(thread))
                    396:                    panic("cpu_launch_first_thread");
                    397:        }
                    398: 
                    399:        rtclock_reset();                /* start realtime clock ticking */
                    400:        PMAP_ACTIVATE_KERNEL(mycpu);
                    401: 
                    402:        thread_machine_set_current(thread);
                    403:        thread_lock(thread);
                    404:        thread->state &= ~TH_UNINT;
                    405:        thread_unlock(thread);
                    406:        timer_switch(&thread->system_timer);
                    407: 
                    408:        PMAP_ACTIVATE_USER(thread->top_act, mycpu);
                    409: 
                    410:        assert(mycpu == cpu_number());
                    411: 
                    412:        /* The following is necessary to keep things balanced */
                    413:        disable_preemption();
                    414:        
                    415:        load_context(thread);
                    416:        /*NOTREACHED*/
                    417: }

unix.superglobalmegacorp.com

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