1 /*
2  * Copyright (c) 2019 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <kernel_internal.h>
9 #include <zephyr/arch/x86/multiboot.h>
10 #include <zephyr/arch/x86/efi.h>
11 #include <x86_mmu.h>
12 #include <zephyr/platform/hooks.h>
13 #include <zephyr/arch/cache.h>
14 
15 extern FUNC_NORETURN void z_cstart(void);
16 extern void x86_64_irq_init(void);
17 
18 #if !defined(CONFIG_X86_64)
19 __pinned_data x86_boot_arg_t x86_cpu_boot_arg;
20 #endif
21 
22 
23 
24 extern int spec_ctrl_init(void);
25 
26 /* Early global initialization functions, C domain. This runs only on the first
27  * CPU for SMP systems.
28  */
29 __boot_func
z_prep_c(void * arg)30 FUNC_NORETURN void z_prep_c(void *arg)
31 {
32 	x86_boot_arg_t *cpu_arg = arg;
33 
34 #if defined(CONFIG_SOC_PREP_HOOK)
35 	soc_prep_hook();
36 #endif
37 	_kernel.cpus[0].nested = 0;
38 
39 #ifdef CONFIG_MMU
40 	z_x86_mmu_init();
41 #endif
42 
43 #if defined(CONFIG_LOAPIC)
44 	z_loapic_enable(0);
45 #endif
46 
47 #ifdef CONFIG_X86_64
48 	x86_64_irq_init();
49 #endif
50 
51 	if (IS_ENABLED(CONFIG_MULTIBOOT_INFO) &&
52 		cpu_arg->boot_type == MULTIBOOT_BOOT_TYPE) {
53 		z_multiboot_init((struct multiboot_info *)cpu_arg->arg);
54 	} else if (IS_ENABLED(CONFIG_X86_EFI) &&
55 		cpu_arg->boot_type == EFI_BOOT_TYPE) {
56 		efi_init((struct efi_boot_arg *)cpu_arg->arg);
57 	} else {
58 		ARG_UNUSED(cpu_arg);
59 	}
60 
61 #ifdef CONFIG_X86_VERY_EARLY_CONSOLE
62 	z_x86_early_serial_init();
63 
64 #if defined(CONFIG_BOARD_QEMU_X86) || defined(CONFIG_BOARD_QEMU_X86_64)
65 	/*
66 	 * Under QEMU and SeaBIOS, everything gets to be printed
67 	 * immediately after "Booting from ROM.." as there is no newline.
68 	 * This prevents parsing QEMU console output for the very first
69 	 * line where it needs to match from the beginning of the line.
70 	 * So add a dummy newline here so the next output is at
71 	 * the beginning of a line.
72 	 */
73 	arch_printk_char_out('\n');
74 #endif
75 #endif
76 
77 #ifdef CONFIG_X86_STACK_PROTECTION
78 	unsigned int num_cpus = arch_num_cpus();
79 
80 	for (int i = 0; i < num_cpus; i++) {
81 		z_x86_set_stack_guard(z_interrupt_stacks[i]);
82 	}
83 #endif
84 #if CONFIG_ARCH_CACHE
85 	arch_cache_init();
86 #endif
87 #if defined(CONFIG_X86_DISABLE_SSBD) || defined(CONFIG_X86_ENABLE_EXTENDED_IBRS)
88 	spec_ctrl_init();
89 #endif
90 
91 	z_cstart();
92 	CODE_UNREACHABLE;
93 }
94