1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2018, Linaro Limited 4 */ 5 6 #include <common.h> 7 #include <log.h> 8 #include <tee.h> 9 #include <linux/types.h> 10 11 #include "optee_msg.h" 12 #include "optee_msg_supplicant.h" 13 #include "optee_private.h" 14 #include "optee_smc.h" 15 16 static void cmd_shm_alloc(struct udevice *dev, struct optee_msg_arg *arg, 17 void **page_list) 18 { 19 int rc; 20 struct tee_shm *shm; 21 void *pl; 22 u64 ph_ptr; 23 24 arg->ret_origin = TEE_ORIGIN_COMMS; 25 26 if (arg->num_params != 1 || 27 arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) { 28 arg->ret = TEE_ERROR_BAD_PARAMETERS; 29 return; 30 } 31 32 rc = __tee_shm_add(dev, 0, NULL, arg->params[0].u.value.b, 33 TEE_SHM_REGISTER | TEE_SHM_ALLOC, &shm); 34 if (rc) { 35 if (rc == -ENOMEM) 36 arg->ret = TEE_ERROR_OUT_OF_MEMORY; 37 else 38 arg->ret = TEE_ERROR_GENERIC; 39 return; 40 } 41 42 pl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr); 43 if (!pl) { 44 arg->ret = TEE_ERROR_OUT_OF_MEMORY; 45 tee_shm_free(shm); 46 return; 47 } 48 49 *page_list = pl; 50 arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | 51 OPTEE_MSG_ATTR_NONCONTIG; 52 arg->params[0].u.tmem.buf_ptr = ph_ptr; 53 arg->params[0].u.tmem.size = shm->size; 54 arg->params[0].u.tmem.shm_ref = (ulong)shm; 55 arg->ret = TEE_SUCCESS; 56 } 57 58 static void cmd_shm_free(struct optee_msg_arg *arg) 59 { 60 arg->ret_origin = TEE_ORIGIN_COMMS; 61 62 if (arg->num_params != 1 || 63 arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) { 64 arg->ret = TEE_ERROR_BAD_PARAMETERS; 65 return; 66 } 67 68 tee_shm_free((struct tee_shm *)(ulong)arg->params[0].u.value.b); 69 arg->ret = TEE_SUCCESS; 70 } 71 72 void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg, 73 void **page_list) 74 { 75 struct optee_msg_arg *arg = shm_arg->addr; 76 77 switch (arg->cmd) { 78 case OPTEE_MSG_RPC_CMD_SHM_ALLOC: 79 cmd_shm_alloc(dev, arg, page_list); 80 break; 81 case OPTEE_MSG_RPC_CMD_SHM_FREE: 82 cmd_shm_free(arg); 83 break; 84 case OPTEE_MSG_RPC_CMD_FS: 85 debug("OPTEE_MSG_RPC_CMD_FS not implemented\n"); 86 arg->ret = TEE_ERROR_NOT_IMPLEMENTED; 87 break; 88 case OPTEE_MSG_RPC_CMD_RPMB: 89 optee_suppl_cmd_rpmb(dev, arg); 90 break; 91 default: 92 arg->ret = TEE_ERROR_NOT_IMPLEMENTED; 93 } 94 95 arg->ret_origin = TEE_ORIGIN_COMMS; 96 } 97