2 * Copyright (c) 2014, Allwinner Technology Co., Ltd.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
28 #include <platform_config.h>
35 #include <sm/tee_mon.h>
36 #include <sm/optee_smc.h>
37 #include <optee_msg.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>
54 /* teecore heap address/size is defined in scatter file */
55 extern unsigned char teecore_heap_start;
56 extern unsigned char teecore_heap_end;
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);
62 static const struct thread_handlers handlers = {
63 .std_smc = main_tee_entry_std,
64 .fast_smc = main_tee_entry_fast,
68 .cpu_suspend = pm_panic,
69 .cpu_resume = pm_panic,
70 .system_off = pm_panic,
71 .system_reset = pm_panic,
74 void main_init(uint32_t nsec_entry); /* called from assembly only */
75 void main_init(uint32_t nsec_entry)
77 struct sm_nsec_ctx *nsec_ctx;
78 size_t pos = get_core_pos();
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.
86 thread_mask_exceptions(THREAD_EXCP_FIQ | THREAD_EXCP_IRQ);
89 thread_init_primary(&handlers);
91 /* initialize platform */
95 thread_init_per_cpu();
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;
104 /* core malloc pool init */
105 #ifdef CFG_TEE_MALLOC_START
106 a = CFG_TEE_MALLOC_START;
107 s = CFG_TEE_MALLOC_SIZE;
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 */
115 malloc_add_pool((void *)a, s);
117 teecore_init_ta_ram();
119 if (init_teecore() != TEE_SUCCESS) {
124 IMSG("optee initialize finished\n");
127 static void main_fiq(void)
132 static void main_tee_entry_fast(struct thread_smc_args *args)
134 /* TODO move to main_init() */
135 if (init_teecore() != TEE_SUCCESS)
138 /* SiP Service Call Count */
139 if (args->a0 == OPTEE_SMC_SIP_SUNXI_CALLS_COUNT) {
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;
153 /* SiP Service Calls */
154 if (args->a0 == OPTEE_SMC_OPTEE_FAST_CALL_SIP_SUNXI) {
155 platform_smc_handle(args);
159 tee_entry_fast(args);
164 static void main_tee_entry_std(struct thread_smc_args *args)
166 /* TODO move to main_init() */
167 if (init_teecore() != TEE_SUCCESS)
173 /* main_tee_entry_fast() supports 3 platform-specific functions */
174 void tee_entry_get_api_call_count(struct thread_smc_args *args)
176 args->a0 = tee_entry_generic_get_api_call_count() + 3;