Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2010-2014 Wind River Systems, Inc.
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : /**
8 : : * @file
9 : : * @brief Kernel initialization module
10 : : *
11 : : * This module contains routines that are used to initialize the kernel.
12 : : */
13 : :
14 : : #include <ctype.h>
15 : : #include <stdbool.h>
16 : : #include <string.h>
17 : : #include <offsets_short.h>
18 : : #include <zephyr/kernel.h>
19 : : #include <zephyr/sys/printk.h>
20 : : #include <zephyr/debug/stack.h>
21 : : #include <zephyr/random/random.h>
22 : : #include <zephyr/linker/sections.h>
23 : : #include <zephyr/toolchain.h>
24 : : #include <zephyr/kernel_structs.h>
25 : : #include <zephyr/device.h>
26 : : #include <zephyr/init.h>
27 : : #include <zephyr/linker/linker-defs.h>
28 : : #include <zephyr/platform/hooks.h>
29 : : #include <ksched.h>
30 : : #include <kthread.h>
31 : : #include <ipi.h>
32 : : #include <zephyr/sys/dlist.h>
33 : : #include <kernel_internal.h>
34 : : #include <zephyr/drivers/entropy.h>
35 : : #include <zephyr/logging/log_ctrl.h>
36 : : #include <zephyr/tracing/tracing.h>
37 : : #include <zephyr/debug/gcov.h>
38 : : #include <kswap.h>
39 : : #include <zephyr/timing/timing.h>
40 : : #include <zephyr/logging/log.h>
41 : : #include <zephyr/internal/syscall_handler.h>
42 : : #include <zephyr/arch/common/init.h>
43 : :
44 : : LOG_MODULE_REGISTER(os, CONFIG_KERNEL_LOG_LEVEL);
45 : :
46 : : /* the only struct z_kernel instance */
47 : : __pinned_bss
48 : : struct z_kernel _kernel;
49 : :
50 : : #ifdef CONFIG_PM
51 : : __pinned_bss atomic_t _cpus_active;
52 : : #endif
53 : :
54 : : /* init/main and idle threads */
55 : : K_THREAD_PINNED_STACK_DEFINE(z_main_stack, CONFIG_MAIN_STACK_SIZE);
56 : : struct k_thread z_main_thread;
57 : :
58 : : #ifdef CONFIG_MULTITHREADING
59 : : __pinned_bss
60 : : struct k_thread z_idle_threads[CONFIG_MP_MAX_NUM_CPUS];
61 : :
62 : : static K_KERNEL_PINNED_STACK_ARRAY_DEFINE(z_idle_stacks,
63 : : CONFIG_MP_MAX_NUM_CPUS,
64 : : CONFIG_IDLE_STACK_SIZE);
65 : :
66 : 1 : static void z_init_static_threads(void)
67 : : {
68 [ - + - + ]: 1 : STRUCT_SECTION_FOREACH(_static_thread_data, thread_data) {
69 : 0 : z_setup_new_thread(
70 : : thread_data->init_thread,
71 : : thread_data->init_stack,
72 : : thread_data->init_stack_size,
73 : : thread_data->init_entry,
74 : : thread_data->init_p1,
75 : : thread_data->init_p2,
76 : : thread_data->init_p3,
77 : : thread_data->init_prio,
78 : : thread_data->init_options,
79 : : thread_data->init_name);
80 : :
81 : 0 : thread_data->init_thread->init_data = thread_data;
82 : : }
83 : :
84 : : #ifdef CONFIG_USERSPACE
85 : : STRUCT_SECTION_FOREACH(k_object_assignment, pos) {
86 : : for (int i = 0; pos->objects[i] != NULL; i++) {
87 : : k_object_access_grant(pos->objects[i],
88 : : pos->thread);
89 : : }
90 : : }
91 : : #endif /* CONFIG_USERSPACE */
92 : :
93 : : /*
94 : : * Non-legacy static threads may be started immediately or
95 : : * after a previously specified delay. Even though the
96 : : * scheduler is locked, ticks can still be delivered and
97 : : * processed. Take a sched lock to prevent them from running
98 : : * until they are all started.
99 : : *
100 : : * Note that static threads defined using the legacy API have a
101 : : * delay of K_FOREVER.
102 : : */
103 : 1 : k_sched_lock();
104 [ - + - + ]: 1 : STRUCT_SECTION_FOREACH(_static_thread_data, thread_data) {
105 : 0 : k_timeout_t init_delay = Z_THREAD_INIT_DELAY(thread_data);
106 : :
107 [ # # ]: 0 : if (!K_TIMEOUT_EQ(init_delay, K_FOREVER)) {
108 : 0 : thread_schedule_new(thread_data->init_thread,
109 : : init_delay);
110 : : }
111 : : }
112 : 1 : k_sched_unlock();
113 : 1 : }
114 : : #else
115 : : #define z_init_static_threads() do { } while (false)
116 : : #endif /* CONFIG_MULTITHREADING */
117 : :
118 : : extern const struct init_entry __init_start[];
119 : : extern const struct init_entry __init_EARLY_start[];
120 : : extern const struct init_entry __init_PRE_KERNEL_1_start[];
121 : : extern const struct init_entry __init_PRE_KERNEL_2_start[];
122 : : extern const struct init_entry __init_POST_KERNEL_start[];
123 : : extern const struct init_entry __init_APPLICATION_start[];
124 : : extern const struct init_entry __init_end[];
125 : :
126 : : enum init_level {
127 : : INIT_LEVEL_EARLY = 0,
128 : : INIT_LEVEL_PRE_KERNEL_1,
129 : : INIT_LEVEL_PRE_KERNEL_2,
130 : : INIT_LEVEL_POST_KERNEL,
131 : : INIT_LEVEL_APPLICATION,
132 : : #ifdef CONFIG_SMP
133 : : INIT_LEVEL_SMP,
134 : : #endif /* CONFIG_SMP */
135 : : };
136 : :
137 : : #ifdef CONFIG_SMP
138 : : extern const struct init_entry __init_SMP_start[];
139 : : #endif /* CONFIG_SMP */
140 : :
141 : : /*
142 : : * storage space for the interrupt stack
143 : : *
144 : : * Note: This area is used as the system stack during kernel initialization,
145 : : * since the kernel hasn't yet set up its own stack areas. The dual purposing
146 : : * of this area is safe since interrupts are disabled until the kernel context
147 : : * switches to the init thread.
148 : : */
149 : : K_KERNEL_PINNED_STACK_ARRAY_DEFINE(z_interrupt_stacks,
150 : : CONFIG_MP_MAX_NUM_CPUS,
151 : : CONFIG_ISR_STACK_SIZE);
152 : :
153 : : extern void idle(void *unused1, void *unused2, void *unused3);
154 : :
155 : : #ifdef CONFIG_OBJ_CORE_SYSTEM
156 : : static struct k_obj_type obj_type_cpu;
157 : : static struct k_obj_type obj_type_kernel;
158 : :
159 : : #ifdef CONFIG_OBJ_CORE_STATS_SYSTEM
160 : : static struct k_obj_core_stats_desc cpu_stats_desc = {
161 : : .raw_size = sizeof(struct k_cycle_stats),
162 : : .query_size = sizeof(struct k_thread_runtime_stats),
163 : : .raw = z_cpu_stats_raw,
164 : : .query = z_cpu_stats_query,
165 : : .reset = NULL,
166 : : .disable = NULL,
167 : : .enable = NULL,
168 : : };
169 : :
170 : : static struct k_obj_core_stats_desc kernel_stats_desc = {
171 : : .raw_size = sizeof(struct k_cycle_stats) * CONFIG_MP_MAX_NUM_CPUS,
172 : : .query_size = sizeof(struct k_thread_runtime_stats),
173 : : .raw = z_kernel_stats_raw,
174 : : .query = z_kernel_stats_query,
175 : : .reset = NULL,
176 : : .disable = NULL,
177 : : .enable = NULL,
178 : : };
179 : : #endif /* CONFIG_OBJ_CORE_STATS_SYSTEM */
180 : : #endif /* CONFIG_OBJ_CORE_SYSTEM */
181 : :
182 : : #ifdef CONFIG_REQUIRES_STACK_CANARIES
183 : : #ifdef CONFIG_STACK_CANARIES_TLS
184 : : extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
185 : : #else
186 : : extern volatile uintptr_t __stack_chk_guard;
187 : : #endif /* CONFIG_STACK_CANARIES_TLS */
188 : : #endif /* CONFIG_REQUIRES_STACK_CANARIES */
189 : :
190 : : __pinned_bss
191 : : bool z_sys_post_kernel;
192 : :
193 : : /* defined in device.c */
194 : : extern int do_device_init(const struct device *dev);
195 : :
196 : : /**
197 : : * @brief Initialize state for all static devices.
198 : : *
199 : : * The state object is always zero-initialized, but this may not be
200 : : * sufficient.
201 : : */
202 : 1 : static void z_device_state_init(void)
203 : : {
204 [ - + - + ]: 1 : STRUCT_SECTION_FOREACH(device, dev) {
205 : 0 : k_object_init(dev);
206 : : }
207 : 1 : }
208 : :
209 : : /**
210 : : * @brief Execute all the init entry initialization functions at a given level
211 : : *
212 : : * @details Invokes the initialization routine for each init entry object
213 : : * created by the INIT_ENTRY_DEFINE() macro using the specified level.
214 : : * The linker script places the init entry objects in memory in the order
215 : : * they need to be invoked, with symbols indicating where one level leaves
216 : : * off and the next one begins.
217 : : *
218 : : * @param level init level to run.
219 : : */
220 : 5 : static void z_sys_init_run_level(enum init_level level)
221 : : {
222 : 5 : static const struct init_entry *levels[] = {
223 : : __init_EARLY_start,
224 : : __init_PRE_KERNEL_1_start,
225 : : __init_PRE_KERNEL_2_start,
226 : : __init_POST_KERNEL_start,
227 : : __init_APPLICATION_start,
228 : : #ifdef CONFIG_SMP
229 : : __init_SMP_start,
230 : : #endif /* CONFIG_SMP */
231 : : /* End marker */
232 : : __init_end,
233 : : };
234 : 5 : const struct init_entry *entry;
235 : :
236 [ + + ]: 8 : for (entry = levels[level]; entry < levels[level+1]; entry++) {
237 : 3 : const struct device *dev = entry->dev;
238 : 3 : int result = 0;
239 : :
240 : 3 : sys_trace_sys_init_enter(entry, level);
241 [ - + ]: 3 : if (dev != NULL) {
242 [ # # ]: 0 : if ((dev->flags & DEVICE_FLAG_INIT_DEFERRED) == 0U) {
243 : 0 : result = do_device_init(dev);
244 : : }
245 : : } else {
246 : 3 : result = entry->init_fn();
247 : : }
248 : 3 : sys_trace_sys_init_exit(entry, level, result);
249 : : }
250 : 5 : }
251 : :
252 : : /* defined in banner.c */
253 : : extern void boot_banner(void);
254 : :
255 : :
256 : : #ifdef CONFIG_STATIC_INIT_GNU
257 : :
258 : : extern void (*__zephyr_init_array_start[])();
259 : : extern void (*__zephyr_init_array_end[])();
260 : :
261 : 1 : static void z_static_init_gnu(void)
262 : : {
263 : 1 : void (**fn)();
264 : :
265 [ + + ]: 194 : for (fn = __zephyr_init_array_start; fn != __zephyr_init_array_end; fn++) {
266 : : /* MWDT toolchain sticks a NULL at the end of the array */
267 [ + - ]: 193 : if (*fn == NULL) {
268 : : break;
269 : : }
270 : 193 : (**fn)();
271 : : }
272 : 1 : }
273 : :
274 : : #endif
275 : :
276 : : /**
277 : : * @brief Mainline for kernel's background thread
278 : : *
279 : : * This routine completes kernel initialization by invoking the remaining
280 : : * init functions, then invokes application's main() routine.
281 : : */
282 : : __boot_func
283 : 1 : static void bg_thread_main(void *unused1, void *unused2, void *unused3)
284 : : {
285 : 1 : ARG_UNUSED(unused1);
286 : 1 : ARG_UNUSED(unused2);
287 : 1 : ARG_UNUSED(unused3);
288 : :
289 : : #ifdef CONFIG_MMU
290 : : /* Invoked here such that backing store or eviction algorithms may
291 : : * initialize kernel objects, and that all POST_KERNEL and later tasks
292 : : * may perform memory management tasks (except for
293 : : * k_mem_map_phys_bare() which is allowed at any time)
294 : : */
295 : : z_mem_manage_init();
296 : : #endif /* CONFIG_MMU */
297 : 1 : z_sys_post_kernel = true;
298 : :
299 : : #if CONFIG_IRQ_OFFLOAD
300 : : arch_irq_offload_init();
301 : : #endif
302 : 1 : z_sys_init_run_level(INIT_LEVEL_POST_KERNEL);
303 : :
304 : 1 : soc_late_init_hook();
305 : :
306 : 1 : board_late_init_hook();
307 : :
308 : : #if defined(CONFIG_STACK_POINTER_RANDOM) && (CONFIG_STACK_POINTER_RANDOM != 0)
309 : : z_stack_adjust_initialized = 1;
310 : : #endif /* CONFIG_STACK_POINTER_RANDOM */
311 : 1 : boot_banner();
312 : :
313 : : #ifdef CONFIG_STATIC_INIT_GNU
314 : 1 : z_static_init_gnu();
315 : : #endif /* CONFIG_STATIC_INIT_GNU */
316 : :
317 : : /* Final init level before app starts */
318 : 1 : z_sys_init_run_level(INIT_LEVEL_APPLICATION);
319 : :
320 : 1 : z_init_static_threads();
321 : :
322 : : #ifdef CONFIG_KERNEL_COHERENCE
323 : : __ASSERT_NO_MSG(sys_cache_is_mem_coherent(&_kernel));
324 : : #endif /* CONFIG_KERNEL_COHERENCE */
325 : :
326 : : #ifdef CONFIG_SMP
327 : : if (!IS_ENABLED(CONFIG_SMP_BOOT_DELAY)) {
328 : : z_smp_init();
329 : : }
330 : : z_sys_init_run_level(INIT_LEVEL_SMP);
331 : : #endif /* CONFIG_SMP */
332 : :
333 : : #ifdef CONFIG_MMU
334 : : z_mem_manage_boot_finish();
335 : : #endif /* CONFIG_MMU */
336 : :
337 : : #ifdef CONFIG_BOOTARGS
338 : : extern int main(int, char **);
339 : : extern char **prepare_main_args(int *argc);
340 : :
341 : : int argc = 0;
342 : : char **argv = prepare_main_args(&argc);
343 : : (void)main(argc, argv);
344 : : #else
345 : 1 : extern int main(void);
346 : :
347 : 1 : (void)main();
348 : : #endif /* CONFIG_BOOTARGS */
349 : :
350 : : /* Mark non-essential since main() has no more work to do */
351 : 0 : z_thread_essential_clear(&z_main_thread);
352 : :
353 : : #ifdef CONFIG_COVERAGE_DUMP
354 : : /* Dump coverage data once the main() has exited. */
355 : : gcov_coverage_dump();
356 : : #elif defined(CONFIG_COVERAGE_SEMIHOST)
357 : : gcov_coverage_semihost();
358 : : #endif /* CONFIG_COVERAGE_DUMP */
359 : : } /* LCOV_EXCL_LINE ... because we just dumped final coverage data */
360 : :
361 : : #if defined(CONFIG_MULTITHREADING)
362 : : __boot_func
363 : 1 : static void init_idle_thread(int i)
364 : : {
365 : 1 : struct k_thread *thread = &z_idle_threads[i];
366 : 1 : k_thread_stack_t *stack = z_idle_stacks[i];
367 : 1 : size_t stack_size = K_KERNEL_STACK_SIZEOF(z_idle_stacks[i]);
368 : :
369 : : #ifdef CONFIG_THREAD_NAME
370 : :
371 : : #if CONFIG_MP_MAX_NUM_CPUS > 1
372 : : char tname[8];
373 : : snprintk(tname, 8, "idle %02d", i);
374 : : #else
375 : 1 : char *tname = "idle";
376 : : #endif /* CONFIG_MP_MAX_NUM_CPUS */
377 : :
378 : : #else
379 : : char *tname = NULL;
380 : : #endif /* CONFIG_THREAD_NAME */
381 : :
382 : 1 : z_setup_new_thread(thread, stack,
383 : 1 : stack_size, idle, &_kernel.cpus[i],
384 : : NULL, NULL, K_IDLE_PRIO, K_ESSENTIAL,
385 : : tname);
386 : 1 : z_mark_thread_as_not_sleeping(thread);
387 : :
388 : : #ifdef CONFIG_SMP
389 : : thread->base.is_idle = 1U;
390 : : #endif /* CONFIG_SMP */
391 : 1 : }
392 : :
393 : 1 : void z_init_cpu(int id)
394 : : {
395 : 1 : init_idle_thread(id);
396 : 1 : _kernel.cpus[id].idle_thread = &z_idle_threads[id];
397 : 1 : _kernel.cpus[id].id = id;
398 : 1 : _kernel.cpus[id].irq_stack =
399 : 1 : (K_KERNEL_STACK_BUFFER(z_interrupt_stacks[id]) +
400 : : K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[id]));
401 : : #ifdef CONFIG_SCHED_THREAD_USAGE_ALL
402 : : _kernel.cpus[id].usage = &_kernel.usage[id];
403 : : _kernel.cpus[id].usage->track_usage =
404 : : CONFIG_SCHED_THREAD_USAGE_AUTO_ENABLE;
405 : : #endif
406 : :
407 : : #ifdef CONFIG_PM
408 : : /*
409 : : * Increment number of CPUs active. The pm subsystem
410 : : * will keep track of this from here.
411 : : */
412 : : atomic_inc(&_cpus_active);
413 : : #endif
414 : :
415 : : #ifdef CONFIG_OBJ_CORE_SYSTEM
416 : : k_obj_core_init_and_link(K_OBJ_CORE(&_kernel.cpus[id]), &obj_type_cpu);
417 : : #ifdef CONFIG_OBJ_CORE_STATS_SYSTEM
418 : : k_obj_core_stats_register(K_OBJ_CORE(&_kernel.cpus[id]),
419 : : _kernel.cpus[id].usage,
420 : : sizeof(struct k_cycle_stats));
421 : : #endif
422 : : #endif
423 : :
424 : : #ifdef CONFIG_SCHED_IPI_SUPPORTED
425 : : sys_dlist_init(&_kernel.cpus[id].ipi_workq);
426 : : #endif
427 : 1 : }
428 : :
429 : : /**
430 : : *
431 : : * @brief Initializes kernel data structures
432 : : *
433 : : * This routine initializes various kernel data structures, including
434 : : * the init and idle threads and any architecture-specific initialization.
435 : : *
436 : : * Note that all fields of "_kernel" are set to zero on entry, which may
437 : : * be all the initialization many of them require.
438 : : *
439 : : * @return initial stack pointer for the main thread
440 : : */
441 : : __boot_func
442 : 1 : static char *prepare_multithreading(void)
443 : : {
444 : 1 : char *stack_ptr;
445 : :
446 : : /* _kernel.ready_q is all zeroes */
447 : 1 : z_sched_init();
448 : :
449 : : #ifndef CONFIG_SMP
450 : : /*
451 : : * prime the cache with the main thread since:
452 : : *
453 : : * - the cache can never be NULL
454 : : * - the main thread will be the one to run first
455 : : * - no other thread is initialized yet and thus their priority fields
456 : : * contain garbage, which would prevent the cache loading algorithm
457 : : * to work as intended
458 : : */
459 : 1 : _kernel.ready_q.cache = &z_main_thread;
460 : : #endif /* CONFIG_SMP */
461 : 1 : stack_ptr = z_setup_new_thread(&z_main_thread, z_main_stack,
462 : : K_THREAD_STACK_SIZEOF(z_main_stack),
463 : : bg_thread_main,
464 : : NULL, NULL, NULL,
465 : : CONFIG_MAIN_THREAD_PRIORITY,
466 : : K_ESSENTIAL, "main");
467 : 1 : z_mark_thread_as_not_sleeping(&z_main_thread);
468 : 1 : z_ready_thread(&z_main_thread);
469 : :
470 : 1 : z_init_cpu(0);
471 : :
472 : 1 : return stack_ptr;
473 : : }
474 : :
475 : : __boot_func
476 : 1 : static FUNC_NORETURN void switch_to_main_thread(char *stack_ptr)
477 : : {
478 : : #ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
479 : 1 : arch_switch_to_main_thread(&z_main_thread, stack_ptr, bg_thread_main);
480 : : #else
481 : : ARG_UNUSED(stack_ptr);
482 : : /*
483 : : * Context switch to main task (entry function is _main()): the
484 : : * current fake thread is not on a wait queue or ready queue, so it
485 : : * will never be rescheduled in.
486 : : */
487 : : z_swap_unlocked();
488 : : #endif /* CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN */
489 : : CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
490 : : }
491 : : #endif /* CONFIG_MULTITHREADING */
492 : :
493 : : __boot_func
494 : 0 : void __weak z_early_rand_get(uint8_t *buf, size_t length)
495 : : {
496 : 0 : static uint64_t state = (uint64_t)CONFIG_TIMER_RANDOM_INITIAL_STATE;
497 : 0 : int rc;
498 : :
499 : : #ifdef CONFIG_ENTROPY_HAS_DRIVER
500 : : const struct device *const entropy = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy));
501 : :
502 : : if ((entropy != NULL) && device_is_ready(entropy)) {
503 : : /* Try to see if driver provides an ISR-specific API */
504 : : rc = entropy_get_entropy_isr(entropy, buf, length, ENTROPY_BUSYWAIT);
505 : : if (rc > 0) {
506 : : length -= rc;
507 : : buf += rc;
508 : : }
509 : : }
510 : : #endif /* CONFIG_ENTROPY_HAS_DRIVER */
511 : :
512 [ # # ]: 0 : while (length > 0) {
513 : 0 : uint32_t val;
514 : :
515 : 0 : state = state + k_cycle_get_32();
516 : 0 : state = state * 2862933555777941757ULL + 3037000493ULL;
517 : 0 : val = (uint32_t)(state >> 32);
518 : 0 : rc = min(length, sizeof(val));
519 : 0 : arch_early_memcpy((void *)buf, &val, rc);
520 : :
521 : 0 : length -= rc;
522 : 0 : buf += rc;
523 : : }
524 : 0 : }
525 : :
526 : : /**
527 : : *
528 : : * @brief Initialize kernel
529 : : *
530 : : * This routine is invoked when the system is ready to run C code. The
531 : : * processor must be running in 32-bit mode, and the BSS must have been
532 : : * cleared/zeroed.
533 : : *
534 : : * @return Does not return
535 : : */
536 : : __boot_func
537 : : FUNC_NO_STACK_PROTECTOR
538 : 1 : FUNC_NORETURN void z_cstart(void)
539 : : {
540 : : /* gcov hook needed to get the coverage report.*/
541 : 1 : gcov_static_init();
542 : :
543 : : /* initialize early init calls */
544 : 1 : z_sys_init_run_level(INIT_LEVEL_EARLY);
545 : :
546 : : /* perform any architecture-specific initialization */
547 : 1 : arch_kernel_init();
548 : :
549 : 1 : LOG_CORE_INIT();
550 : :
551 : : #if defined(CONFIG_MULTITHREADING)
552 : 1 : z_dummy_thread_init(&_thread_dummy);
553 : : #endif /* CONFIG_MULTITHREADING */
554 : : /* do any necessary initialization of static devices */
555 : 1 : z_device_state_init();
556 : :
557 : 1 : soc_early_init_hook();
558 : :
559 : 1 : board_early_init_hook();
560 : :
561 : : /* perform basic hardware initialization */
562 : 1 : z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_1);
563 : : #if defined(CONFIG_SMP)
564 : : arch_smp_init();
565 : : #endif
566 : 1 : z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2);
567 : :
568 : : #ifdef CONFIG_REQUIRES_STACK_CANARIES
569 : : uintptr_t stack_guard;
570 : :
571 : : z_early_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard));
572 : : __stack_chk_guard = stack_guard;
573 : : __stack_chk_guard <<= 8;
574 : : #endif /* CONFIG_REQUIRES_STACK_CANARIES */
575 : :
576 : : #ifdef CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT
577 : : timing_init();
578 : : timing_start();
579 : : #endif /* CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT */
580 : :
581 : : #ifdef CONFIG_MULTITHREADING
582 : 1 : switch_to_main_thread(prepare_multithreading());
583 : : #else
584 : : #ifdef ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING
585 : : /* Custom ARCH-specific routine to switch to main()
586 : : * in the case of no multi-threading.
587 : : */
588 : : ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING(bg_thread_main,
589 : : NULL, NULL, NULL);
590 : : #else
591 : : bg_thread_main(NULL, NULL, NULL);
592 : :
593 : : /* LCOV_EXCL_START
594 : : * We've already dumped coverage data at this point.
595 : : */
596 : : irq_lock();
597 : : while (true) {
598 : : }
599 : : /* LCOV_EXCL_STOP */
600 : : #endif /* ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING */
601 : : #endif /* CONFIG_MULTITHREADING */
602 : :
603 : : /*
604 : : * Compiler can't tell that the above routines won't return and issues
605 : : * a warning unless we explicitly tell it that control never gets this
606 : : * far.
607 : : */
608 : :
609 : : CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
610 : : }
611 : :
612 : : #ifdef CONFIG_OBJ_CORE_SYSTEM
613 : : static int init_cpu_obj_core_list(void)
614 : : {
615 : : /* Initialize CPU object type */
616 : :
617 : : z_obj_type_init(&obj_type_cpu, K_OBJ_TYPE_CPU_ID,
618 : : offsetof(struct _cpu, obj_core));
619 : :
620 : : #ifdef CONFIG_OBJ_CORE_STATS_SYSTEM
621 : : k_obj_type_stats_init(&obj_type_cpu, &cpu_stats_desc);
622 : : #endif /* CONFIG_OBJ_CORE_STATS_SYSTEM */
623 : :
624 : : return 0;
625 : : }
626 : :
627 : : static int init_kernel_obj_core_list(void)
628 : : {
629 : : /* Initialize kernel object type */
630 : :
631 : : z_obj_type_init(&obj_type_kernel, K_OBJ_TYPE_KERNEL_ID,
632 : : offsetof(struct z_kernel, obj_core));
633 : :
634 : : #ifdef CONFIG_OBJ_CORE_STATS_SYSTEM
635 : : k_obj_type_stats_init(&obj_type_kernel, &kernel_stats_desc);
636 : : #endif /* CONFIG_OBJ_CORE_STATS_SYSTEM */
637 : :
638 : : k_obj_core_init_and_link(K_OBJ_CORE(&_kernel), &obj_type_kernel);
639 : : #ifdef CONFIG_OBJ_CORE_STATS_SYSTEM
640 : : k_obj_core_stats_register(K_OBJ_CORE(&_kernel), _kernel.usage,
641 : : sizeof(_kernel.usage));
642 : : #endif /* CONFIG_OBJ_CORE_STATS_SYSTEM */
643 : :
644 : : return 0;
645 : : }
646 : :
647 : : SYS_INIT(init_cpu_obj_core_list, PRE_KERNEL_1,
648 : : CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
649 : :
650 : : SYS_INIT(init_kernel_obj_core_list, PRE_KERNEL_1,
651 : : CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
652 : : #endif /* CONFIG_OBJ_CORE_SYSTEM */
|