blob: b56c982eb75e4847102e2aefc690500bf8e11f3c [file] [log] [blame]
Jens Wiklandera10b9832018-09-25 16:40:19 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018 Linaro Limited
4 */
5
Jens Wiklandera10b9832018-09-25 16:40:19 +02006#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -06007#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -07008#include <malloc.h>
Jens Wiklandera10b9832018-09-25 16:40:19 +02009#include <dm/test.h>
10#include <sandboxtee.h>
11#include <tee.h>
Simon Glass75c4d412020-07-19 10:15:37 -060012#include <test/test.h>
Jens Wiklandera10b9832018-09-25 16:40:19 +020013#include <test/ut.h>
14#include <tee/optee_ta_avb.h>
Igor Opaniuk40154e92021-01-25 14:28:43 +020015#include <tee/optee_ta_rpc_test.h>
Jens Wiklandera10b9832018-09-25 16:40:19 +020016
Igor Opaniuk40154e92021-01-25 14:28:43 +020017static int open_session(struct udevice *dev, u32 *session,
18 struct tee_optee_ta_uuid *uuid)
Jens Wiklandera10b9832018-09-25 16:40:19 +020019{
20 struct tee_open_session_arg arg;
Jens Wiklandera10b9832018-09-25 16:40:19 +020021 int rc;
22
23 memset(&arg, 0, sizeof(arg));
Igor Opaniuk40154e92021-01-25 14:28:43 +020024 tee_optee_ta_uuid_to_octets(arg.uuid, uuid);
Jens Wiklandera10b9832018-09-25 16:40:19 +020025 rc = tee_open_session(dev, &arg, 0, NULL);
26 if (rc)
27 return rc;
28 if (arg.ret)
29 return -EIO;
30 *session = arg.session;
31
32 return 0;
33}
34
Igor Opaniuk40154e92021-01-25 14:28:43 +020035static int invoke_func_avb(struct udevice *dev, u32 session)
Jens Wiklandera10b9832018-09-25 16:40:19 +020036{
37 struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
38 struct tee_invoke_arg arg;
39
40 memset(&arg, 0, sizeof(arg));
41 arg.session = session;
42 arg.func = TA_AVB_CMD_READ_LOCK_STATE;
43
44 if (tee_invoke_func(dev, &arg, 1, &param) || arg.ret)
45 return -1;
46
47 return 0;
48}
49
Igor Opaniuk40154e92021-01-25 14:28:43 +020050static int invoke_func_rpc_test(struct udevice *dev, u32 session,
51 u64 op, u64 busnum, u64 chip_addr,
52 u64 xfer_flags, u8 *buf, size_t buf_size)
53{
54 struct tee_param param[2];
55 struct tee_invoke_arg arg;
56 struct tee_shm *shm_buf;
57 int rc;
58
59 memset(&arg, 0, sizeof(arg));
60 arg.session = session;
61 arg.func = op;
62
63 rc = tee_shm_alloc(dev, buf_size,
64 TEE_SHM_ALLOC, &shm_buf);
65 if (rc)
66 return rc;
67
68 if (op == TA_RPC_TEST_CMD_I2C_WRITE)
69 memcpy(shm_buf->addr, buf, buf_size);
70
71 memset(param, 0, sizeof(param));
72 param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
73 param[0].u.value.a = busnum;
74 param[0].u.value.b = chip_addr;
75 param[0].u.value.c = xfer_flags;
76 param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
77 param[1].u.memref.shm = shm_buf;
78 param[1].u.memref.size = buf_size;
79
80 if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
81 rc = -1;
82 goto out;
83 }
84
85 if (op == TA_RPC_TEST_CMD_I2C_READ)
86 memcpy(buf, shm_buf->addr, buf_size);
87out:
88 tee_shm_free(shm_buf);
89 return rc;
90}
91
Jens Wiklandera10b9832018-09-25 16:40:19 +020092static int match(struct tee_version_data *vers, const void *data)
93{
94 return vers->gen_caps & TEE_GEN_CAP_GP;
95}
96
Jens Wiklander78c4b3e2018-10-29 11:41:35 +010097struct test_tee_vars {
98 struct tee_shm *reg_shm;
99 struct tee_shm *alloc_shm;
100};
101
102static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
Jens Wiklandera10b9832018-09-25 16:40:19 +0200103{
104 struct tee_version_data vers;
105 struct udevice *dev;
106 struct sandbox_tee_state *state;
Igor Opaniuk40154e92021-01-25 14:28:43 +0200107 struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
Jens Wiklandera10b9832018-09-25 16:40:19 +0200108 u32 session = 0;
109 int rc;
110 u8 data[128];
Jens Wiklandera10b9832018-09-25 16:40:19 +0200111
112 dev = tee_find_device(NULL, match, NULL, &vers);
113 ut_assert(dev);
114 state = dev_get_priv(dev);
115 ut_assert(!state->session);
116
Igor Opaniuk40154e92021-01-25 14:28:43 +0200117 rc = open_session(dev, &session, &avb_uuid);
Jens Wiklandera10b9832018-09-25 16:40:19 +0200118 ut_assert(!rc);
119 ut_assert(session == state->session);
120
Igor Opaniuk40154e92021-01-25 14:28:43 +0200121 rc = invoke_func_avb(dev, session);
Jens Wiklandera10b9832018-09-25 16:40:19 +0200122 ut_assert(!rc);
123
124 rc = tee_close_session(dev, session);
125 ut_assert(!rc);
126 ut_assert(!state->session);
127
128 ut_assert(!state->num_shms);
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100129 rc = tee_shm_register(dev, data, sizeof(data), 0, &vars->reg_shm);
Jens Wiklandera10b9832018-09-25 16:40:19 +0200130 ut_assert(!rc);
131 ut_assert(state->num_shms == 1);
132
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100133 rc = tee_shm_alloc(dev, 256, 0, &vars->alloc_shm);
Jens Wiklandera10b9832018-09-25 16:40:19 +0200134 ut_assert(!rc);
135 ut_assert(state->num_shms == 2);
136
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100137 ut_assert(tee_shm_is_registered(vars->reg_shm, dev));
138 ut_assert(tee_shm_is_registered(vars->alloc_shm, dev));
Jens Wiklandera10b9832018-09-25 16:40:19 +0200139
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100140 tee_shm_free(vars->reg_shm);
141 vars->reg_shm = NULL;
142 tee_shm_free(vars->alloc_shm);
143 vars->alloc_shm = NULL;
Jens Wiklandera10b9832018-09-25 16:40:19 +0200144 ut_assert(!state->num_shms);
145
Igor Opaniuk40154e92021-01-25 14:28:43 +0200146 return rc;
Jens Wiklandera10b9832018-09-25 16:40:19 +0200147}
148
Igor Opaniuk40154e92021-01-25 14:28:43 +0200149#define I2C_BUF_SIZE 64
150
151static int test_tee_rpc(struct unit_test_state *uts)
152{
153 struct tee_version_data vers;
154 struct udevice *dev;
155 struct sandbox_tee_state *state;
156 struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
157 u32 session = 0;
158 int rc;
159
160 char *test_str = "Test string";
161 u8 data[I2C_BUF_SIZE] = {0};
162 u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
163
164 /* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
165 u64 bus = 0;
166 u64 chip = 0x2c;
167 u64 xfer_flags = 0;
168
169 dev = tee_find_device(NULL, match, NULL, &vers);
170 ut_assert(dev);
171 state = dev_get_priv(dev);
172 ut_assert(!state->session);
173
174 /* Test RPC call asking for I2C service */
175 rc = open_session(dev, &session, &rpc_test_uuid);
176 ut_assert(!rc);
177 ut_assert(session == state->session);
178
179 /* Write buffer */
180 strncpy((char *)data, test_str, strlen(test_str));
181 rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
182 bus, chip, xfer_flags, data, sizeof(data));
183 ut_assert(!rc);
184
185 /* Read buffer */
186 rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
187 bus, chip, xfer_flags, data_from_eeprom,
188 sizeof(data_from_eeprom));
189 ut_assert(!rc);
190
191 /* Compare */
192 ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
193
194 rc = tee_close_session(dev, session);
195 ut_assert(!rc);
196 ut_assert(!state->session);
197
198 return rc;
199}
200
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100201static int dm_test_tee(struct unit_test_state *uts)
202{
203 struct test_tee_vars vars = { NULL, NULL };
204 int rc = test_tee(uts, &vars);
205
Igor Opaniuk40154e92021-01-25 14:28:43 +0200206 if (rc)
207 goto out;
208
209 if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
210 rc = test_tee_rpc(uts);
211out:
Jens Wiklander78c4b3e2018-10-29 11:41:35 +0100212 /* In case test_tee() asserts these may still remain allocated */
213 tee_shm_free(vars.reg_shm);
214 tee_shm_free(vars.alloc_shm);
215
216 return rc;
217}
Simon Glass1a92f832024-08-22 07:57:48 -0600218DM_TEST(dm_test_tee, UTF_SCAN_FDT);