]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kernel_thread.cpp
update
[l4.git] / kernel / fiasco / src / kern / kernel_thread.cpp
1 INTERFACE:
2
3 #include "thread_object.h"
4
5 class Kernel_thread : public Thread_object
6 {
7 private:
8   /**
9    * Frees the memory of the initcall sections.
10    *
11    * Virtually initcall sections are freed by not marking them
12    * reserved in the KIP. This method just invalidates the contents of
13    * the memory, by filling it with some invalid data and may be
14    * unmapping it.
15    */
16   void  free_initcall_section();
17   void  bootstrap()             asm ("call_bootstrap") FIASCO_FASTCALL;
18   void  bootstrap_arch();
19   void  run();
20   void  do_idle() __attribute__((noreturn));
21
22 protected:
23   void  init_workload();
24 };
25
26 INTERFACE [kernel_can_exit]:
27
28 EXTENSION class Kernel_thread
29 {
30 private:
31   void  arch_exit() __attribute__((noreturn));
32 };
33
34 IMPLEMENTATION:
35
36 #include <cstdlib>
37 #include <cstdio>
38
39 #include "config.h"
40 #include "cpu.h"
41 #include "delayloop.h"
42 #include "globals.h"
43 #include "helping_lock.h"
44 #include "kernel_task.h"
45 #include "processor.h"
46 #include "task.h"
47 #include "thread.h"
48 #include "thread_state.h"
49 #include "timer.h"
50 #include "vmem_alloc.h"
51
52
53
54 PUBLIC
55 Kernel_thread::Kernel_thread() : Thread_object(Thread::Kernel)
56 {}
57
58 PUBLIC inline
59 Mword *
60 Kernel_thread::init_stack()
61 {
62   return _kernel_sp;
63 }
64
65 // the kernel bootstrap routine
66 IMPLEMENT FIASCO_INIT
67 void
68 Kernel_thread::bootstrap()
69 {
70   // Initializations done -- Helping_lock can now use helping lock
71   Helping_lock::threading_system_active = true;
72
73   state_change_dirty (0, Thread_ready);         // Set myself ready
74
75   set_cpu_of(this, Cpu::boot_cpu()->id());
76   Timer::init_system_clock();
77   Sched_context::rq(cpu()).set_idle(this->sched());
78
79   Kernel_task::kernel_task()->mem_space()->make_current();
80
81   // Setup initial timeslice
82   set_current_sched(sched());
83
84   Timer::enable();
85
86   bootstrap_arch();
87
88   Per_cpu_data::run_late_ctors(0);
89
90   Proc::sti();
91   printf("Calibrating timer loop... ");
92   // Init delay loop, needs working timer interrupt
93   if (running)
94     Delay::init();
95   printf("done.\n");
96
97   run();
98 }
99
100 /**
101  * The idle loop
102  * NEVER inline this function, because our caller is an initcall
103  */
104 IMPLEMENT FIASCO_NOINLINE FIASCO_NORETURN
105 void
106 Kernel_thread::run()
107 {
108   free_initcall_section();
109
110   // No initcalls after this point!
111
112   kernel_context(cpu(), this);
113
114   // init_workload cannot be an initcall, because it fires up the userland
115   // applications which then have access to initcall frames as per kinfo page.
116   init_workload();
117
118   do_idle();
119 }
120
121 // ------------------------------------------------------------------------
122 IMPLEMENTATION [!arch_idle]:
123
124 PUBLIC inline NEEDS["processor.h"]
125 void
126 Kernel_thread::idle_op()
127 {
128   if (Config::hlt_works_ok)
129     Proc::halt();                       // stop the CPU, waiting for an int
130   else
131     Proc::pause();
132 }
133
134 // ------------------------------------------------------------------------
135 IMPLEMENTATION [!kernel_can_exit]:
136
137 IMPLEMENT
138 void
139 Kernel_thread::do_idle()
140 {
141   while (1)
142     idle_op();
143 }
144
145 // ------------------------------------------------------------------------
146 IMPLEMENTATION [kernel_can_exit]:
147
148 IMPLEMENT
149 void
150 Kernel_thread::do_idle()
151 {
152   while (running)
153     {
154       Mem::rmb();
155       idle_op();
156     }
157
158   puts ("\nExiting, wait...");
159
160   Reap_list rl;
161   Task *sigma0 = static_cast<Task *>(sigma0_task);
162   delete sigma0;
163
164   rl = Reap_list();
165   boot_task->initiate_deletion(rl.list());
166   boot_task->destroy(rl.list());
167   rl.del();
168   delete boot_task; // Nuke everything else
169
170   Helping_lock::threading_system_active = false;
171
172   arch_exit();
173 }