]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/app_cpu_thread.cpp
update
[l4.git] / kernel / fiasco / src / kern / app_cpu_thread.cpp
1 INTERFACE [mp]:
2
3 #include "kernel_thread.h"
4
5 class App_cpu_thread : public Kernel_thread
6 {
7 private:
8   void bootstrap(Mword resume) asm ("call_ap_bootstrap") FIASCO_FASTCALL;
9 };
10
11 IMPLEMENTATION [mp]:
12
13 #include <cstdlib>
14 #include <cstdio>
15
16 #include "config.h"
17 #include "delayloop.h"
18 #include "fpu.h"
19 #include "globals.h"
20 #include "helping_lock.h"
21 #include "kernel_task.h"
22 #include "processor.h"
23 #include "scheduler.h"
24 #include "task.h"
25 #include "thread.h"
26 #include "thread_state.h"
27 #include "timer.h"
28 #include "timer_tick.h"
29 #include "spin_lock.h"
30
31 PUBLIC static
32 Kernel_thread *
33 App_cpu_thread::may_be_create(Cpu_number cpu, bool cpu_never_seen_before)
34 {
35   if (!cpu_never_seen_before)
36     {
37       kernel_context(cpu)->reset_kernel_sp();
38       return static_cast<Kernel_thread *>(kernel_context(cpu));
39     }
40
41   Kernel_thread *t = new (Ram_quota::root) App_cpu_thread;
42   assert (t);
43
44   t->set_home_cpu(cpu);
45   t->set_current_cpu(cpu);
46   check(t->bind(Kernel_task::kernel_task(), User<Utcb>::Ptr(0)));
47   return t;
48 }
49
50
51 // the kernel bootstrap routine
52 IMPLEMENT
53 void
54 App_cpu_thread::bootstrap(Mword resume)
55 {
56   extern Spin_lock<Mword> _tramp_mp_spinlock;
57
58   state_change_dirty(0, Thread_ready);          // Set myself ready
59
60
61   Fpu::init(current_cpu(), resume);
62
63   // initialize the current_mem_space function to point to the kernel space
64   Kernel_task::kernel_task()->make_current();
65
66   Mem_unit::tlb_flush();
67
68   Cpu::cpus.current().set_online(1);
69
70   _tramp_mp_spinlock.set(1);
71
72   if (!resume)
73     {
74       kernel_context(current_cpu(), this);
75       Sched_context::rq.current().set_idle(this->sched());
76
77       Timer_tick::setup(current_cpu());
78     }
79
80   Rcu::leave_idle(current_cpu());
81   enable_tlb(current_cpu());
82
83   if (!resume)
84     // Setup initial timeslice
85     Sched_context::rq.current().set_current_sched(sched());
86
87   if (!resume)
88     Per_cpu_data::run_late_ctors(current_cpu());
89
90   Scheduler::scheduler.trigger_hotplug_event();
91   Timer_tick::enable(current_cpu());
92   cpu_lock.clear();
93
94   if (!resume)
95     printf("CPU[%u]: goes to idle loop\n", cxx::int_value<Cpu_number>(current_cpu()));
96
97   for (;;)
98     idle_op();
99 }