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