4 //---------------------------------------------------------------------------
13 #include "initcalls.h"
14 #include "kmem_alloc.h"
16 #include "pagetable.h"
18 #include "kernel_thread.h"
19 #include "kernel_task.h"
20 #include "kernel_console.h"
23 #include "terminate.h"
25 #include "processor.h"
27 static int exit_question_active = 0;
29 extern "C" void __attribute__ ((noreturn))
32 if (exit_question_active)
43 static void exit_question()
45 exit_question_active = 1;
49 puts("\nReturn reboots, \"k\" enters L4 kernel debugger...");
51 char c = Kconsole::console()->getchar();
53 if (c == 'k' || c == 'K')
59 // it may be better to not call all the destruction stuff
60 // because of unresolved static destructor dependency
62 // SO just do the reset at this point.
63 puts("\033[1mRebooting...\033[0m");
73 // caution: no stack variables in this function because we're going
74 // to change the stack pointer!
76 // make some basic initializations, then create and run the kernel
78 set_exit_question(&exit_question);
80 printf("%s\n", Kip::k()->version_string());
82 // disallow all interrupts before we selectively enable them
85 // create kernel thread
86 static Kernel_thread *kernel = new (Ram_quota::root) Kernel_thread;
88 Task *const ktask = Kernel_task::kernel_task();
89 check(kernel->bind(ktask, User<Utcb>::Ptr(0)));
91 Mem_unit::tlb_flush();
93 // switch to stack of kernel thread and bootstrap the kernel
95 (" str sp,%0 \n" // save stack pointer in safe register
96 " mov sp,%1 \n" // switch stack
97 " mov r0,%2 \n" // push "this" pointer
98 " bl call_bootstrap \n"
100 : "r" (kernel->init_stack()), "r" (kernel));
103 //------------------------------------------------------------------------
104 IMPLEMENTATION[arm && mp]:
110 #include "app_cpu_thread.h"
111 #include "per_cpu_data_alloc.h"
112 #include "perf_cnt.h"
114 #include "spin_lock.h"
115 #include "utcb_init.h"
118 int boot_ap_cpu(unsigned cpu) __asm__("BOOT_AP_CPU");
120 int boot_ap_cpu(unsigned _cpu)
122 if (!Per_cpu_data_alloc::alloc(_cpu))
124 extern Spin_lock<Mword> _tramp_mp_spinlock;
125 printf("CPU allocation failed for CPU%u, disabling CPU.\n", _cpu);
126 _tramp_mp_spinlock.clear();
130 Per_cpu_data::run_ctors(_cpu);
131 Cpu &cpu = Cpu::cpus.cpu(_cpu);
134 Utcb_init::init_ap(cpu);
136 Ipi::cpu(_cpu).init();
140 // create kernel thread
141 App_cpu_thread *kernel = new (Ram_quota::root) App_cpu_thread();
142 set_cpu_of(kernel, _cpu);
143 check(kernel->bind(Kernel_task::kernel_task(), User<Utcb>::Ptr(0)));
145 // switch to stack of kernel thread and bootstrap the kernel
147 (" mov sp,%0 \n" // switch stack
148 " mov r0,%1 \n" // push "this" pointer
149 " bl call_ap_bootstrap \n"
151 : "r" (kernel->init_stack()), "r" (kernel));