source: mainline/kernel/generic/src/main/main.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 9.9 KB
RevLine 
[f761f1eb]1/*
[df4ed85]2 * Copyright (c) 2001-2004 Jakub Jermar
[f761f1eb]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[8e3bf3e2]29/** @addtogroup main
[b45c443]30 * @{
31 */
32
[9179d0a]33/**
[b45c443]34 * @file
[13a638d]35 * @brief Main initialization kernel function for all processors.
[9179d0a]36 *
37 * During kernel boot, all processors, after architecture dependent
38 * initialization, start executing code found in this file. After
39 * bringing up all subsystems, control is passed to scheduler().
40 *
41 * The bootstrap processor starts executing main_bsp() while
42 * the application processors start executing main_ap().
43 *
44 * @see scheduler()
45 * @see main_bsp()
46 * @see main_ap()
47 */
48
[f761f1eb]49#include <arch/asm.h>
[63e27ef]50#include <debug.h>
[d5d2a3f]51#include <context.h>
[f761f1eb]52#include <print.h>
[02a99d2]53#include <panic.h>
[63e27ef]54#include <assert.h>
[f761f1eb]55#include <config.h>
56#include <time/clock.h>
[b3f8fb7]57#include <time/timeout.h>
[f761f1eb]58#include <proc/scheduler.h>
59#include <proc/thread.h>
60#include <proc/task.h>
61#include <main/kinit.h>
[5fe5f1e]62#include <main/version.h>
[f4338d2]63#include <console/kconsole.h>
[5d67baa]64#include <console/console.h>
[91db0280]65#include <log.h>
[f761f1eb]66#include <cpu.h>
[e0cdb7b6]67#include <align.h>
[aace6624]68#include <interrupt.h>
[b5746a2]69#include <str.h>
[f761f1eb]70#include <mm/frame.h>
71#include <mm/page.h>
[6d7ffa65]72#include <genarch/mm/page_pt.h>
[622f409]73#include <mm/km.h>
[169587a]74#include <mm/tlb.h>
[20d50a1]75#include <mm/as.h>
[4e147a6]76#include <mm/slab.h>
[8d308b9]77#include <mm/reserve.h>
[f761f1eb]78#include <synch/waitq.h>
[9aa72b4]79#include <synch/futex.h>
[8a64e81e]80#include <synch/workqueue.h>
[2ee1ccc]81#include <smp/smp_call.h>
[393f631]82#include <arch/arch.h>
[f761f1eb]83#include <arch.h>
[f2ffad4]84#include <arch/faddr.h>
[6d9c49a]85#include <ipc/ipc.h>
[93165be]86#include <macros.h>
[2810636]87#include <adt/btree.h>
[5fe5f1e]88#include <smp/smp.h>
[f8ddd17]89#include <ddi/ddi.h>
[4b241f3]90#include <main/main.h>
[13a638d]91#include <ipc/event.h>
[d9fae235]92#include <sysinfo/sysinfo.h>
[9dae191e]93#include <sysinfo/stats.h>
[41deb2a]94#include <lib/ra.h>
[ce732e74]95#include <cap/cap.h>
[5fe5f1e]96
[328cc31]97/* Ensure [u]int*_t types are of correct size.
98 *
99 * Probably, this is not the best place for such tests
100 * but this file is compiled on all architectures.
101 */
102#define CHECK_INT_TYPE_(signness, size) \
[63e27ef]103 static_assert(sizeof(signness##size##_t) * 8 == size, \
[328cc31]104 #signness #size "_t does not have " #size " bits");
[9e40355e]105
[328cc31]106#define CHECK_INT_TYPE(size) \
[9e40355e]107 CHECK_INT_TYPE_(int, size); \
108 CHECK_INT_TYPE_(uint, size)
[328cc31]109
110CHECK_INT_TYPE(8);
111CHECK_INT_TYPE(16);
112CHECK_INT_TYPE(32);
113CHECK_INT_TYPE(64);
114
[e459f12]115/** Global configuration structure. */
[55896b6]116config_t config = {
117 .identity_configured = false,
[40c8c17]118 .non_identity_configured = false,
119 .physmem_end = 0
[55896b6]120};
[e459f12]121
[3b3faf51]122/** Boot arguments. */
123char bargs[CONFIG_BOOT_ARGUMENTS_BUFLEN] = {};
124
[e459f12]125/** Initial user-space tasks */
126init_t init = {
[6c441cf8]127 .cnt = 0
[e459f12]128};
[5fe5f1e]129
[61e90dd]130/** Boot allocations. */
131ballocs_t ballocs = {
[0b4a67a]132 .base = (uintptr_t) NULL,
[61e90dd]133 .size = 0
134};
135
[f761f1eb]136context_t ctx;
137
[c0855a0]138/** Lowest safe stack virtual address. */
[263bda2]139uintptr_t stack_safe = 0;
[deaa22f]140
[f761f1eb]141/*
142 * These two functions prevent stack from underflowing during the
143 * kernel boot phase when SP is set to the very top of the reserved
144 * space. The stack could get corrupted by a fooled compiler-generated
145 * pop sequence otherwise.
146 */
147static void main_bsp_separated_stack(void);
[263bda2]148
[80d2bdb]149#ifdef CONFIG_SMP
[f761f1eb]150static void main_ap_separated_stack(void);
[80d2bdb]151#endif
[f761f1eb]152
[7f0837c]153/** Main kernel routine for bootstrap CPU.
[673104e]154 *
[7a4202d]155 * The code here still runs on the boot stack, which knows nothing about
156 * preemption counts. Because of that, this function cannot directly call
157 * functions that disable or enable preemption (e.g. spinlock_lock()). The
158 * primary task of this function is to calculate address of a new stack and
159 * switch to it.
[673104e]160 *
[22f7769]161 * Assuming interrupts_disable().
[673104e]162 *
[f761f1eb]163 */
[7a0359b]164NO_TRACE void main_bsp(void)
[f761f1eb]165{
166 config.cpu_count = 1;
167 config.cpu_active = 1;
[a35b458]168
[aed4eca]169 config.base = hardcoded_load_address;
[f8ddd17]170 config.kernel_size = ALIGN_UP(hardcoded_ktext_size +
[6f4495f5]171 hardcoded_kdata_size, PAGE_SIZE);
[26aafe8]172 config.stack_size = STACK_SIZE;
[a35b458]173
[deaa22f]174 /* Initialy the stack is placed just after the kernel */
175 config.stack_base = config.base + config.kernel_size;
[a35b458]176
[deaa22f]177 /* Avoid placing stack on top of init */
[98000fb]178 size_t i;
[deaa22f]179 for (i = 0; i < init.cnt; i++) {
[32817cc]180 if (overlaps(KA2PA(config.stack_base), config.stack_size,
181 init.tasks[i].paddr, init.tasks[i].size)) {
182 /*
183 * The init task overlaps with the memory behind the
184 * kernel image so it must be in low memory and we can
185 * use PA2KA on the init task's physical address.
186 */
187 config.stack_base = ALIGN_UP(
188 PA2KA(init.tasks[i].paddr) + init.tasks[i].size,
189 config.stack_size);
190 }
[deaa22f]191 }
[a35b458]192
[61e90dd]193 /* Avoid placing stack on top of boot allocations. */
194 if (ballocs.size) {
[e2650d3]195 if (PA_OVERLAPS(config.stack_base, config.stack_size,
[6f4495f5]196 ballocs.base, ballocs.size))
[f8ddd17]197 config.stack_base = ALIGN_UP(ballocs.base +
[6f4495f5]198 ballocs.size, PAGE_SIZE);
[61e90dd]199 }
[a35b458]200
[deaa22f]201 if (config.stack_base < stack_safe)
202 config.stack_base = ALIGN_UP(stack_safe, PAGE_SIZE);
[a35b458]203
[be50915]204 context_save(&ctx);
[26aafe8]205 context_set(&ctx, FADDR(main_bsp_separated_stack),
206 config.stack_base, STACK_SIZE);
[be50915]207 context_restore(&ctx);
[f761f1eb]208 /* not reached */
209}
210
[7f0837c]211/** Main kernel routine for bootstrap CPU using new stack.
[673104e]212 *
213 * Second part of main_bsp().
214 *
215 */
[263bda2]216void main_bsp_separated_stack(void)
[fde6429]217{
[7a4202d]218 /* Keep this the first thing. */
219 the_initialize(THE);
[a35b458]220
[7a4202d]221 version_print();
[a35b458]222
[7e752b2]223 LOG("\nconfig.base=%p config.kernel_size=%zu"
224 "\nconfig.stack_base=%p config.stack_size=%zu",
[1caeb2d]225 (void *) config.base, config.kernel_size,
226 (void *) config.stack_base, config.stack_size);
[a35b458]227
[76fca31]228#ifdef CONFIG_KCONSOLE
[ff3b3197]229 /*
230 * kconsole data structures must be initialized very early
231 * because other subsystems will register their respective
232 * commands.
233 */
[263bda2]234 kconsole_init();
[76fca31]235#endif
[a35b458]236
[ef67bab]237 /*
238 * Exception handler initialization, before architecture
[0132630]239 * starts adding its own handlers
[aace6624]240 */
[263bda2]241 exc_init();
[a35b458]242
[fc1e4f6]243 /*
244 * Memory management subsystems initialization.
[b84aaba]245 */
[36df4109]246 ARCH_OP(pre_mm_init);
[622f409]247 km_identity_init();
[263bda2]248 frame_init();
249 slab_cache_init();
[dabbe28]250 ra_init();
[263bda2]251 sysinfo_init();
252 btree_init();
253 as_init();
254 page_init();
255 tlb_init();
[622f409]256 km_non_identity_init();
[263bda2]257 ddi_init();
[36df4109]258 ARCH_OP(post_mm_init);
[8d308b9]259 reserve_init();
[36df4109]260 ARCH_OP(pre_smp_init);
[263bda2]261 smp_init();
[a35b458]262
[f8ddd17]263 /* Slab must be initialized after we know the number of processors. */
[263bda2]264 slab_enable_cpucache();
[a35b458]265
[933cadf]266 uint64_t size;
267 const char *size_suffix;
268 bin_order_suffix(zones_total_size(), &size, &size_suffix, false);
269 printf("Detected %u CPU(s), %" PRIu64 " %s free memory\n",
270 config.cpu_count, size, size_suffix);
[a35b458]271
[263bda2]272 cpu_init();
273 calibrate_delay_loop();
[36df4109]274 ARCH_OP(post_cpu_init);
[49e6c6b4]275
[2ee1ccc]276 smp_call_init();
[8a64e81e]277 workq_global_init();
[263bda2]278 clock_counter_init();
279 timeout_init();
280 scheduler_init();
[ce732e74]281 caps_init();
[263bda2]282 task_init();
283 thread_init();
284 futex_init();
[3b3faf51]285
286 sysinfo_set_item_data("boot_args", NULL, bargs, str_size(bargs) + 1);
287
[c06eb06]288 if (init.cnt > 0) {
[98000fb]289 size_t i;
[c06eb06]290 for (i = 0; i < init.cnt; i++)
[7e752b2]291 LOG("init[%zu].addr=%p, init[%zu].size=%zu",
[edd7c63c]292 i, (void *) init.tasks[i].paddr, i, init.tasks[i].size);
[c06eb06]293 } else
[ae5aa90]294 printf("No init binaries found.\n");
[a35b458]295
[263bda2]296 ipc_init();
297 event_init();
[6fa9a99d]298 kio_init();
[91db0280]299 log_init();
[263bda2]300 stats_init();
[a35b458]301
[f761f1eb]302 /*
303 * Create kernel task.
304 */
[b84aaba]305 task_t *kernel = task_create(AS_KERNEL, "kernel");
306 if (!kernel)
[f651e80]307 panic("Cannot create kernel task.");
[a35b458]308
[f761f1eb]309 /*
310 * Create the first thread.
311 */
[6eef3c4]312 thread_t *kinit_thread = thread_create(kinit, NULL, kernel,
313 THREAD_FLAG_UNCOUNTED, "kinit");
[b84aaba]314 if (!kinit_thread)
[f651e80]315 panic("Cannot create kinit thread.");
[263bda2]316 thread_ready(kinit_thread);
[a35b458]317
[f761f1eb]318 /*
319 * This call to scheduler() will return to kinit,
320 * starting the thread of kernel threads.
321 */
322 scheduler();
323 /* not reached */
324}
325
[5f85c91]326#ifdef CONFIG_SMP
[263bda2]327
[7f0837c]328/** Main kernel routine for application CPUs.
[673104e]329 *
330 * Executed by application processors, temporary stack
[26678e5]331 * is at ctx.sp which was set during BSP boot.
[5fe5f1e]332 * This function passes control directly to
333 * main_ap_separated_stack().
[673104e]334 *
[22f7769]335 * Assuming interrupts_disable()'d.
[673104e]336 *
[f761f1eb]337 */
338void main_ap(void)
339{
340 /*
341 * Incrementing the active CPU counter will guarantee that the
[26678e5]342 * *_init() functions can find out that they need to
343 * do initialization for AP only.
[f761f1eb]344 */
345 config.cpu_active++;
[a35b458]346
[7ce9284]347 /*
348 * The THE structure is well defined because ctx.sp is used as stack.
349 */
350 the_initialize(THE);
[a35b458]351
[36df4109]352 ARCH_OP(pre_mm_init);
[f761f1eb]353 frame_init();
354 page_init();
[ce031f0]355 tlb_init();
[36df4109]356 ARCH_OP(post_mm_init);
[a35b458]357
[f761f1eb]358 cpu_init();
359 calibrate_delay_loop();
[36df4109]360 ARCH_OP(post_cpu_init);
[a35b458]361
[7ce9284]362 the_copy(THE, (the_t *) CPU->stack);
[a35b458]363
[f761f1eb]364 /*
365 * If we woke kmp up before we left the kernel stack, we could
366 * collide with another CPU coming up. To prevent this, we
367 * switch to this cpu's private stack prior to waking kmp up.
368 */
[b24786a]369 context_save(&CPU->saved_context);
[f8ddd17]370 context_set(&CPU->saved_context, FADDR(main_ap_separated_stack),
[26aafe8]371 (uintptr_t) CPU->stack, STACK_SIZE);
[be50915]372 context_restore(&CPU->saved_context);
[f761f1eb]373 /* not reached */
374}
375
[7f0837c]376/** Main kernel routine for application CPUs using new stack.
[673104e]377 *
378 * Second part of main_ap().
379 *
380 */
[f761f1eb]381void main_ap_separated_stack(void)
382{
[2ee1ccc]383 smp_call_init();
[a35b458]384
[f761f1eb]385 /*
386 * Configure timeouts for this cpu.
387 */
388 timeout_init();
[a35b458]389
[f761f1eb]390 waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
391 scheduler();
392 /* not reached */
393}
[263bda2]394
[5f85c91]395#endif /* CONFIG_SMP */
[b45c443]396
[8e3bf3e2]397/** @}
[b45c443]398 */
Note: See TracBrowser for help on using the repository browser.