]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/main-ia32.cpp
1e318c0f22b3f428cca47b0a4d02b840f55fc972
[l4.git] / kernel / fiasco / src / kern / ia32 / main-ia32.cpp
1 /*
2  * Fiasco-IA32/AMD64
3  * Architecture specific main startup/shutdown code
4  */
5
6 IMPLEMENTATION[ia32,amd64]:
7
8 #include <cstdio>
9 #include <cstring>
10 #include <cstdlib>
11 #include "config.h"
12 #include "io.h"
13 #include "idt.h"
14 #include "kdb_ke.h"
15 #include "kernel_console.h"
16 #include "koptions.h"
17 #include "pic.h"
18 #include "processor.h"
19 #include "reset.h"
20 #include "timer.h"
21 #include "timer_tick.h"
22 #include "terminate.h"
23
24 static int exit_question_active;
25
26
27 extern "C" void __attribute__ ((noreturn))
28 _exit(int)
29 {
30   if (exit_question_active)
31     platform_reset();
32
33   while (1)
34     {
35       Proc::halt();
36       Proc::pause();
37     }
38 }
39
40
41 static
42 void
43 exit_question()
44 {
45   Proc::cli();
46   exit_question_active = 1;
47
48   Pic::Status irqs = Pic::disable_all_save();
49   if (Config::getchar_does_hlt_works_ok)
50     {
51       Timer_tick::set_vectors_stop();
52       Timer_tick::enable(0); // hmexit alway on CPU 0
53       Proc::sti();
54     }
55
56   // make sure that we don't acknowledg the exit question automatically
57   Kconsole::console()->change_state(Console::PUSH, 0, ~Console::INENABLED, 0);
58   puts("\nReturn reboots, \"k\" enters L4 kernel debugger...");
59
60   char c = Kconsole::console()->getchar();
61
62   if (c == 'k' || c == 'K') 
63     {
64       Pic::restore_all(irqs);
65       kdb_ke("_exit");
66     }
67   else
68     {
69       // It may be better to not call all the destruction stuff because of
70       // unresolved static destructor dependency problems. So just do the
71       // reset at this point.
72       puts("\033[1mRebooting.\033[m");
73     }
74 }
75
76 void
77 main_arch()
78 {
79   // console initialization
80   set_exit_question(&exit_question);
81
82   //Pic::disable_all_save();
83 }
84
85
86 //------------------------------------------------------------------------
87 IMPLEMENTATION[(ia32,amd64) && mp]:
88
89 #include <cstdio>
90 #include "apic.h"
91 #include "app_cpu_thread.h"
92 #include "config.h"
93 #include "cpu.h"
94 #include "div32.h"
95 #include "fpu.h"
96 #include "globals.h"
97 #include "ipi.h"
98 #include "kernel_task.h"
99 #include "processor.h"
100 #include "per_cpu_data_alloc.h"
101 #include "perf_cnt.h"
102 #include "spin_lock.h"
103 #include "utcb_init.h"
104
105 int FIASCO_FASTCALL boot_ap_cpu(unsigned _cpu) __asm__("BOOT_AP_CPU");
106
107 int FIASCO_FASTCALL boot_ap_cpu(unsigned _cpu)
108 {
109   if (!Per_cpu_data_alloc::alloc(_cpu))
110     {
111       extern Spin_lock<Mword> _tramp_mp_spinlock;
112       printf("CPU allocation failed for CPU%u, disabling CPU.\n", _cpu);
113       _tramp_mp_spinlock.clear();
114       while (1)
115         Proc::halt();
116     }
117   Per_cpu_data::run_ctors(_cpu);
118   Cpu &cpu = Cpu::cpus.cpu(_cpu);
119
120   Kmem::init_cpu(cpu);
121   Idt::load();
122
123   Apic::init_ap();
124   Ipi::init(_cpu);
125   Timer::init(_cpu);
126   Apic::check_still_getting_interrupts();
127
128
129   // caution: no stack variables in this function because we're going
130   // to change the stack pointer!
131   cpu.print();
132   cpu.show_cache_tlb_info("");
133
134   if (Koptions::o()->opt(Koptions::F_loadcnt))
135     Perf_cnt::init_ap();
136
137   puts("");
138
139   // create kernel thread
140   App_cpu_thread *kernel = new (Ram_quota::root) App_cpu_thread();
141   set_cpu_of(kernel, _cpu);
142   check(kernel->bind(Kernel_task::kernel_task(), User<Utcb>::Ptr(0)));
143
144   main_switch_ap_cpu_stack(kernel);
145   return 0;
146 }