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