Annotation of XNU/osfmk/kern/startup.c, revision 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.