kinit.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00044 #include <main/kinit.h>
00045 #include <config.h>
00046 #include <arch.h>
00047 #include <proc/scheduler.h>
00048 #include <proc/task.h>
00049 #include <proc/thread.h>
00050 #include <panic.h>
00051 #include <func.h>
00052 #include <cpu.h>
00053 #include <arch/asm.h>
00054 #include <mm/page.h>
00055 #include <arch/mm/page.h>
00056 #include <mm/as.h>
00057 #include <mm/frame.h>
00058 #include <print.h>
00059 #include <memstr.h>
00060 #include <console/console.h>
00061 #include <interrupt.h>
00062 #include <console/kconsole.h>
00063 #include <security/cap.h>
00064 
00065 #ifdef CONFIG_SMP
00066 #include <arch/smp/mps.h>
00067 #endif /* CONFIG_SMP */
00068 
00069 #include <synch/waitq.h>
00070 #include <synch/spinlock.h>
00071 
00072 #ifdef CONFIG_TEST
00073 #include <test.h>
00074 #endif /* CONFIG_TEST */
00075 
00084 void kinit(void *arg)
00085 {
00086         thread_t *t;
00087 
00088         /*
00089          * Detach kinit as nobody will call thread_join_timeout() on it.
00090          */
00091         thread_detach(THREAD);
00092 
00093         interrupts_disable();
00094 
00095 #ifdef CONFIG_SMP                       
00096         if (config.cpu_count > 1) {
00097                 /*
00098                  * Create the kmp thread and wait for its completion.
00099                  * cpu1 through cpuN-1 will come up consecutively and
00100                  * not mess together with kcpulb threads.
00101                  * Just a beautification.
00102                  */
00103                 if ((t = thread_create(kmp, NULL, TASK, 0, "kmp"))) {
00104                         spinlock_lock(&t->lock);
00105                         t->flags |= X_WIRED;
00106                         t->cpu = &cpus[0];
00107                         spinlock_unlock(&t->lock);
00108                         thread_ready(t);
00109                 } else
00110                         panic("thread_create/kmp\n");
00111                 thread_join(t);
00112                 thread_detach(t);
00113         }
00114 #endif /* CONFIG_SMP */
00115         /*
00116          * Now that all CPUs are up, we can report what we've found.
00117          */
00118         cpu_list();
00119 
00120 #ifdef CONFIG_SMP
00121         if (config.cpu_count > 1) {
00122                 int i;
00123                 
00124                 /*
00125                  * For each CPU, create its load balancing thread.
00126                  */
00127                 for (i = 0; i < config.cpu_count; i++) {
00128 
00129                         if ((t = thread_create(kcpulb, NULL, TASK, 0, "kcpulb"))) {
00130                                 spinlock_lock(&t->lock);                        
00131                                 t->flags |= X_WIRED;
00132                                 t->cpu = &cpus[i];
00133                                 spinlock_unlock(&t->lock);
00134                                 thread_ready(t);
00135                         } else
00136                                 panic("thread_create/kcpulb\n");
00137 
00138                 }
00139         }
00140 #endif /* CONFIG_SMP */
00141 
00142         /*
00143          * At this point SMP, if present, is configured.
00144          */
00145         arch_post_smp_init();
00146 
00147         /*
00148          * Create kernel console.
00149          */
00150         if ((t = thread_create(kconsole, "kconsole", TASK, 0, "kconsole")))
00151                 thread_ready(t);
00152         else
00153                 panic("thread_create/kconsole\n");
00154 
00155         interrupts_enable();
00156 
00157 #ifdef CONFIG_TEST
00158         test();
00159         printf("\nTest finished, please reboot\n");
00160 #else  /* CONFIG_TEST */
00161 
00162         task_t *utask;
00163         count_t i;
00164         for (i = 0; i < init.cnt; i++) {
00165                 /*
00166                  * Run user tasks.
00167                  */
00168                 
00169                 if (init.tasks[i].addr % FRAME_SIZE)
00170                         panic("init[%d].addr is not frame aligned", i);
00171 
00172                 utask = task_run_program((void *) init.tasks[i].addr, "USPACE");
00173                 if (utask) {
00174                         /*
00175                          * Set capabilities to init userspace tasks.
00176                          */
00177                         cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG);
00178                         
00179                         if (!ipc_phone_0) 
00180                                 ipc_phone_0 = &utask->answerbox;
00181                 } else
00182                         printf("Init task %zd not started.\n", i);
00183         }
00184 
00185 
00186         if (!stdin) {
00187                 while (1) {
00188                         thread_sleep(1);
00189                         printf("kinit... ");
00190                 }
00191         }
00192 #endif /* CONFIG_TEST */
00193 
00194 }
00195 

Generated on Sun Jun 18 16:26:58 2006 for HelenOS Kernel (amd64) by  doxygen 1.4.6