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