1abdd2437Shisping /* 2abdd2437Shisping * Copyright 2017, Rockchip Electronics Co., Ltd 3abdd2437Shisping * hisping lin, <hisping.lin@rock-chips.com> 4abdd2437Shisping * 5abdd2437Shisping * SPDX-License-Identifier: GPL-2.0+ 6abdd2437Shisping */ 7abdd2437Shisping #include <common.h> 8abdd2437Shisping #include <stdlib.h> 9abdd2437Shisping #include <command.h> 10abdd2437Shisping #include <mmc.h> 11b122ee17SHisping Lin #include <optee_include/OpteeClientLoadTa.h> 12abdd2437Shisping #include <optee_include/OpteeClientMem.h> 13abdd2437Shisping #include <optee_include/OpteeClientRPC.h> 14abdd2437Shisping #include <optee_include/teesmc.h> 151f25ada2SHisping Lin #include <optee_include/teesmc_v2.h> 16abdd2437Shisping #include <optee_include/teesmc_optee.h> 17*10adce6aSHisping Lin #include <optee_include/tee_mmc_rpmb.h> 18abdd2437Shisping #include <optee_include/tee_rpc_types.h> 19abdd2437Shisping #include <optee_include/tee_rpc.h> 203251364cSHisping Lin #ifdef CONFIG_OPTEE_V1 211f25ada2SHisping Lin #include <optee_include/OpteeClientRkFs.h> 223251364cSHisping Lin #endif 233251364cSHisping Lin #ifdef CONFIG_OPTEE_V2 24df538e29SHisping Lin #include <optee_include/OpteeClientRkNewFs.h> 253251364cSHisping Lin #endif 26abdd2437Shisping 27abdd2437Shisping /* 28abdd2437Shisping * Memory allocation. 29abdd2437Shisping * Currently treated the same for both arguments & payloads. 30abdd2437Shisping */ 31abdd2437Shisping TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address) 32abdd2437Shisping { 33abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 341f25ada2SHisping Lin size_t AllocAddress; 35abdd2437Shisping 36abdd2437Shisping *Address = 0; 37abdd2437Shisping 38abdd2437Shisping if (Size != 0) { 391f25ada2SHisping Lin AllocAddress = (size_t) OpteeClientMemAlloc(Size); 40abdd2437Shisping 41abdd2437Shisping if (AllocAddress == 0) 42abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 43abdd2437Shisping else 44abdd2437Shisping *Address = AllocAddress; 45abdd2437Shisping } 46abdd2437Shisping return TeecResult; 47abdd2437Shisping } 48abdd2437Shisping 49abdd2437Shisping /* 50abdd2437Shisping * Memory free. 51abdd2437Shisping * Currently treated the same for both arguments & payloads. 52abdd2437Shisping */ 53abdd2437Shisping TEEC_Result OpteeRpcFree(uint32_t Address) 54abdd2437Shisping { 551f25ada2SHisping Lin OpteeClientMemFree((void *)(size_t)Address); 56abdd2437Shisping return TEEC_SUCCESS; 57abdd2437Shisping } 58abdd2437Shisping 591f25ada2SHisping Lin TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg) 601f25ada2SHisping Lin { 611f25ada2SHisping Lin TEEC_Result TeecResult = TEEC_SUCCESS; 621f25ada2SHisping Lin t_teesmc32_param *TeeSmc32Param = NULL; 63b122ee17SHisping Lin int ta_found = 0; 64b122ee17SHisping Lin size_t size = 0; 651f25ada2SHisping Lin 661f25ada2SHisping Lin if (TeeSmc32Arg->num_params != 2) { 671f25ada2SHisping Lin TeecResult = TEEC_ERROR_BAD_PARAMETERS; 681f25ada2SHisping Lin goto Exit; 691f25ada2SHisping Lin } 701f25ada2SHisping Lin 711f25ada2SHisping Lin TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 721f25ada2SHisping Lin 73b122ee17SHisping Lin size = TeeSmc32Param[1].u.memref.size; 74b122ee17SHisping Lin ta_found = search_ta((void *)(size_t)&TeeSmc32Param[0].u.value, 75b122ee17SHisping Lin (void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr, &size); 76b122ee17SHisping Lin if (ta_found == TA_BINARY_FOUND) { 77b122ee17SHisping Lin TeeSmc32Param[1].u.memref.size = size; 78b122ee17SHisping Lin TeecResult = TEEC_SUCCESS; 791f25ada2SHisping Lin } else { 80b122ee17SHisping Lin printf(" TA not found \n"); 81b122ee17SHisping Lin TeecResult = TEEC_ERROR_ITEM_NOT_FOUND; 821f25ada2SHisping Lin } 831f25ada2SHisping Lin 841f25ada2SHisping Lin Exit: 851f25ada2SHisping Lin TeeSmc32Arg->ret = TeecResult; 861f25ada2SHisping Lin TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 871f25ada2SHisping Lin 88b122ee17SHisping Lin debug("TEEC: OpteeRpcCmdLoadV2Ta Exit : TeecResult=0x%X\n", TeecResult); 89abdd2437Shisping 90abdd2437Shisping return TeecResult; 91abdd2437Shisping } 92abdd2437Shisping 93abdd2437Shisping /* 94abdd2437Shisping * Execute an RPMB storage operation. 95abdd2437Shisping */ 96abdd2437Shisping TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg) 97abdd2437Shisping { 98*10adce6aSHisping Lin return emmc_rpmb_process(TeeSmc32Arg); 99abdd2437Shisping } 100abdd2437Shisping 101abdd2437Shisping /* 102abdd2437Shisping * Execute a normal world local file system operation. 103abdd2437Shisping */ 104abdd2437Shisping TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg) 105abdd2437Shisping { 1061f25ada2SHisping Lin TEEC_Result TeecResult = TEEC_SUCCESS; 1071f25ada2SHisping Lin t_teesmc32_param *TeeSmc32Param; 108abdd2437Shisping 1091f25ada2SHisping Lin TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 1103251364cSHisping Lin #ifdef CONFIG_OPTEE_V1 111d079c1a5SHisping Lin TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr, 1121f25ada2SHisping Lin TeeSmc32Param[0].u.memref.size); 113a3cf1018SHisping Lin TeeSmc32Arg->ret = TEEC_SUCCESS; 1143251364cSHisping Lin #endif 1153251364cSHisping Lin #ifdef CONFIG_OPTEE_V2 116df538e29SHisping Lin TeecResult = OpteeClientRkFsProcess((size_t)TeeSmc32Arg->num_params, 1173251364cSHisping Lin (struct tee_ioctl_param *)TeeSmc32Param); 118a3cf1018SHisping Lin TeeSmc32Arg->ret = TeecResult; 1193251364cSHisping Lin #endif 1201f25ada2SHisping Lin return TeecResult; 1211f25ada2SHisping Lin } 122abdd2437Shisping 123abdd2437Shisping /* 124abdd2437Shisping * TBD. 125abdd2437Shisping */ 126abdd2437Shisping TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg) 127abdd2437Shisping { 128abdd2437Shisping return TEEC_ERROR_NOT_IMPLEMENTED; 129abdd2437Shisping } 130abdd2437Shisping 131abdd2437Shisping /* 132abdd2437Shisping * TBD. 133abdd2437Shisping */ 134abdd2437Shisping TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg) 135abdd2437Shisping { 136abdd2437Shisping return TEEC_ERROR_NOT_IMPLEMENTED; 137abdd2437Shisping } 138abdd2437Shisping 139abdd2437Shisping /* 140abdd2437Shisping * Handle the callback from secure world. 141abdd2437Shisping */ 142abdd2437Shisping TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs) 143abdd2437Shisping { 144abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 145abdd2437Shisping 1461f25ada2SHisping Lin //printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n", 1471f25ada2SHisping Lin //ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2); 148abdd2437Shisping 149abdd2437Shisping switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) { 150abdd2437Shisping case TEESMC_RPC_FUNC_ALLOC_ARG: { 151efb93541SHisping Lin debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1); 1521f25ada2SHisping Lin TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2); 1531f25ada2SHisping Lin ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2; 1541f25ada2SHisping Lin ArmSmcArgs->Arg1 = 0; 1551f25ada2SHisping Lin ArmSmcArgs->Arg4 = 0; 156abdd2437Shisping break; 157abdd2437Shisping } 158abdd2437Shisping 159abdd2437Shisping case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: { 160abdd2437Shisping TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 161abdd2437Shisping break; 162abdd2437Shisping } 163abdd2437Shisping 164abdd2437Shisping case TEESMC_RPC_FUNC_FREE_ARG: { 1651f25ada2SHisping Lin TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2); 166abdd2437Shisping break; 167abdd2437Shisping } 168abdd2437Shisping 169abdd2437Shisping case TEESMC_RPC_FUNC_FREE_PAYLOAD: { 170abdd2437Shisping TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 171abdd2437Shisping break; 172abdd2437Shisping } 173abdd2437Shisping 174abdd2437Shisping case TEESMC_RPC_FUNC_IRQ: { 175abdd2437Shisping break; 176abdd2437Shisping } 177abdd2437Shisping 178abdd2437Shisping case TEESMC_RPC_FUNC_CMD: { 1791f25ada2SHisping Lin t_teesmc32_arg *TeeSmc32Arg = 180d156c9ffSHisping Lin (t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2); 181efb93541SHisping Lin debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd); 182abdd2437Shisping switch (TeeSmc32Arg->cmd) { 1831f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: { 1841f25ada2SHisping Lin uint32_t tempaddr; 1851f25ada2SHisping Lin uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b; 1861f25ada2SHisping Lin TeecResult = OpteeRpcAlloc(allocsize, &tempaddr); 187efb93541SHisping Lin debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr); 1881f25ada2SHisping Lin TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2; 1891f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr; 1901f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.size = allocsize; 1911f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr; 1921f25ada2SHisping Lin TeeSmc32Arg->ret = TEE_SUCCESS; 1931f25ada2SHisping Lin break; 1941f25ada2SHisping Lin } 1951f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: { 1961f25ada2SHisping Lin uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b; 1971f25ada2SHisping Lin TeecResult = OpteeRpcFree(tempaddr); 1981f25ada2SHisping Lin break; 1991f25ada2SHisping Lin 2001f25ada2SHisping Lin } 2011f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_RPMB_V2: { 2021f25ada2SHisping Lin TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg); 2031f25ada2SHisping Lin break; 2041f25ada2SHisping Lin } 2053251364cSHisping Lin case OPTEE_MSG_RPC_CMD_FS_V2: { 2063251364cSHisping Lin TeecResult = OpteeRpcCmdFs(TeeSmc32Arg); 2073251364cSHisping Lin break; 2083251364cSHisping Lin } 2091f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: { 2101f25ada2SHisping Lin TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg); 2111f25ada2SHisping Lin break; 2121f25ada2SHisping Lin } 213abdd2437Shisping 214abdd2437Shisping default: { 215efb93541SHisping Lin printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n", 216abdd2437Shisping TeeSmc32Arg->cmd); 217abdd2437Shisping TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 218abdd2437Shisping break; 219abdd2437Shisping } 220abdd2437Shisping } 221abdd2437Shisping 222abdd2437Shisping break; 223abdd2437Shisping } 224abdd2437Shisping 225abdd2437Shisping case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: { 226abdd2437Shisping TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 227abdd2437Shisping ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1; 228abdd2437Shisping break; 229abdd2437Shisping } 230abdd2437Shisping 231abdd2437Shisping case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: { 232abdd2437Shisping TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 233abdd2437Shisping break; 234abdd2437Shisping } 235abdd2437Shisping 236abdd2437Shisping default: { 237efb93541SHisping Lin printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0); 238abdd2437Shisping TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 239abdd2437Shisping break; 240abdd2437Shisping } 241abdd2437Shisping } 242abdd2437Shisping 243abdd2437Shisping ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC; 244efb93541SHisping Lin debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult); 245abdd2437Shisping 246abdd2437Shisping return TeecResult; 247abdd2437Shisping } 248