xref: /optee_os/core/arch/arm/plat-sunxi/main.c (revision b1469ba0bfd0371eb52bd50f5c52eeda7a8f5f1e)
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 <arm.h>
29 #include <assert.h>
30 #include <console.h>
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>
37 #include <malloc.h>
38 #include <mm/core_mmu.h>
39 #include <mm/tee_mmu.h>
40 #include <optee_msg.h>
41 #include <platform_config.h>
42 #include <platform.h>
43 #include <sm/optee_smc.h>
44 #include <sm/sm.h>
45 #include <sm/tee_mon.h>
46 #include <stdint.h>
47 #include <string.h>
48 #include <tee/entry_fast.h>
49 #include <tee/entry_std.h>
50 #include <trace.h>
51 #include <util.h>
52 
53 /* teecore heap address/size is defined in scatter file */
54 extern unsigned char teecore_heap_start;
55 extern unsigned char teecore_heap_end;
56 
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);
60 
61 static const struct thread_handlers handlers = {
62 	.std_smc = main_tee_entry_std,
63 	.fast_smc = main_tee_entry_fast,
64 	.nintr = main_fiq,
65 	.cpu_on = pm_panic,
66 	.cpu_off = pm_panic,
67 	.cpu_suspend = pm_panic,
68 	.cpu_resume = pm_panic,
69 	.system_off = pm_panic,
70 	.system_reset = pm_panic,
71 };
72 
73 void main_init(uint32_t nsec_entry); /* called from assembly only */
74 void main_init(uint32_t nsec_entry)
75 {
76 	struct sm_nsec_ctx *nsec_ctx;
77 	size_t pos = get_core_pos();
78 
79 	/*
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.
84 	 */
85 	thread_mask_exceptions(
86 			THREAD_EXCP_NATIVE_INTR | THREAD_EXCP_FOREIGN_INTR);
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 }
178 
179 static struct sunxi_uart_data console_data;
180 
181 void console_init(void)
182 {
183 	sunxi_uart_init(&console_data, CONSOLE_UART_BASE);
184 	register_serial_console(&console_data.chip);
185 }
186