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