xref: /optee_os/core/arch/riscv/kernel/boot.c (revision 4edd96e6d7a7228e907cf498b23e5b5fbdaf39a0)
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 	if (mark_tddram_as_reserved(dt))
51 		panic("Failed to config secure memory");
52 }
53 #else /*CFG_DT*/
54 static void update_external_dt(void)
55 {
56 }
57 #endif /*!CFG_DT*/
58 
59 void init_sec_mon(unsigned long nsec_entry __maybe_unused)
60 {
61 	assert(nsec_entry == PADDR_INVALID);
62 	/* Do nothing as we don't have a secure monitor */
63 }
64 
65 #ifdef CFG_RISCV_S_MODE
66 static void start_secondary_cores(void)
67 {
68 	size_t i = 0;
69 	size_t pos = get_core_pos();
70 
71 	for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++)
72 		if (i != pos && IS_ENABLED(CFG_RISCV_SBI) &&
73 		    sbi_boot_hart(i, start_addr, i))
74 			EMSG("Error starting secondary hart %zu", i);
75 }
76 #endif
77 
78 static void init_runtime(void)
79 {
80 	malloc_add_pool(__heap1_start, __heap1_end - __heap1_start);
81 
82 	IMSG_RAW("\n");
83 }
84 
85 void init_tee_runtime(void)
86 {
87 	core_mmu_init_ta_ram();
88 	call_preinitcalls();
89 	call_initcalls();
90 }
91 
92 static void init_primary(unsigned long nsec_entry)
93 {
94 	thread_init_core_local_stacks();
95 
96 	/*
97 	 * Mask asynchronous exceptions before switch to the thread vector
98 	 * as the thread handler requires those to be masked while
99 	 * executing with the temporary stack. The thread subsystem also
100 	 * asserts that the foreign interrupts are blocked when using most of
101 	 * its functions.
102 	 */
103 	thread_set_exceptions(THREAD_EXCP_ALL);
104 
105 	init_runtime();
106 	thread_init_boot_thread();
107 	thread_init_primary();
108 	thread_init_per_cpu();
109 	init_sec_mon(nsec_entry);
110 }
111 
112 /* May be overridden in plat-$(PLATFORM)/main.c */
113 __weak void plat_primary_init_early(void)
114 {
115 }
116 
117 /* May be overridden in plat-$(PLATFORM)/main.c */
118 __weak void boot_primary_init_intc(void)
119 {
120 }
121 
122 /* May be overridden in plat-$(PLATFORM)/main.c */
123 __weak void boot_secondary_init_intc(void)
124 {
125 }
126 
127 void boot_init_primary_early(unsigned long pageable_part __unused,
128 			     unsigned long nsec_entry __unused)
129 {
130 	unsigned long e = PADDR_INVALID;
131 
132 	init_primary(e);
133 }
134 
135 void boot_init_primary_late(unsigned long fdt,
136 			    unsigned long tos_fw_config __unused)
137 {
138 	init_external_dt(fdt);
139 	update_external_dt();
140 
141 	IMSG("OP-TEE version: %s", core_v_str);
142 	if (IS_ENABLED(CFG_WARN_INSECURE)) {
143 		IMSG("WARNING: This OP-TEE configuration might be insecure!");
144 		IMSG("WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html");
145 	}
146 	IMSG("Primary CPU initializing");
147 	boot_primary_init_intc();
148 	init_tee_runtime();
149 	call_finalcalls();
150 	IMSG("Primary CPU initialized");
151 
152 #ifdef CFG_RISCV_S_MODE
153 	start_secondary_cores();
154 #endif
155 }
156 
157 static void init_secondary_helper(unsigned long nsec_entry)
158 {
159 	size_t pos = get_core_pos();
160 
161 	IMSG("Secondary CPU %zu initializing", pos);
162 
163 	/*
164 	 * Mask asynchronous exceptions before switch to the thread vector
165 	 * as the thread handler requires those to be masked while
166 	 * executing with the temporary stack. The thread subsystem also
167 	 * asserts that the foreign interrupts are blocked when using most of
168 	 * its functions.
169 	 */
170 	thread_set_exceptions(THREAD_EXCP_ALL);
171 
172 	thread_init_per_cpu();
173 	init_sec_mon(nsec_entry);
174 	boot_secondary_init_intc();
175 
176 	IMSG("Secondary CPU %zu initialized", pos);
177 }
178 
179 void boot_init_secondary(unsigned long nsec_entry __unused)
180 {
181 	init_secondary_helper(PADDR_INVALID);
182 }
183