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