3954d9db08cef72da993b40440b6161b6f2c18b3
[platform/core/security/tef-optee_os.git] / core / arch / arm / plat-sunxi / main.c
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 <tee/entry_std.h>
48 #include <tee/entry_fast.h>
49 #include <platform.h>
50 #include <util.h>
51 #include <trace.h>
52 #include <malloc.h>
53
54 /* teecore heap address/size is defined in scatter file */
55 extern unsigned char teecore_heap_start;
56 extern unsigned char teecore_heap_end;
57
58 static void main_fiq(void);
59 static void main_tee_entry_std(struct thread_smc_args *args);
60 static void main_tee_entry_fast(struct thread_smc_args *args);
61
62 static const struct thread_handlers handlers = {
63         .std_smc = main_tee_entry_std,
64         .fast_smc = main_tee_entry_fast,
65         .fiq = main_fiq,
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         thread_mask_exceptions(THREAD_EXCP_FIQ | THREAD_EXCP_IRQ);
87
88         if (pos == 0) {
89                 thread_init_primary(&handlers);
90
91                 /* initialize platform */
92                 platform_init();
93         }
94
95         thread_init_per_cpu();
96
97         /* Initialize secure monitor */
98         nsec_ctx = sm_get_nsec_ctx();
99         nsec_ctx->mon_lr = nsec_entry;
100         nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I;
101
102         if (pos == 0) {
103                 unsigned long a, s;
104                 /* core malloc pool init */
105 #ifdef CFG_TEE_MALLOC_START
106                 a = CFG_TEE_MALLOC_START;
107                 s = CFG_TEE_MALLOC_SIZE;
108 #else
109                 a = (unsigned long)&teecore_heap_start;
110                 s = (unsigned long)&teecore_heap_end;
111                 a = ((a + 1) & ~0x0FFFF) + 0x10000;     /* 64kB aligned */
112                 s = s & ~0x0FFFF;       /* 64kB aligned */
113                 s = s - a;
114 #endif
115                 malloc_add_pool((void *)a, s);
116
117                 teecore_init_ta_ram();
118
119                 if (init_teecore() != TEE_SUCCESS) {
120                         panic();
121                 }
122         }
123
124         IMSG("optee initialize finished\n");
125 }
126
127 static void main_fiq(void)
128 {
129         panic();
130 }
131
132 static void main_tee_entry_fast(struct thread_smc_args *args)
133 {
134         /* TODO move to main_init() */
135         if (init_teecore() != TEE_SUCCESS)
136                 panic();
137
138         /* SiP Service Call Count */
139         if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_COUNT) {
140                 args->a0 = 1;
141                 return;
142         }
143
144         /*  SiP Service Call UID */
145         if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_UID) {
146                 args->a0 = OPTEE_SMC_SIP_SUNXI_UID_R0;
147                 args->a1 = OPTEE_SMC_SIP_SUNXI_UID_R1;
148                 args->a2 = OPTEE_SMC_SIP_SUNXI_UID_R2;
149                 args->a3 = OPTEE_SMC_SIP_SUNXI_UID_R3;
150                 return;
151         }
152
153         /* SiP Service Calls */
154         if (args->a0 == OPTEE_SMC_OPTEE_FAST_CALL_SIP_SUNXI) {
155                 platform_smc_handle(args);
156                 return;
157         }
158
159         tee_entry_fast(args);
160 }
161
162
163
164 static void main_tee_entry_std(struct thread_smc_args *args)
165 {
166         /* TODO move to main_init() */
167         if (init_teecore() != TEE_SUCCESS)
168                 panic();
169
170         tee_entry_std(args);
171 }
172
173 /* main_tee_entry_fast() supports 3 platform-specific functions */
174 void tee_entry_get_api_call_count(struct thread_smc_args *args)
175 {
176         args->a0 = tee_entry_generic_get_api_call_count() + 3;
177 }