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