xref: /optee_os/core/arch/arm/plat-sunxi/main.c (revision 983d02116743476904b68d52ca432d0f79c38c43)
1 /*
2  * Copyright (c) 2014, Allwinner Technology Co., Ltd.
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 
28 #include <platform_config.h>
29 
30 #include <stdint.h>
31 #include <string.h>
32 #include <assert.h>
33 
34 #include <sm/sm.h>
35 #include <sm/tee_mon.h>
36 #include <sm/optee_smc.h>
37 #include <optee_msg.h>
38 
39 #include <arm.h>
40 #include <kernel/thread.h>
41 #include <kernel/time_source.h>
42 #include <kernel/panic.h>
43 #include <kernel/pm_stubs.h>
44 #include <kernel/misc.h>
45 #include <mm/tee_mmu.h>
46 #include <mm/core_mmu.h>
47 #include <mm/tee_mmu_defs.h>
48 #include <tee/entry_std.h>
49 #include <tee/entry_fast.h>
50 #include <platform.h>
51 #include <util.h>
52 #include <trace.h>
53 #include <malloc.h>
54 
55 /* teecore heap address/size is defined in scatter file */
56 extern unsigned char teecore_heap_start;
57 extern unsigned char teecore_heap_end;
58 
59 static void main_fiq(void);
60 static void main_tee_entry_std(struct thread_smc_args *args);
61 static void main_tee_entry_fast(struct thread_smc_args *args);
62 
63 static const struct thread_handlers handlers = {
64 	.std_smc = main_tee_entry_std,
65 	.fast_smc = main_tee_entry_fast,
66 	.fiq = main_fiq,
67 	.cpu_on = pm_panic,
68 	.cpu_off = pm_panic,
69 	.cpu_suspend = pm_panic,
70 	.cpu_resume = pm_panic,
71 	.system_off = pm_panic,
72 	.system_reset = pm_panic,
73 };
74 
75 void main_init(uint32_t nsec_entry); /* called from assembly only */
76 void main_init(uint32_t nsec_entry)
77 {
78 	struct sm_nsec_ctx *nsec_ctx;
79 	size_t pos = get_core_pos();
80 
81 	/*
82 	 * Mask IRQ and FIQ before switch to the thread vector as the
83 	 * thread handler requires IRQ and FIQ to be masked while executing
84 	 * with the temporary stack. The thread subsystem also asserts that
85 	 * IRQ is blocked when using most if its functions.
86 	 */
87 	thread_mask_exceptions(THREAD_EXCP_FIQ | THREAD_EXCP_IRQ);
88 
89 	if (pos == 0) {
90 		thread_init_primary(&handlers);
91 
92 		/* initialize platform */
93 		platform_init();
94 	}
95 
96 	thread_init_per_cpu();
97 
98 	/* Initialize secure monitor */
99 	nsec_ctx = sm_get_nsec_ctx();
100 	nsec_ctx->mon_lr = nsec_entry;
101 	nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
102 
103 	if (pos == 0) {
104 		unsigned long a, s;
105 		/* core malloc pool init */
106 #ifdef CFG_TEE_MALLOC_START
107 		a = CFG_TEE_MALLOC_START;
108 		s = CFG_TEE_MALLOC_SIZE;
109 #else
110 		a = (unsigned long)&teecore_heap_start;
111 		s = (unsigned long)&teecore_heap_end;
112 		a = ((a + 1) & ~0x0FFFF) + 0x10000;	/* 64kB aligned */
113 		s = s & ~0x0FFFF;	/* 64kB aligned */
114 		s = s - a;
115 #endif
116 		malloc_add_pool((void *)a, s);
117 
118 		teecore_init_ta_ram();
119 
120 		if (init_teecore() != TEE_SUCCESS) {
121 			panic();
122 		}
123 	}
124 
125 	IMSG("optee initialize finished\n");
126 }
127 
128 static void main_fiq(void)
129 {
130 	panic();
131 }
132 
133 static void main_tee_entry_fast(struct thread_smc_args *args)
134 {
135 	/* TODO move to main_init() */
136 	if (init_teecore() != TEE_SUCCESS)
137 		panic();
138 
139 	/* SiP Service Call Count */
140 	if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_COUNT) {
141 		args->a0 = 1;
142 		return;
143 	}
144 
145 	/*  SiP Service Call UID */
146 	if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_UID) {
147 		args->a0 = OPTEE_SMC_SIP_SUNXI_UID_R0;
148 		args->a1 = OPTEE_SMC_SIP_SUNXI_UID_R1;
149 		args->a2 = OPTEE_SMC_SIP_SUNXI_UID_R2;
150 		args->a3 = OPTEE_SMC_SIP_SUNXI_UID_R3;
151 		return;
152 	}
153 
154 	/* SiP Service Calls */
155 	if (args->a0 == OPTEE_SMC_OPTEE_FAST_CALL_SIP_SUNXI) {
156 		platform_smc_handle(args);
157 		return;
158 	}
159 
160 	tee_entry_fast(args);
161 }
162 
163 
164 
165 static void main_tee_entry_std(struct thread_smc_args *args)
166 {
167 	/* TODO move to main_init() */
168 	if (init_teecore() != TEE_SUCCESS)
169 		panic();
170 
171 	tee_entry_std(args);
172 }
173 
174 /* main_tee_entry_fast() supports 3 platform-specific functions */
175 void tee_entry_get_api_call_count(struct thread_smc_args *args)
176 {
177 	args->a0 = tee_entry_generic_get_api_call_count() + 3;
178 }
179