xref: /optee_os/core/arch/arm/plat-stm/main.c (revision 5526b8c03ac27344f144c538b8a58d5f014c05de)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <stdint.h>
28 #include <string.h>
29 #include <sm/sm.h>
30 #include <sm/tee_mon.h>
31 #include <sm/teesmc.h>
32 #include <sm/teesmc_optee.h>
33 #include <arm.h>
34 #include <kernel/thread.h>
35 #include <kernel/panic.h>
36 #include <kernel/pm_stubs.h>
37 #include <malloc.h>
38 #include <util.h>
39 #include <trace.h>
40 #include <kernel/misc.h>
41 #include <mm/tee_pager.h>
42 #include <mm/core_mmu.h>
43 #include <mm/tee_mmu.h>
44 #include <mm/tee_mmu_defs.h>
45 #include <tee/entry.h>
46 #include <tee/arch_svc.h>
47 #include <console.h>
48 #include <asc.h>
49 #include <assert.h>
50 #include <platform_config.h>
51 
52 /* teecore heap address/size is defined in scatter file */
53 extern unsigned char teecore_heap_start;
54 extern unsigned char teecore_heap_end;
55 
56 
57 static void main_fiq(void);
58 static void main_tee_entry(struct thread_smc_args *args);
59 
60 static const struct thread_handlers handlers = {
61 	.std_smc = main_tee_entry,
62 	.fast_smc = main_tee_entry,
63 	.fiq = main_fiq,
64 	.svc = tee_svc_handler,
65 	.abort = tee_pager_abort_handler,
66 	.cpu_on = pm_panic,
67 	.cpu_off = pm_panic,
68 	.cpu_suspend = pm_panic,
69 	.cpu_resume = pm_panic,
70 	.system_off = pm_panic,
71 	.system_reset = pm_panic,
72 };
73 
74 #define PADDR_INVALID		0xffffffff
75 
76 /* May be overridden in plat-$(PLATFORM)/main.c */
77 void main_init_gic(void);
78 __weak void main_init_gic(void)
79 {
80 }
81 
82 #if defined(CFG_WITH_ARM_TRUSTED_FW)
83 static void init_sec_mon(uint32_t nsec_entry __unused)
84 {
85 	assert(nsec_entry == PADDR_INVALID);
86 	/* Do nothing as we don't have a secure monitor */
87 }
88 #else
89 static void init_sec_mon(uint32_t nsec_entry)
90 {
91 	struct sm_nsec_ctx *nsec_ctx;
92 
93 	assert(nsec_entry != PADDR_INVALID);
94 
95 	/* Initialize secure monitor */
96 	nsec_ctx = sm_get_nsec_ctx();
97 	nsec_ctx->mon_lr = nsec_entry;
98 	nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
99 
100 }
101 #endif
102 
103 #if defined(CFG_WITH_ARM_TRUSTED_FW)
104 static void init_nsacr(void)
105 {
106 }
107 #else
108 static void init_nsacr(void)
109 {
110 	/* Normal world can use CP10 and CP11 (SIMD/VFP) */
111 	write_nsacr(read_nsacr() | NSACR_CP10 | NSACR_CP11);
112 }
113 #endif
114 
115 #ifdef CFG_WITH_VFP
116 static void init_cpacr(void)
117 {
118 	uint32_t cpacr = read_cpacr();
119 
120 	/* Enabled usage of CP10 and CP11 (SIMD/VFP) */
121 	cpacr &= ~CPACR_CP(10, CPACR_CP_ACCESS_FULL);
122 	cpacr |= CPACR_CP(10, CPACR_CP_ACCESS_PL1_ONLY);
123 	cpacr &= ~CPACR_CP(11, CPACR_CP_ACCESS_FULL);
124 	cpacr |= CPACR_CP(11, CPACR_CP_ACCESS_PL1_ONLY);
125 	write_cpacr(cpacr);
126 }
127 #else
128 static void init_cpacr(void)
129 {
130 	/* We're not using VFP/SIMD instructions, leave it disabled */
131 }
132 #endif
133 
134 static void init_primary_helper(uint32_t nsec_entry)
135 {
136 	/*
137 	 * Mask asynchronous exceptions before switch to the thread vector
138 	 * as the thread handler requires those to be masked while
139 	 * executing with the temporary stack. The thread subsystem also
140 	 * asserts that IRQ is blocked when using most if its functions.
141 	 */
142 	thread_set_exceptions(THREAD_EXCP_ALL);
143 	init_cpacr();
144 
145 	/* init_runtime(pageable_part); */
146 
147 	DMSG("TEE initializing\n");
148 
149 	thread_init_primary(&handlers);
150 	thread_init_per_cpu();
151 	init_sec_mon(nsec_entry);
152 
153 
154 	main_init_gic();
155 	init_nsacr();
156 
157 	{
158 		unsigned long a, s;
159 		/* core malloc pool init */
160 #ifdef CFG_TEE_MALLOC_START
161 		a = CFG_TEE_MALLOC_START;
162 		s = CFG_TEE_MALLOC_SIZE;
163 #else
164 		a = (unsigned long)&teecore_heap_start;
165 		s = (unsigned long)&teecore_heap_end;
166 		a = ((a + 1) & ~0x0FFFF) + 0x10000;	/* 64kB aligned */
167 		s = s & ~0x0FFFF;	/* 64kB aligned */
168 		s = s - a;
169 #endif
170 		malloc_init((void *)a, s);
171 
172 		teecore_init_ta_ram();
173 	}
174 }
175 
176 static void init_secondary_helper(uint32_t nsec_entry)
177 {
178 	/*
179 	 * Mask asynchronous exceptions before switch to the thread vector
180 	 * as the thread handler requires those to be masked while
181 	 * executing with the temporary stack. The thread subsystem also
182 	 * asserts that IRQ is blocked when using most if its functions.
183 	 */
184 	thread_set_exceptions(THREAD_EXCP_ALL);
185 
186 	thread_init_per_cpu();
187 	init_sec_mon(nsec_entry);
188 	init_cpacr();
189 	init_nsacr();
190 
191 	DMSG("Secondary CPU Switching to normal world boot\n");
192 }
193 
194 #if defined(CFG_WITH_ARM_TRUSTED_FW)
195 uint32_t *generic_boot_init_primary(uint32_t pageable_part)
196 {
197 	init_primary_helper(pageable_part, PADDR_INVALID);
198 	return thread_vector_table;
199 }
200 
201 uint32_t generic_boot_cpu_on_handler(uint32_t a0 __unused, uint32_t a1 __unused)
202 {
203 	DMSG("cpu %zu: a0 0x%x", get_core_pos(), a0);
204 	init_secondary_helper(PADDR_INVALID);
205 	return 0;
206 }
207 #else
208 void generic_boot_init_primary(uint32_t nsec_entry);
209 void generic_boot_init_primary(uint32_t nsec_entry)
210 {
211 	init_primary_helper(nsec_entry);
212 }
213 
214 void generic_boot_init_secondary(uint32_t nsec_entry);
215 void generic_boot_init_secondary(uint32_t nsec_entry)
216 {
217 	init_secondary_helper(nsec_entry);
218 }
219 #endif
220 
221 static void main_fiq(void)
222 {
223 	panic();
224 }
225 
226 static void main_tee_entry(struct thread_smc_args *args)
227 {
228 	/* TODO move to main_init() */
229 	if (init_teecore() != TEE_SUCCESS)
230 		panic();
231 
232 	tee_entry(args);
233 }
234 
235 void console_putc(int ch)
236 {
237 	__asc_xmit_char((char)ch);
238 }
239 
240 void console_flush(void)
241 {
242 	__asc_flush();
243 }
244