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 
13 extern FUNC_NORETURN void z_cstart(void);
14 extern void x86_64_irq_init(void);
15 
16 #if !defined(CONFIG_X86_64)
17 __pinned_data x86_boot_arg_t x86_cpu_boot_arg;
18 #endif
19 
20 /* Early global initialization functions, C domain. This runs only on the first
21  * CPU for SMP systems.
22  */
23 __boot_func
z_prep_c(void * arg)24 FUNC_NORETURN void z_prep_c(void *arg)
25 {
26 	x86_boot_arg_t *cpu_arg = arg;
27 
28 	_kernel.cpus[0].nested = 0;
29 
30 #ifdef CONFIG_MMU
31 	z_x86_mmu_init();
32 #endif
33 
34 #if defined(CONFIG_LOAPIC)
35 	z_loapic_enable(0);
36 #endif
37 
38 #ifdef CONFIG_X86_64
39 	x86_64_irq_init();
40 #endif
41 
42 	if (IS_ENABLED(CONFIG_MULTIBOOT_INFO) &&
43 		cpu_arg->boot_type == MULTIBOOT_BOOT_TYPE) {
44 		z_multiboot_init((struct multiboot_info *)cpu_arg->arg);
45 	} else if (IS_ENABLED(CONFIG_X86_EFI) &&
46 		cpu_arg->boot_type == EFI_BOOT_TYPE) {
47 		efi_init((struct efi_boot_arg *)cpu_arg->arg);
48 	} else {
49 		ARG_UNUSED(cpu_arg);
50 	}
51 
52 #ifdef CONFIG_X86_VERY_EARLY_CONSOLE
53 	z_x86_early_serial_init();
54 
55 #if defined(CONFIG_BOARD_QEMU_X86) || defined(CONFIG_BOARD_QEMU_X86_64)
56 	/*
57 	 * Under QEMU and SeaBIOS, everything gets to be printed
58 	 * immediately after "Booting from ROM.." as there is no newline.
59 	 * This prevents parsing QEMU console output for the very first
60 	 * line where it needs to match from the beginning of the line.
61 	 * So add a dummy newline here so the next output is at
62 	 * the beginning of a line.
63 	 */
64 	arch_printk_char_out('\n');
65 #endif
66 #endif
67 
68 #ifdef CONFIG_X86_STACK_PROTECTION
69 	unsigned int num_cpus = arch_num_cpus();
70 
71 	for (int i = 0; i < num_cpus; i++) {
72 		z_x86_set_stack_guard(z_interrupt_stacks[i]);
73 	}
74 #endif
75 
76 	z_cstart();
77 	CODE_UNREACHABLE;
78 }
79