xref: /optee_os/core/arch/riscv/kernel/boot.c (revision 12fc37711783247b0d05fdc271ef007f4930767b)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022-2023 NXP
4  */
5 
6 #include <assert.h>
7 #include <compiler.h>
8 #include <config.h>
9 #include <console.h>
10 #include <keep.h>
11 #include <kernel/boot.h>
12 #include <kernel/linker.h>
13 #include <kernel/misc.h>
14 #include <kernel/panic.h>
15 #include <kernel/thread.h>
16 #include <mm/core_memprot.h>
17 #include <mm/core_mmu.h>
18 #include <mm/tee_mm.h>
19 #include <mm/tee_pager.h>
20 #include <platform_config.h>
21 #include <riscv.h>
22 #include <sbi.h>
23 #include <stdio.h>
24 #include <trace.h>
25 #include <util.h>
26 
27 #define PADDR_INVALID               ULONG_MAX
28 
29 paddr_t start_addr;
30 unsigned long boot_args[4];
31 
32 uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE];
33 
34 void init_sec_mon(unsigned long nsec_entry __maybe_unused)
35 {
36 	assert(nsec_entry == PADDR_INVALID);
37 	/* Do nothing as we don't have a secure monitor */
38 }
39 
40 #ifdef CFG_RISCV_S_MODE
41 static void start_secondary_cores(void)
42 {
43 	size_t i = 0;
44 	size_t pos = get_core_pos();
45 
46 	for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
47 		if (i != pos && IS_ENABLED(CFG_RISCV_SBI) &&
48 		    sbi_boot_hart(i, start_addr, i))
49 			EMSG("Error starting secondary hart %zu", i);
50 }
51 #endif
52 
53 static void init_runtime(void)
54 {
55 	malloc_add_pool(__heap1_start, __heap1_end - __heap1_start);
56 
57 	IMSG_RAW("\n");
58 }
59 
60 void init_tee_runtime(void)
61 {
62 	core_mmu_init_ta_ram();
63 	call_preinitcalls();
64 	call_initcalls();
65 }
66 
67 static void init_primary(unsigned long nsec_entry)
68 {
69 	thread_init_core_local_stacks();
70 
71 	/*
72 	 * Mask asynchronous exceptions before switch to the thread vector
73 	 * as the thread handler requires those to be masked while
74 	 * executing with the temporary stack. The thread subsystem also
75 	 * asserts that the foreign interrupts are blocked when using most of
76 	 * its functions.
77 	 */
78 	thread_set_exceptions(THREAD_EXCP_ALL);
79 
80 	init_runtime();
81 	thread_init_boot_thread();
82 	thread_init_primary();
83 	thread_init_per_cpu();
84 	init_sec_mon(nsec_entry);
85 }
86 
87 /* May be overridden in plat-$(PLATFORM)/main.c */
88 __weak void plat_primary_init_early(void)
89 {
90 }
91 
92 /* May be overridden in plat-$(PLATFORM)/main.c */
93 __weak void main_init_plic(void)
94 {
95 }
96 
97 /* May be overridden in plat-$(PLATFORM)/main.c */
98 __weak void main_secondary_init_plic(void)
99 {
100 }
101 
102 void boot_init_primary_early(unsigned long pageable_part __unused,
103 			     unsigned long nsec_entry __unused)
104 {
105 	unsigned long e = PADDR_INVALID;
106 
107 	init_primary(e);
108 }
109 
110 void boot_init_primary_late(unsigned long fdt __unused,
111 			    unsigned long tos_fw_config __unused)
112 {
113 	IMSG("OP-TEE version: %s", core_v_str);
114 	if (IS_ENABLED(CFG_WARN_INSECURE)) {
115 		IMSG("WARNING: This OP-TEE configuration might be insecure!");
116 		IMSG("WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html");
117 	}
118 	IMSG("Primary CPU initializing");
119 	main_init_plic();
120 	init_tee_runtime();
121 	call_finalcalls();
122 	IMSG("Primary CPU initialized");
123 
124 #ifdef CFG_RISCV_S_MODE
125 	start_secondary_cores();
126 #endif
127 }
128 
129 static void init_secondary_helper(unsigned long nsec_entry)
130 {
131 	size_t pos = get_core_pos();
132 
133 	IMSG("Secondary CPU %zu initializing", pos);
134 
135 	/*
136 	 * Mask asynchronous exceptions before switch to the thread vector
137 	 * as the thread handler requires those to be masked while
138 	 * executing with the temporary stack. The thread subsystem also
139 	 * asserts that the foreign interrupts are blocked when using most of
140 	 * its functions.
141 	 */
142 	thread_set_exceptions(THREAD_EXCP_ALL);
143 
144 	thread_init_per_cpu();
145 	init_sec_mon(nsec_entry);
146 	main_secondary_init_plic();
147 
148 	IMSG("Secondary CPU %zu initialized", pos);
149 }
150 
151 void boot_init_secondary(unsigned long nsec_entry __unused)
152 {
153 	init_secondary_helper(PADDR_INVALID);
154 }
155