xref: /openbmc/u-boot/drivers/tee/optee/supplicant.c (revision 5c8fd32b)
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