xref: /optee_os/core/arch/arm/tee/entry_fast.c (revision 9403c583381528e7fb391e3769644cc9653cfbb6)
1 /*
2  * Copyright (c) 2015, Linaro Limited
3  * All rights reserved.
4  * Copyright (c) 2014, STMicroelectronics International N.V.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <tee/entry_fast.h>
31 #include <sm/teesmc.h>
32 #include <sm/teesmc_optee.h>
33 #include <kernel/tee_l2cc_mutex.h>
34 #include <kernel/panic.h>
35 #include <mm/core_mmu.h>
36 
37 #include <assert.h>
38 
39 static void tee_entry_get_shm_config(struct thread_smc_args *args)
40 {
41 	args->a0 = TEESMC_RETURN_OK;
42 	args->a1 = default_nsec_shm_paddr;
43 	args->a2 = default_nsec_shm_size;
44 	/* Should this be TEESMC cache attributes instead? */
45 	args->a3 = core_mmu_is_shm_cached();
46 }
47 
48 static void tee_entry_fastcall_l2cc_mutex(struct thread_smc_args *args)
49 {
50 	TEE_Result ret;
51 
52 #ifdef ARM32
53 	switch (args->a1) {
54 	case TEESMC_OPTEE_L2CC_MUTEX_GET_ADDR:
55 		ret = tee_get_l2cc_mutex(&args->a2);
56 		break;
57 	case TEESMC_OPTEE_L2CC_MUTEX_SET_ADDR:
58 		ret = tee_set_l2cc_mutex(&args->a2);
59 		break;
60 	case TEESMC_OPTEE_L2CC_MUTEX_ENABLE:
61 		ret = tee_enable_l2cc_mutex();
62 		break;
63 	case TEESMC_OPTEE_L2CC_MUTEX_DISABLE:
64 		ret = tee_disable_l2cc_mutex();
65 		break;
66 	default:
67 		args->a0 = TEESMC_RETURN_EBADCMD;
68 		return;
69 	}
70 #else
71 	ret = TEE_ERROR_NOT_SUPPORTED;
72 #endif
73 	if (ret == TEE_ERROR_NOT_SUPPORTED)
74 		args->a0 = TEESMC_RETURN_UNKNOWN_FUNCTION;
75 	else if (ret)
76 		args->a0 = TEESMC_RETURN_EBADADDR;
77 	else
78 		args->a0 = TEESMC_RETURN_OK;
79 }
80 
81 void tee_entry_fast(struct thread_smc_args *args)
82 {
83 	switch (args->a0) {
84 
85 	/* Generic functions */
86 	case TEESMC32_CALLS_COUNT:
87 		tee_entry_get_api_call_count(args);
88 		break;
89 	case TEESMC32_CALLS_UID:
90 		tee_entry_get_api_uuid(args);
91 		break;
92 	case TEESMC32_CALLS_REVISION:
93 		tee_entry_get_api_revision(args);
94 		break;
95 	case TEESMC32_CALL_GET_OS_UUID:
96 		tee_entry_get_os_uuid(args);
97 		break;
98 	case TEESMC32_CALL_GET_OS_REVISION:
99 		tee_entry_get_os_revision(args);
100 		break;
101 
102 	/* OP-TEE specific SMC functions */
103 	case TEESMC32_OPTEE_FASTCALL_GET_SHM_CONFIG:
104 		tee_entry_get_shm_config(args);
105 		break;
106 	case TEESMC32_OPTEE_FASTCALL_L2CC_MUTEX:
107 		tee_entry_fastcall_l2cc_mutex(args);
108 		break;
109 	default:
110 		args->a0 = TEESMC_RETURN_UNKNOWN_FUNCTION;
111 		break;
112 	}
113 }
114 
115 size_t tee_entry_generic_get_api_call_count(void)
116 {
117 	/*
118 	 * All the different calls handled in this file. If the specific
119 	 * target has additional calls it will call this function and
120 	 * add the number of calls the target has added.
121 	 */
122 	return 9;
123 }
124 
125 void __weak tee_entry_get_api_call_count(struct thread_smc_args *args)
126 {
127 	args->a0 = tee_entry_generic_get_api_call_count();
128 }
129 
130 void __weak tee_entry_get_api_uuid(struct thread_smc_args *args)
131 {
132 	args->a0 = TEESMC_OPTEE_UID_R0;
133 	args->a1 = TEESMC_OPTEE_UID_R1;
134 	args->a2 = TEESMC_OPTEE_UID_R2;
135 	args->a3 = TEESMC_OPTEE_UID32_R3;
136 }
137 
138 void __weak tee_entry_get_api_revision(struct thread_smc_args *args)
139 {
140 	args->a0 = TEESMC_OPTEE_REVISION_MAJOR;
141 	args->a1 = TEESMC_OPTEE_REVISION_MINOR;
142 }
143 
144 void __weak tee_entry_get_os_uuid(struct thread_smc_args *args)
145 {
146 	args->a0 = TEESMC_OS_OPTEE_UUID_R0;
147 	args->a1 = TEESMC_OS_OPTEE_UUID_R1;
148 	args->a2 = TEESMC_OS_OPTEE_UUID_R2;
149 	args->a3 = TEESMC_OS_OPTEE_UUID_R3;
150 }
151 
152 void __weak tee_entry_get_os_revision(struct thread_smc_args *args)
153 {
154 	args->a0 = TEESMC_OS_OPTEE_REVISION_MAJOR;
155 	args->a1 = TEESMC_OS_OPTEE_REVISION_MINOR;
156 }
157