blob: 8a426f53ba8ef031c486ad2a026d399e7f32f91e [file] [log] [blame]
Jens Wiklander2b7216b2018-09-25 16:40:11 +02001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (c) 2018, Linaro Limited
4 */
5
Jens Wiklander2b7216b2018-09-25 16:40:11 +02006#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -07007#include <malloc.h>
Jens Wiklander2b7216b2018-09-25 16:40:11 +02008#include <tee.h>
Igor Opaniuk4518a4d2024-04-04 15:19:51 +02009#include <linux/errno.h>
Jens Wiklander2b7216b2018-09-25 16:40:11 +020010#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 Opaniuk57816e02018-12-04 14:37:19 +020086 debug("REE FS storage isn't available\n");
87 arg->ret = TEE_ERROR_STORAGE_NOT_AVAILABLE;
Jens Wiklander2b7216b2018-09-25 16:40:11 +020088 break;
Jens Wiklanderf1420dd2018-09-25 16:40:14 +020089 case OPTEE_MSG_RPC_CMD_RPMB:
90 optee_suppl_cmd_rpmb(dev, arg);
91 break;
Jorge Ramirez-Ortizd30807d2021-01-25 14:28:40 +020092 case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
93 optee_suppl_cmd_i2c_transfer(arg);
94 break;
Jens Wiklander2b7216b2018-09-25 16:40:11 +020095 default:
96 arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
97 }
98
99 arg->ret_origin = TEE_ORIGIN_COMMS;
100}