xref: /optee_os/core/arch/riscv/kernel/boot.c (revision 45fecab081173ef58b1cb14b6ddf6892b0b9d3f6)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2023 Andes Technology Corporation
4  * Copyright 2022-2023 NXP
5  */
6 
7 #include <assert.h>
8 #include <compiler.h>
9 #include <config.h>
10 #include <console.h>
11 #include <keep.h>
12 #include <kernel/boot.h>
13 #include <kernel/dt.h>
14 #include <kernel/linker.h>
15 #include <kernel/misc.h>
16 #include <kernel/panic.h>
17 #include <kernel/thread.h>
18 #include <mm/core_memprot.h>
19 #include <mm/core_mmu.h>
20 #include <mm/tee_mm.h>
21 #include <mm/tee_pager.h>
22 #include <platform_config.h>
23 #include <riscv.h>
24 #include <sbi.h>
25 #include <stdio.h>
26 #include <trace.h>
27 #include <util.h>
28 
29 #define PADDR_INVALID               ULONG_MAX
30 
31 paddr_t start_addr;
32 unsigned long boot_args[4];
33 
34 uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE];
35 
36 #if defined(CFG_DT)
37 static int mark_tddram_as_reserved(struct dt_descriptor *dt)
38 {
39 	return add_res_mem_dt_node(dt, "optee_core", CFG_TDDRAM_START,
40 				   CFG_TDDRAM_SIZE);
41 }
42 
43 static void update_external_dt(void)
44 {
45 	struct dt_descriptor *dt = get_external_dt_desc();
46 
47 	if (!dt || !dt->blob)
48 		return;
49 
50 #ifdef CFG_CORE_RESERVED_SHM
51 	if (mark_static_shm_as_reserved(dt))
52 		panic("Failed to config non-secure memory");
53 #endif
54 
55 	if (mark_tddram_as_reserved(dt))
56 		panic("Failed to config secure memory");
57 }
58 #else /*CFG_DT*/
59 static void update_external_dt(void)
60 {
61 }
62 #endif /*!CFG_DT*/
63 
64 void init_sec_mon(unsigned long nsec_entry __maybe_unused)
65 {
66 	assert(nsec_entry == PADDR_INVALID);
67 	/* Do nothing as we don't have a secure monitor */
68 }
69 
70 #ifdef CFG_RISCV_S_MODE
71 static void start_secondary_cores(void)
72 {
73 	size_t i = 0;
74 	size_t pos = get_core_pos();
75 
76 	for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
77 		if (i != pos && IS_ENABLED(CFG_RISCV_SBI) &&
78 		    sbi_hsm_hart_start(i, start_addr, i))
79 			EMSG("Error starting secondary hart %zu", i);
80 }
81 #endif
82 
83 void init_tee_runtime(void)
84 {
85 	call_preinitcalls();
86 	call_early_initcalls();
87 	call_service_initcalls();
88 }
89 
90 static bool add_padding_to_pool(vaddr_t va, size_t len, void *ptr __unused)
91 {
92 	malloc_add_pool((void *)va, len);
93 	return true;
94 }
95 
96 static void init_primary(unsigned long nsec_entry)
97 {
98 	vaddr_t va __maybe_unused = 0;
99 
100 	thread_init_core_local_stacks();
101 
102 	/*
103 	 * Mask asynchronous exceptions before switch to the thread vector
104 	 * as the thread handler requires those to be masked while
105 	 * executing with the temporary stack. The thread subsystem also
106 	 * asserts that the foreign interrupts are blocked when using most of
107 	 * its functions.
108 	 */
109 	thread_set_exceptions(THREAD_EXCP_ALL);
110 
111 	malloc_add_pool(__heap1_start, __heap1_end - __heap1_start);
112 	IMSG_RAW("\n");
113 
114 	core_mmu_save_mem_map();
115 	core_mmu_init_phys_mem();
116 	boot_mem_foreach_padding(add_padding_to_pool, NULL);
117 	va = boot_mem_release_unused();
118 
119 	thread_init_boot_thread();
120 	thread_init_primary();
121 	thread_init_per_cpu();
122 	init_sec_mon(nsec_entry);
123 }
124 
125 /* May be overridden in plat-$(PLATFORM)/main.c */
126 __weak void plat_primary_init_early(void)
127 {
128 }
129 
130 /* May be overridden in plat-$(PLATFORM)/main.c */
131 __weak void boot_primary_init_intc(void)
132 {
133 }
134 
135 /* May be overridden in plat-$(PLATFORM)/main.c */
136 __weak void boot_secondary_init_intc(void)
137 {
138 }
139 
140 void boot_init_primary_early(void)
141 {
142 	unsigned long e = PADDR_INVALID;
143 
144 	init_primary(e);
145 }
146 
147 void boot_init_primary_late(unsigned long fdt,
148 			    unsigned long tos_fw_config __unused)
149 {
150 	init_external_dt(fdt, CFG_DTB_MAX_SIZE);
151 	discover_nsec_memory();
152 	update_external_dt();
153 
154 	IMSG("OP-TEE version: %s", core_v_str);
155 	if (IS_ENABLED(CFG_INSECURE)) {
156 		IMSG("WARNING: This OP-TEE configuration might be insecure!");
157 		IMSG("WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html");
158 	}
159 	IMSG("Primary CPU initializing");
160 	boot_primary_init_intc();
161 	init_tee_runtime();
162 }
163 
164 void __weak boot_init_primary_final(void)
165 {
166 	boot_mem_release_tmp_alloc();
167 
168 	call_driver_initcalls();
169 	call_finalcalls();
170 	IMSG("Primary CPU initialized");
171 
172 #ifdef CFG_RISCV_S_MODE
173 	start_secondary_cores();
174 #endif
175 }
176 
177 static void init_secondary_helper(unsigned long nsec_entry)
178 {
179 	size_t pos = get_core_pos();
180 
181 	IMSG("Secondary CPU %zu initializing", pos);
182 
183 	/*
184 	 * Mask asynchronous exceptions before switch to the thread vector
185 	 * as the thread handler requires those to be masked while
186 	 * executing with the temporary stack. The thread subsystem also
187 	 * asserts that the foreign interrupts are blocked when using most of
188 	 * its functions.
189 	 */
190 	thread_set_exceptions(THREAD_EXCP_ALL);
191 
192 	thread_init_per_cpu();
193 	init_sec_mon(nsec_entry);
194 	boot_secondary_init_intc();
195 
196 	IMSG("Secondary CPU %zu initialized", pos);
197 }
198 
199 void boot_init_secondary(unsigned long nsec_entry __unused)
200 {
201 	init_secondary_helper(PADDR_INVALID);
202 }
203