xref: /optee_os/core/arch/arm/plat-stm/main.c (revision 31908aeac446be4859fe9dc98dc4e1e0c13b528c)
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 void main_init(uint32_t nsec_entry); /* called from assembly only */
75 void main_init(uint32_t nsec_entry)
76 {
77 	struct sm_nsec_ctx *nsec_ctx;
78 	size_t pos = get_core_pos();
79 
80 	/*
81 	 * Mask IRQ and FIQ before switch to the thread vector as the
82 	 * thread handler requires IRQ and FIQ to be masked while executing
83 	 * with the temporary stack. The thread subsystem also asserts that
84 	 * IRQ is blocked when using most if its functions.
85 	 */
86 	write_cpsr(read_cpsr() | CPSR_F | CPSR_I);
87 
88 	if (pos == 0)
89 		thread_init_primary(&handlers);
90 
91 	thread_init_per_cpu();
92 
93 	/* Initialize secure monitor */
94 	nsec_ctx = sm_get_nsec_ctx();
95 	nsec_ctx->mon_lr = nsec_entry;
96 	nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
97 
98 	if (pos == 0) {
99 		unsigned long a, s;
100 		/* core malloc pool init */
101 #ifdef CFG_TEE_MALLOC_START
102 		a = CFG_TEE_MALLOC_START;
103 		s = CFG_TEE_MALLOC_SIZE;
104 #else
105 		a = (unsigned long)&teecore_heap_start;
106 		s = (unsigned long)&teecore_heap_end;
107 		a = ((a + 1) & ~0x0FFFF) + 0x10000;	/* 64kB aligned */
108 		s = s & ~0x0FFFF;	/* 64kB aligned */
109 		s = s - a;
110 #endif
111 		malloc_init((void *)a, s);
112 
113 		teecore_init_ta_ram();
114 	}
115 }
116 
117 static void main_fiq(void)
118 {
119 	panic();
120 }
121 
122 static void main_tee_entry(struct thread_smc_args *args)
123 {
124 	/* TODO move to main_init() */
125 	if (init_teecore() != TEE_SUCCESS)
126 		panic();
127 
128 	tee_entry(args);
129 }
130 
131 /* ttbr1 for teecore mapping: 16kB, fixed addr. */
132 extern uint8_t *SEC_MMU_TTB_FLD;
133 /* ttbr0 for TA mapping (default was 128kB) */
134 extern uint8_t *SEC_TA_MMU_TTB_FLD;
135 
136 paddr_t core_mmu_get_main_ttb_pa(void)
137 {
138 	/* Note that this depends on flat mapping of TEE Core */
139 	paddr_t pa = (paddr_t)core_mmu_get_main_ttb_va();
140 
141 	TEE_ASSERT(!(pa & ~TEE_MMU_TTB_L1_MASK));
142 	return pa;
143 }
144 
145 vaddr_t core_mmu_get_main_ttb_va(void)
146 {
147 	return (vaddr_t)&SEC_MMU_TTB_FLD;
148 }
149 
150 paddr_t core_mmu_get_ul1_ttb_pa(void)
151 {
152 	/* Note that this depends on flat mapping of TEE Core */
153 	paddr_t pa = (paddr_t)core_mmu_get_ul1_ttb_va();
154 	TEE_ASSERT(!(pa & ~TEE_MMU_TTB_UL1_MASK));
155 	return pa;
156 }
157 
158 vaddr_t core_mmu_get_ul1_ttb_va(void)
159 {
160 	return (vaddr_t)&SEC_TA_MMU_TTB_FLD;
161 }
162 
163 void console_putc(int ch)
164 {
165 	__asc_xmit_char((char)ch);
166 }
167 
168 void console_flush(void)
169 {
170 	__asc_flush();
171 }
172 
173 /* L2 translation table(s) for teecore mapping: fixed addr. */
174 extern uint8_t *SEC_MMU_L2_TTB_FLD;
175 extern uint8_t *SEC_MMU_L2_TTB_END;
176 
177 void *core_mmu_alloc_l2(struct tee_mmap_region *mm)
178 {
179 	/* Can't have this in .bss since it's not initialized yet */
180 	static size_t l2_offs __attribute__((section(".data")));
181 	const size_t l2_size = SEC_MMU_L2_TTB_END - SEC_MMU_L2_TTB_FLD;
182 	const size_t l2_va_size = TEE_MMU_L2_NUM_ENTRIES * SMALL_PAGE_SIZE;
183 	size_t l2_va_space = ((l2_size - l2_offs) / TEE_MMU_L2_SIZE) *
184 				l2_va_size;
185 
186 	if (l2_offs)
187 		return NULL;
188 	if (mm->size > l2_va_space)
189 		return NULL;
190 	l2_offs += ROUNDUP(mm->size, l2_va_size) / l2_va_size;
191 	return SEC_MMU_L2_TTB_FLD;
192 }
193