1 /* 2 * Copyright 2017, Rockchip Electronics Co., Ltd 3 * hisping lin, <hisping.lin@rock-chips.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <stdlib.h> 9 #include <command.h> 10 #include <mmc.h> 11 #include <optee_include/OpteeClientLoadTa.h> 12 #include <optee_include/OpteeClientMem.h> 13 #include <optee_include/OpteeClientRPC.h> 14 #include <optee_include/teesmc.h> 15 #include <optee_include/teesmc_v2.h> 16 #include <optee_include/teesmc_optee.h> 17 #include <optee_include/tee_mmc_rpmb.h> 18 #include <optee_include/tee_rpc_types.h> 19 #include <optee_include/tee_rpc.h> 20 #ifdef CONFIG_OPTEE_V1 21 #include <optee_include/OpteeClientRkFs.h> 22 #endif 23 #ifdef CONFIG_OPTEE_V2 24 #include <optee_include/OpteeClientRkNewFs.h> 25 #endif 26 27 /* 28 * Memory allocation. 29 * Currently treated the same for both arguments & payloads. 30 */ 31 TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address) 32 { 33 TEEC_Result TeecResult = TEEC_SUCCESS; 34 size_t AllocAddress; 35 36 *Address = 0; 37 38 if (Size != 0) { 39 AllocAddress = (size_t) OpteeClientMemAlloc(Size); 40 41 if (AllocAddress == 0) 42 TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 43 else 44 *Address = AllocAddress; 45 } 46 return TeecResult; 47 } 48 49 /* 50 * Memory free. 51 * Currently treated the same for both arguments & payloads. 52 */ 53 TEEC_Result OpteeRpcFree(uint32_t Address) 54 { 55 OpteeClientMemFree((void *)(size_t)Address); 56 return TEEC_SUCCESS; 57 } 58 59 TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg) 60 { 61 TEEC_Result TeecResult = TEEC_SUCCESS; 62 t_teesmc32_param *TeeSmc32Param = NULL; 63 int ta_found = 0; 64 size_t size = 0; 65 66 if (TeeSmc32Arg->num_params != 2) { 67 TeecResult = TEEC_ERROR_BAD_PARAMETERS; 68 goto Exit; 69 } 70 71 TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 72 73 size = TeeSmc32Param[1].u.memref.size; 74 ta_found = search_ta((void *)(size_t)&TeeSmc32Param[0].u.value, 75 (void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr, &size); 76 if (ta_found == TA_BINARY_FOUND) { 77 TeeSmc32Param[1].u.memref.size = size; 78 TeecResult = TEEC_SUCCESS; 79 } else { 80 printf(" TA not found \n"); 81 TeecResult = TEEC_ERROR_ITEM_NOT_FOUND; 82 } 83 84 Exit: 85 TeeSmc32Arg->ret = TeecResult; 86 TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 87 88 debug("TEEC: OpteeRpcCmdLoadV2Ta Exit : TeecResult=0x%X\n", TeecResult); 89 90 return TeecResult; 91 } 92 93 /* 94 * Execute an RPMB storage operation. 95 */ 96 TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg) 97 { 98 return emmc_rpmb_process(TeeSmc32Arg); 99 } 100 101 /* 102 * Execute a normal world local file system operation. 103 */ 104 TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg) 105 { 106 TEEC_Result TeecResult = TEEC_SUCCESS; 107 t_teesmc32_param *TeeSmc32Param; 108 109 TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 110 #ifdef CONFIG_OPTEE_V1 111 TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr, 112 TeeSmc32Param[0].u.memref.size); 113 TeeSmc32Arg->ret = TEEC_SUCCESS; 114 #endif 115 #ifdef CONFIG_OPTEE_V2 116 TeecResult = OpteeClientRkFsProcess((size_t)TeeSmc32Arg->num_params, 117 (struct tee_ioctl_param *)TeeSmc32Param); 118 TeeSmc32Arg->ret = TeecResult; 119 #endif 120 return TeecResult; 121 } 122 123 /* 124 * TBD. 125 */ 126 TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg) 127 { 128 return TEEC_ERROR_NOT_IMPLEMENTED; 129 } 130 131 /* 132 * TBD. 133 */ 134 TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg) 135 { 136 return TEEC_ERROR_NOT_IMPLEMENTED; 137 } 138 139 /* 140 * Handle the callback from secure world. 141 */ 142 TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs) 143 { 144 TEEC_Result TeecResult = TEEC_SUCCESS; 145 146 //printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n", 147 //ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2); 148 149 switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) { 150 case TEESMC_RPC_FUNC_ALLOC_ARG: { 151 debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1); 152 TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2); 153 ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2; 154 ArmSmcArgs->Arg1 = 0; 155 ArmSmcArgs->Arg4 = 0; 156 break; 157 } 158 159 case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: { 160 TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 161 break; 162 } 163 164 case TEESMC_RPC_FUNC_FREE_ARG: { 165 TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2); 166 break; 167 } 168 169 case TEESMC_RPC_FUNC_FREE_PAYLOAD: { 170 TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 171 break; 172 } 173 174 case TEESMC_RPC_FUNC_IRQ: { 175 break; 176 } 177 178 case TEESMC_RPC_FUNC_CMD: { 179 t_teesmc32_arg *TeeSmc32Arg = 180 (t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2); 181 debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd); 182 switch (TeeSmc32Arg->cmd) { 183 case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: { 184 uint32_t tempaddr; 185 uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b; 186 TeecResult = OpteeRpcAlloc(allocsize, &tempaddr); 187 debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr); 188 TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2; 189 TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr; 190 TeeSmc32Arg->params[0].u.memref.size = allocsize; 191 TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr; 192 TeeSmc32Arg->ret = TEE_SUCCESS; 193 break; 194 } 195 case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: { 196 uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b; 197 TeecResult = OpteeRpcFree(tempaddr); 198 break; 199 200 } 201 case OPTEE_MSG_RPC_CMD_RPMB_V2: { 202 TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg); 203 break; 204 } 205 case OPTEE_MSG_RPC_CMD_FS_V2: { 206 TeecResult = OpteeRpcCmdFs(TeeSmc32Arg); 207 break; 208 } 209 case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: { 210 TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg); 211 break; 212 } 213 214 default: { 215 printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n", 216 TeeSmc32Arg->cmd); 217 TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 218 break; 219 } 220 } 221 222 break; 223 } 224 225 case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: { 226 TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 227 ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1; 228 break; 229 } 230 231 case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: { 232 TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 233 break; 234 } 235 236 default: { 237 printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0); 238 TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 239 break; 240 } 241 } 242 243 ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC; 244 debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult); 245 246 return TeecResult; 247 } 248