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.
31 #include <drivers/sunxi_uart.h>
32 #include <kernel/misc.h>
33 #include <kernel/panic.h>
34 #include <kernel/pm_stubs.h>
35 #include <kernel/thread.h>
36 #include <kernel/time_source.h>
38 #include <mm/core_mmu.h>
39 #include <mm/tee_mmu.h>
40 #include <optee_msg.h>
41 #include <platform_config.h>
43 #include <sm/optee_smc.h>
45 #include <sm/tee_mon.h>
48 #include <tee/entry_fast.h>
49 #include <tee/entry_std.h>
53 /* teecore heap address/size is defined in scatter file */
54 extern unsigned char teecore_heap_start;
55 extern unsigned char teecore_heap_end;
57 static void main_fiq(void);
58 static void main_tee_entry_std(struct thread_smc_args *args);
59 static void main_tee_entry_fast(struct thread_smc_args *args);
61 static const struct thread_handlers handlers = {
62 .std_smc = main_tee_entry_std,
63 .fast_smc = main_tee_entry_fast,
67 .cpu_suspend = pm_panic,
68 .cpu_resume = pm_panic,
69 .system_off = pm_panic,
70 .system_reset = pm_panic,
73 void main_init(uint32_t nsec_entry); /* called from assembly only */
74 void main_init(uint32_t nsec_entry)
76 struct sm_nsec_ctx *nsec_ctx;
77 size_t pos = get_core_pos();
80 * Mask the interrupts before switch to the thread vector as the
81 * thread handler requires the interrupts to be masked while executing
82 * with the temporary stack. The thread subsystem also asserts that
83 * foreign interrupts are blocked when using most if its functions.
85 thread_mask_exceptions(
86 THREAD_EXCP_NATIVE_INTR | THREAD_EXCP_FOREIGN_INTR);
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;
179 static struct sunxi_uart_data console_data __early_bss;
181 void console_init(void)
183 sunxi_uart_init(&console_data, CONSOLE_UART_BASE);
184 register_serial_console(&console_data.chip);