]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kernel_thread.cpp
dee8b99081c79f266c91111358bdd6d52784b7f2
[l4.git] / kernel / fiasco / src / kern / kernel_thread.cpp
1 INTERFACE:
2
3 #include "thread.h"
4
5 class Kernel_thread : public Thread
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(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   // Setup initial timeslice
80   set_current_sched (sched());
81
82   Timer::enable();
83
84   bootstrap_arch();
85
86   Per_cpu_data::run_late_ctors(0);
87
88   Proc::sti();
89   printf("Calibrating timer loop... ");
90   // Init delay loop, needs working timer interrupt
91   if (running)
92     Delay::init();
93   printf("done.\n");
94
95   run();
96 }
97
98 /**
99  * The idle loop
100  * NEVER inline this function, because our caller is an initcall
101  */
102 IMPLEMENT FIASCO_NOINLINE FIASCO_NORETURN
103 void
104 Kernel_thread::run()
105 {
106   free_initcall_section();
107
108   // No initcalls after this point!
109
110   kernel_context(cpu(), this);
111
112   // init_workload cannot be an initcall, because it fires up the userland
113   // applications which then have access to initcall frames as per kinfo page.
114   init_workload();
115
116   do_idle();
117 }
118
119 // ------------------------------------------------------------------------
120 IMPLEMENTATION [!arch_idle]:
121
122 PUBLIC inline NEEDS["processor.h"]
123 void
124 Kernel_thread::idle_op()
125 {
126   if (Config::hlt_works_ok)
127     Proc::halt();                       // stop the CPU, waiting for an int
128   else
129     Proc::pause();
130 }
131
132 // ------------------------------------------------------------------------
133 IMPLEMENTATION [!kernel_can_exit]:
134
135 IMPLEMENT
136 void
137 Kernel_thread::do_idle()
138 {
139   while (1)
140     idle_op();
141 }
142
143 // ------------------------------------------------------------------------
144 IMPLEMENTATION [kernel_can_exit]:
145
146 IMPLEMENT
147 void
148 Kernel_thread::do_idle()
149 {
150   while (running)
151     {
152       Mem::rmb();
153       idle_op();
154     }
155
156   puts ("\nExiting, wait...");
157
158   Reap_list rl;
159   Task *sigma0 = static_cast<Task *>(sigma0_task);
160   delete sigma0;
161
162   rl = Reap_list();
163   boot_task->initiate_deletion(rl.list());
164   boot_task->destroy(rl.list());
165   rl.del();
166   delete boot_task; // Nuke everything else
167
168   Helping_lock::threading_system_active = false;
169
170   arch_exit();
171 }