/* * load_context: * * Start the first thread on a processor. */ static void load_context( thread_t thread) { processor_t processor = current_processor(); #define load_context_kprintf(x...) /* kprintf("load_context: " x) */ load_context_kprintf("calling machine_set_current_thread\n"); machine_set_current_thread(thread); load_context_kprintf("calling processor_up\n"); processor_up(processor); PMAP_ACTIVATE_KERNEL(processor->cpu_id); /* * Acquire a stack if none attached. The panic * should never occur since the thread is expected * to have reserved stack. */ load_context_kprintf("thread %p, stack %lx, stackptr %lx\n", thread, thread->kernel_stack, thread->machine.kstackptr); if (!thread->kernel_stack) { load_context_kprintf("calling stack_alloc_try\n"); if (!stack_alloc_try(thread)) panic("load_context"); } /* * The idle processor threads are not counted as * running for load calculations. */ if (!(thread->state & TH_IDLE)) sched_run_incr(); processor->active_thread = thread; processor->current_pri = thread->sched_pri; processor->current_thmode = thread->sched_mode; processor->deadline = UINT64_MAX; thread->last_processor = processor; processor->last_dispatch = mach_absolute_time(); timer_start(&thread->system_timer, processor->last_dispatch); PROCESSOR_DATA(processor, thread_timer) = PROCESSOR_DATA(processor, kernel_timer) = &thread->system_timer; timer_start(&PROCESSOR_DATA(processor, system_state), processor->last_dispatch); PROCESSOR_DATA(processor, current_state) = &PROCESSOR_DATA(processor, system_state); PMAP_ACTIVATE_USER(thread, processor->cpu_id); load_context_kprintf("calling machine_load_context\n"); machine_load_context(thread); /*NOTREACHED*/ }
/* * Start up the first thread on a CPU. * First thread is specified for the master CPU. */ void cpu_launch_first_thread( register thread_t th) { register int mycpu; mycpu = cpu_number(); #if MACH_ASSERT if (watchacts & WA_BOOT) printf("cpu_launch_first_thread(%x) cpu=%d\n", th, mycpu); #endif /* MACH_ASSERT */ cpu_up(mycpu); start_timer(&kernel_timer[mycpu]); /* * Block all interrupts for choose_thread. */ (void) splhigh(); if (th == THREAD_NULL) { th = cpu_to_processor(mycpu)->idle_thread; if (th == THREAD_NULL || !rem_runq(th)) panic("cpu_launch_first_thread"); } rtclock_reset(); /* start realtime clock ticking */ PMAP_ACTIVATE_KERNEL(mycpu); thread_machine_set_current(th); thread_lock(th); th->state &= ~TH_UNINT; thread_unlock(th); timer_switch(&th->system_timer); PMAP_ACTIVATE_USER(th->top_act, mycpu); assert(mycpu == cpu_number()); /* The following is necessary to keep things balanced */ disable_preemption(); load_context(th); /*NOTREACHED*/ }