1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <types.h>
8 #include <asm/init.h>
9 #include <console.h>
10 #include <asm/per_cpu.h>
11 #include <shell.h>
12 #include <asm/vmx.h>
13 #include <asm/guest/vm.h>
14 #include <logmsg.h>
15 #include <asm/seed.h>
16 #include <asm/boot/ld_sym.h>
17 #include <boot.h>
18 
19 /* boot_regs store the multiboot info magic and address, defined in
20    arch/x86/boot/cpu_primary.S.
21    */
22 extern uint32_t boot_regs[2];
23 
24 /* Push sp magic to top of stack for call trace */
25 #define SWITCH_TO(rsp, to)                                              \
26 {                                                                       \
27 	asm volatile ("movq %0, %%rsp\n"                                \
28 			"pushq %1\n"                                    \
29 			"jmpq *%2\n"                                    \
30 			 :                                              \
31 			 : "r"(rsp), "rm"(SP_BOTTOM_MAGIC), "a"(to));   \
32 }
33 
34 /*TODO: move into debug module */
init_debug_pre(void)35 static void init_debug_pre(void)
36 {
37 	/* Initialize console */
38 	console_init();
39 
40 	/* Enable logging */
41 	init_logmsg();
42 }
43 
44 /*TODO: move into debug module */
init_debug_post(uint16_t pcpu_id)45 static void init_debug_post(uint16_t pcpu_id)
46 {
47 	if (pcpu_id == BSP_CPU_ID) {
48 		/* Initialize the shell */
49 		shell_init();
50 	}
51 
52 	if (pcpu_id == VUART_TIMER_CPU) {
53 		console_setup_timer();
54 	}
55 
56 	profiling_setup();
57 }
58 
59 /*TODO: move into guest-vcpu module */
init_guest_mode(uint16_t pcpu_id)60 static void init_guest_mode(uint16_t pcpu_id)
61 {
62 	vmx_on();
63 
64 	launch_vms(pcpu_id);
65 }
66 
init_pcpu_comm_post(void)67 static void init_pcpu_comm_post(void)
68 {
69 	uint16_t pcpu_id;
70 
71 	pcpu_id = get_pcpu_id();
72 
73 	init_pcpu_post(pcpu_id);
74 	init_debug_post(pcpu_id);
75 	init_guest_mode(pcpu_id);
76 	run_idle_thread();
77 }
78 
init_misc(void)79 static void init_misc(void)
80 {
81 	init_cr0_cr4_flexible_bits();
82 	if (!sanitize_cr0_cr4_pattern()) {
83 		panic("%s Sanitize pattern of CR0 or CR4 failed.\n", __func__);
84 	}
85 }
86 
87 /* NOTE: this function is using temp stack, and after SWITCH_TO(runtime_sp, to)
88  * it will switch to runtime stack.
89  */
init_primary_pcpu(void)90 void init_primary_pcpu(void)
91 {
92 	uint64_t rsp;
93 
94 	/* Clear BSS */
95 	(void)memset(&ld_bss_start, 0U, (size_t)(&ld_bss_end - &ld_bss_start));
96 
97 	init_acrn_boot_info(boot_regs);
98 
99 	init_debug_pre();
100 
101 	if (sanitize_acrn_boot_info(get_acrn_boot_info()) != 0) {
102 		panic("Sanitize boot info failed!");
103 	}
104 
105 	init_pcpu_pre(true);
106 
107 	init_seed();
108 	init_misc();
109 
110 	/* Switch to run-time stack */
111 	rsp = (uint64_t)(&get_cpu_var(stack)[CONFIG_STACK_SIZE - 1]);
112 	rsp &= ~(CPU_STACK_ALIGN - 1UL);
113 	SWITCH_TO(rsp, init_pcpu_comm_post);
114 }
115 
init_secondary_pcpu(void)116 void init_secondary_pcpu(void)
117 {
118 	init_pcpu_pre(false);
119 	init_pcpu_comm_post();
120 }
121