/* * Now running in a thread. Create the rest of the kernel threads * and the bootstrap task. */ void start_kernel_threads() { register int i; /* * Create the idle threads and the other * service threads. */ for (i = 0; i < NCPUS; i++) { if (machine_slot[i].is_cpu) { thread_t th; (void) thread_create(kernel_task, &th); thread_bind(th, cpu_to_processor(i)); thread_start(th, idle_thread); thread_doswapin(th); (void) thread_resume(th); } } (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); (void) kernel_thread(kernel_task, sched_thread, (char *) 0); #if NCPUS > 1 /* * Create the shutdown thread. */ (void) kernel_thread(kernel_task, action_thread, (char *) 0); /* * Allow other CPUs to run. */ start_other_cpus(); #endif NCPUS > 1 /* * Create the device service. */ device_service_create(); /* * Initialize NORMA ipc system. */ #if NORMA_IPC norma_ipc_init(); #endif NORMA_IPC /* * Initialize NORMA vm system. */ #if NORMA_VM norma_vm_init(); #endif NORMA_VM /* * Start the user bootstrap. */ bootstrap_create(); #if XPR_DEBUG xprinit(); /* XXX */ #endif XPR_DEBUG /* * Become the pageout daemon. */ (void) spl0(); vm_pageout(); /*NOTREACHED*/ }
/* * Now running in a thread. Create the rest of the kernel threads * and the bootstrap task. */ void start_kernel_threads(void) { register int i; /* * Create the idle threads and the other * service threads. */ for (i = 0; i < NCPUS; i++) { if (machine_slot[i].is_cpu) { thread_t th; spl_t s; processor_t processor = cpu_to_processor(i); (void) thread_create_at(kernel_task, &th, idle_thread); s=splsched(); thread_lock(th); thread_bind_locked(th, processor); processor->idle_thread = th; /*(void) thread_resume(th->top_act);*/ th->state |= TH_RUN; thread_setrun( th, TRUE, TAIL_Q); thread_unlock( th ); splx(s); } } (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); #if THREAD_SWAPPER (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); (void) kernel_thread(kernel_task, swapout_thread, (char *) 0); #endif /* THREAD_SWAPPER */ #if TASK_SWAPPER if (task_swap_on) { (void) kernel_thread(kernel_task, task_swapper, (char *) 0); (void) kernel_thread(kernel_task, task_swap_swapout_thread, (char *) 0); } #endif /* TASK_SWAPPER */ (void) kernel_thread(kernel_task, sched_thread, (char *) 0); (void) kernel_thread(kernel_task, timeout_thread, (char *) 0); #if NORMA_VM (void) kernel_thread(kernel_task, vm_object_thread, (char *) 0); #endif /* NORMA_VM */ /* * Create the clock service. */ clock_service_create(); /* * Create the device service. */ device_service_create(); /* * Initialize distributed services, starting * with distributed IPC and progressing to any * services layered on top of that. * * This stub exists even in non-NORMA systems. */ norma_bootstrap(); /* * Initialize any testing services blocking the main kernel * thread so that the in-kernel tests run without interference * from other boot time activities. We will resume this thread * in kernel_test_thread(). */ #if KERNEL_TEST /* * Initialize the lock that will be used to guard * variables that will be used in the test synchronization * scheme. */ simple_lock_init(&kernel_test_lock, ETAP_MISC_KERNEL_TEST); #if PARAGON860 { char *s; unsigned int firstnode; /* * Only start up loopback tests on boot node. */ if ((s = (char *) getbootenv("BOOT_FIRST_NODE")) == 0) panic("startup"); firstnode = atoi(s); (void) kernel_thread(kernel_task, kernel_test_thread, (char * )(dipc_node_self() == (node_name) firstnode)); } #else /* PARAGON860 */ (void) kernel_thread(kernel_task, kernel_test_thread, (char *) 0); #endif /* PARAGON860 */ { /* * The synchronization scheme uses a simple lock, two * booleans and the wakeup event. The wakeup event will * be posted by kernel_test_thread(). */ spl_t s; s = splsched(); simple_lock(&kernel_test_lock); while(!kernel_test_thread_sync_done){ assert_wait((event_t) &start_kernel_threads, FALSE); start_kernel_threads_blocked = TRUE; simple_unlock(&kernel_test_lock); splx(s); thread_block((void (*)(void)) 0); s = splsched(); simple_lock(&kernel_test_lock); start_kernel_threads_blocked = FALSE; } kernel_test_thread_sync_done = FALSE; /* Reset for next use */ simple_unlock(&kernel_test_lock); splx(s); } #endif /* KERNEL_TEST */ /* * Start the user bootstrap. */ bootstrap_create(); #if XPR_DEBUG xprinit(); /* XXX */ #endif /* XPR_DEBUG */ #if NCPUS > 1 /* * Create the shutdown thread. */ (void) kernel_thread(kernel_task, action_thread, (char *) 0); /* * Allow other CPUs to run. * * (this must be last, to allow bootstrap_create to fiddle with * its child thread before some cpu tries to run it) */ start_other_cpus(); #endif /* NCPUS > 1 */ /* * Become the pageout daemon. */ (void) spllo(); vm_pageout(); /*NOTREACHED*/ }
/* * Now running in a thread. Create the rest of the kernel threads * and the bootstrap task. */ void start_kernel_threads() { register int i; /* * Create the idle threads and the other * service threads. */ for (i = 0; i < NCPUS; i++) { if (machine_slot[i].is_cpu) { thread_t th; (void) thread_create(kernel_task, &th); thread_bind(th, cpu_to_processor(i)); thread_start(th, idle_thread); thread_doswapin(th); (void) thread_resume(th); } } (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); (void) kernel_thread(kernel_task, sched_thread, (char *) 0); #if NCPUS > 1 /* * Create the shutdown thread. */ (void) kernel_thread(kernel_task, action_thread, (char *) 0); /* * Allow other CPUs to run. */ start_other_cpus(); #endif /* NCPUS > 1 */ /* * Create the device service. */ device_service_create(); /* * Initialize kernel task's creation time. * When we created the kernel task in task_init, the mapped * time was not yet available. Now, last thing before starting * the user bootstrap, record the current time as the kernel * task's creation time. */ record_time_stamp (&kernel_task->creation_time); /* * Start the user bootstrap. */ bootstrap_create(); #if XPR_DEBUG xprinit(); /* XXX */ #endif /* XPR_DEBUG */ /* * Become the pageout daemon. */ (void) spl0(); vm_pageout(); /*NOTREACHED*/ }