1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <assert.h>
18 #include <interface/spi/spi_loopback.h>
19 #include <interface/spi/spi_test.h>
20 #include <lib/spi/client/spi.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/auxv.h>
25 #include <trusty/time.h>
26 #include <uapi/err.h>
27
28 #define TLOG_TAG "swspi-test"
29 #include <trusty_unittest.h>
30
31 #define MAX_NUM_CMDS 32
32 #define MAX_TOTAL_PAYLOAD 1024 * 1024 /* 1 MB */
33 #define TXRX_SIZE MAX_TOTAL_PAYLOAD
34 #define CLK_SPEED 1000000 /* 1 MHz */
35 #define PAGE_SIZE getauxval(AT_PAGESZ)
36
37 enum {
38 SPI_TEST_DEV_IDX = 0,
39 SPI_LOOPBACK_DEV_IDX = 1,
40 SPI_DEV_COUNT,
41 };
42
43 /*
44 * TODO: There is currently no way to close a SPI devices, so allocate global
45 * instances and open them once.
46 */
47 struct spi_test_dev {
48 struct spi_dev dev;
49 const char* name;
50 bool initialized;
51 bool loopback;
52 };
53
54 static struct spi_test_dev devs[SPI_DEV_COUNT] = {
55 /*
56 * This device calculates an 8-bit digest of TX buffer, seeds rand()
57 * with that digest, fills RX with random bytes, and sends it back to
58 * us. If we initiate a receive-only transfer, this device uses seed 0.
59 */
60 [SPI_TEST_DEV_IDX] =
61 {
62 .name = SPI_TEST_PORT,
63 },
64 [SPI_LOOPBACK_DEV_IDX] =
65 {
66 .name = SPI_LOOPBACK_PORT,
67 .loopback = true,
68 },
69 };
70
spi_dev_init_once(int idx)71 static int spi_dev_init_once(int idx) {
72 int rc;
73 struct spi_test_dev* test_dev;
74
75 test_dev = &devs[idx];
76 if (test_dev->initialized) {
77 return 0;
78 }
79
80 rc = spi_dev_open(&test_dev->dev, test_dev->name, MAX_NUM_CMDS,
81 MAX_TOTAL_PAYLOAD);
82
83 if (rc == NO_ERROR) {
84 test_dev->initialized = true;
85 }
86
87 return rc;
88 }
89
90 /* calculate an 8-bit digest of a buffer */
digest(uint8_t * buf,size_t sz)91 static uint8_t digest(uint8_t* buf, size_t sz) {
92 uint8_t digest = 0;
93
94 for (size_t i = 0; i < sz; i++) {
95 /* rotate right one bit */
96 digest = digest >> 1 | (digest & 0x1) << 7;
97 digest ^= buf[i];
98 }
99 return digest;
100 }
101
102 /* fill buffer with random bytes generated using a given seed */
rand_buf(uint8_t * buf,size_t sz,uint8_t seed)103 static void rand_buf(uint8_t* buf, size_t sz, uint8_t seed) {
104 /* seed RNG */
105 srand(seed);
106
107 for (size_t i = 0; i < sz; i++) {
108 buf[i] = rand() % 0xff;
109 }
110 }
111
exec_xfer(struct spi_test_dev * test_dev,size_t len)112 static int exec_xfer(struct spi_test_dev* test_dev, size_t len) {
113 /* contains expected received buffer from a data transfer */
114 static uint8_t result[TXRX_SIZE];
115
116 int rc;
117 void* tx = NULL;
118 void* rx = NULL;
119 size_t failed;
120 uint8_t tx_seed;
121 uint8_t rx_seed;
122 struct spi_dev* dev = &test_dev->dev;
123 bool loopback = test_dev->loopback;
124
125 rc = spi_add_set_clk_cmd(dev, CLK_SPEED, NULL);
126 EXPECT_EQ(rc, 0);
127
128 rc = spi_add_cs_assert_cmd(dev);
129 EXPECT_EQ(rc, 0);
130
131 rc = spi_add_data_xfer_cmd(dev, &tx, &rx, len);
132 EXPECT_EQ(rc, 0);
133
134 rc = spi_add_cs_deassert_cmd(dev);
135 EXPECT_EQ(rc, 0);
136
137 /* fill out TX and expected RX */
138 tx_seed = len % 0xff; /* to vary generated byte sequences a little */
139 rand_buf(tx, len, tx_seed);
140 if (loopback) {
141 memcpy(result, tx, len);
142 } else {
143 rx_seed = digest(tx, len);
144 rand_buf(result, len, rx_seed);
145 }
146
147 rc = spi_exec_cmds(dev, &failed);
148 EXPECT_EQ(rc, 0);
149
150 return memcmp(result, rx, len);
151 }
152
153 typedef struct {
154 struct spi_test_dev* test_dev;
155 } swspi_t;
156
TEST_F_SETUP(swspi)157 TEST_F_SETUP(swspi) {
158 int rc;
159 int idx = *((const int*)GetParam());
160 assert(0 <= idx && idx < SPI_DEV_COUNT);
161
162 rc = spi_dev_init_once(idx);
163 ASSERT_EQ(rc, 0);
164
165 _state->test_dev = &devs[idx];
166 spi_clear_cmds(&_state->test_dev->dev);
167
168 test_abort:;
169 }
170
TEST_F_TEARDOWN(swspi)171 TEST_F_TEARDOWN(swspi) {}
172
TEST_P(swspi,add_cmd)173 TEST_P(swspi, add_cmd) {
174 int rc;
175 void* tx = NULL;
176 void* rx = NULL;
177 uint64_t* clk_hz = NULL;
178 struct spi_dev* dev = &_state->test_dev->dev;
179
180 rc = spi_add_cs_assert_cmd(dev);
181 EXPECT_EQ(rc, 0);
182
183 rc = spi_add_data_xfer_cmd(dev, &tx, &rx, 1);
184 EXPECT_EQ(rc, 0);
185 EXPECT_NE(tx, NULL);
186 EXPECT_NE(rx, NULL);
187 tx = NULL;
188 rx = NULL;
189
190 rc = spi_add_data_xfer_cmd(dev, &tx, NULL, 1);
191 EXPECT_EQ(rc, 0);
192 EXPECT_NE(tx, NULL);
193 tx = NULL;
194
195 rc = spi_add_data_xfer_cmd(dev, NULL, &rx, 1);
196 EXPECT_EQ(rc, 0);
197 EXPECT_NE(rx, NULL);
198 rx = NULL;
199
200 rc = spi_add_data_xfer_cmd(dev, &tx, &tx, 1);
201 EXPECT_EQ(rc, 0);
202 EXPECT_NE(tx, NULL);
203 tx = NULL;
204
205 rc = spi_add_data_xfer_cmd(dev, NULL, NULL, 0);
206 EXPECT_EQ(rc, 0);
207
208 rc = spi_add_cs_deassert_cmd(dev);
209 EXPECT_EQ(rc, 0);
210
211 rc = spi_add_set_clk_cmd(dev, CLK_SPEED, NULL);
212 EXPECT_EQ(rc, 0);
213
214 rc = spi_add_set_clk_cmd(dev, CLK_SPEED, &clk_hz);
215 EXPECT_EQ(rc, 0);
216 }
217
TEST_P(swspi,add_cmd_null)218 TEST_P(swspi, add_cmd_null) {
219 /* NULL device */
220 int rc = spi_add_cs_assert_cmd(NULL);
221 EXPECT_EQ(rc, ERR_BAD_HANDLE);
222 }
223
TEST_P(swspi,add_cmd_out_of_bounds)224 TEST_P(swspi, add_cmd_out_of_bounds) {
225 int rc;
226 struct spi_dev* dev = &_state->test_dev->dev;
227
228 for (size_t i = 0; i < MAX_NUM_CMDS; i += 2) {
229 rc = spi_add_cs_assert_cmd(dev);
230 EXPECT_EQ(rc, 0);
231 rc = spi_add_cs_deassert_cmd(dev);
232 EXPECT_EQ(rc, 0);
233 }
234
235 rc = spi_add_cs_assert_cmd(dev);
236 EXPECT_EQ(rc, ERR_OUT_OF_RANGE);
237 }
238
TEST_P(swspi,add_xfer_too_big)239 TEST_P(swspi, add_xfer_too_big) {
240 int rc;
241 void* tx;
242 void* rx;
243 size_t failed;
244 struct spi_dev* dev = &_state->test_dev->dev;
245
246 rc = spi_add_cs_assert_cmd(dev);
247 EXPECT_EQ(rc, 0);
248
249 /* payload too big */
250 rc = spi_add_data_xfer_cmd(dev, &tx, &rx, MAX_TOTAL_PAYLOAD + 1);
251 EXPECT_EQ(rc, ERR_TOO_BIG);
252
253 /* also errors out because of the above error */
254 rc = spi_add_cs_deassert_cmd(dev);
255 EXPECT_LT(rc, 0);
256
257 rc = spi_exec_cmds(dev, &failed);
258 EXPECT_EQ(rc, ERR_BAD_STATE);
259 /* failed index should point to data xfer command */
260 EXPECT_EQ(failed, 1);
261 }
262
TEST_P(swspi,cs_double_assert)263 TEST_P(swspi, cs_double_assert) {
264 int rc;
265 size_t failed;
266 struct spi_dev* dev = &_state->test_dev->dev;
267
268 rc = spi_add_cs_assert_cmd(dev);
269 EXPECT_EQ(rc, 0);
270
271 /* should fail, because CS is already asserted */
272 rc = spi_add_cs_assert_cmd(dev);
273 EXPECT_EQ(rc, 0);
274
275 rc = spi_exec_cmds(dev, &failed);
276 EXPECT_LT(rc, 0);
277 /* failed index should point to the second assert command */
278 EXPECT_EQ(failed, 1);
279 }
280
TEST_P(swspi,cs_already_deasserted)281 TEST_P(swspi, cs_already_deasserted) {
282 int rc;
283 size_t failed;
284 struct spi_dev* dev = &_state->test_dev->dev;
285
286 /* should fail, because CS is already deasserted */
287 rc = spi_add_cs_deassert_cmd(dev);
288 EXPECT_EQ(rc, 0);
289
290 rc = spi_exec_cmds(dev, &failed);
291 EXPECT_LT(rc, 0);
292 EXPECT_EQ(failed, 0);
293 }
294
TEST_P(swspi,cs_shared_bus)295 TEST_P(swspi, cs_shared_bus) {
296 int rc;
297 size_t failed;
298 struct spi_dev* dev = &_state->test_dev->dev;
299 bool loopback = _state->test_dev->loopback;
300
301 /*
302 * Test device must be on a shared bus. That's not necessarily the case for
303 * a loopback device.
304 */
305 if (loopback) {
306 return;
307 }
308
309 /* swspi devices are on a shared bus, so CS can't be left asserted */
310 rc = spi_add_cs_assert_cmd(dev);
311 EXPECT_EQ(rc, 0);
312
313 rc = spi_exec_cmds(dev, &failed);
314 EXPECT_LT(rc, 0);
315 }
316
TEST_P(swspi,set_clk)317 TEST_P(swspi, set_clk) {
318 int rc;
319 uint64_t* clk_hz = NULL;
320 struct spi_dev* dev = &_state->test_dev->dev;
321
322 rc = spi_add_set_clk_cmd(dev, CLK_SPEED, &clk_hz);
323 EXPECT_EQ(rc, 0);
324
325 rc = spi_exec_cmds(dev, NULL);
326 EXPECT_EQ(rc, 0);
327
328 EXPECT_LE(*clk_hz, CLK_SPEED);
329 }
330
TEST_P(swspi,delay)331 TEST_P(swspi, delay) {
332 int rc;
333 struct spi_dev* dev = &_state->test_dev->dev;
334 uint64_t delay_ns = 1000000000; /* 1 second */
335 int64_t start_ns;
336 int64_t end_ns;
337
338 rc = spi_add_cs_assert_cmd(dev);
339 EXPECT_EQ(rc, 0);
340
341 rc = spi_add_delay_cmd(dev, delay_ns);
342 EXPECT_EQ(rc, 0);
343
344 rc = spi_add_cs_deassert_cmd(dev);
345 EXPECT_EQ(rc, 0);
346
347 trusty_gettime(0, &start_ns);
348 rc = spi_exec_cmds(dev, NULL);
349 trusty_gettime(0, &end_ns);
350
351 EXPECT_EQ(rc, 0);
352 EXPECT_GE(end_ns - start_ns, delay_ns);
353 }
354
TEST_P(swspi,single_data_xfer)355 TEST_P(swspi, single_data_xfer) {
356 struct spi_test_dev* test_dev = _state->test_dev;
357 int rc = exec_xfer(test_dev, 1);
358 EXPECT_EQ(rc, 0);
359 }
360
TEST_P(swspi,short_single_data_xfer)361 TEST_P(swspi, short_single_data_xfer) {
362 int rc;
363 size_t max_size = 10;
364 struct spi_test_dev* test_dev = _state->test_dev;
365
366 /* execute short xfers */
367 for (size_t i = 1; i <= max_size; i++) {
368 rc = exec_xfer(test_dev, i);
369 EXPECT_EQ(rc, 0, "size: %zu", i);
370 }
371 }
372
TEST_P(swspi,long_single_data_xfer)373 TEST_P(swspi, long_single_data_xfer) {
374 int rc;
375 struct spi_test_dev* test_dev = _state->test_dev;
376
377 /* execute longer xfer */
378 rc = exec_xfer(test_dev, 256);
379 EXPECT_EQ(rc, 0, "exec xfer 256");
380
381 rc = exec_xfer(test_dev, 512);
382 EXPECT_EQ(rc, 0, "exec xfer 512");
383
384 rc = exec_xfer(test_dev, 1024);
385 EXPECT_EQ(rc, 0, "exec xfer 1024");
386 }
387
TEST_P(swspi,very_large_data_xfer)388 TEST_P(swspi, very_large_data_xfer) {
389 int rc;
390 struct spi_test_dev* test_dev = _state->test_dev;
391
392 rc = exec_xfer(test_dev, MAX_TOTAL_PAYLOAD);
393 EXPECT_EQ(rc, 0);
394 }
395
TEST_P(swspi,multi_segment_xfer)396 TEST_P(swspi, multi_segment_xfer) {
397 int rc;
398 void* tx0;
399 void* tx1;
400 void* rx0;
401 void* rx1;
402 uint8_t expected0[128];
403 uint8_t expected1[64];
404 const size_t sz0 = sizeof(expected0);
405 const size_t sz1 = sizeof(expected1);
406 struct spi_dev* dev = &_state->test_dev->dev;
407 bool loopback = _state->test_dev->loopback;
408
409 rc = spi_add_cs_assert_cmd(dev);
410 EXPECT_EQ(rc, 0);
411
412 rc = spi_add_data_xfer_cmd(dev, &tx0, &rx0, sz0);
413 EXPECT_EQ(rc, 0);
414
415 rc = spi_add_data_xfer_cmd(dev, &tx1, &rx1, sz1);
416 EXPECT_EQ(rc, 0);
417
418 rc = spi_add_cs_deassert_cmd(dev);
419 EXPECT_EQ(rc, 0);
420
421 /* fill out TX buffers and expected RX buffers */
422 rand_buf(tx0, sz0, 0);
423 rand_buf(tx1, sz1, 1);
424 rand_buf(expected0, sz0, digest(tx0, sz0));
425 rand_buf(expected1, sz1, digest(tx1, sz1));
426
427 rc = spi_exec_cmds(dev, NULL);
428 EXPECT_EQ(rc, 0);
429
430 /* check data */
431 if (loopback) {
432 EXPECT_EQ(memcmp(tx0, rx0, sz0), 0);
433 EXPECT_EQ(memcmp(tx1, rx1, sz1), 0);
434 } else {
435 EXPECT_EQ(memcmp(expected0, rx0, sz0), 0);
436 EXPECT_EQ(memcmp(expected1, rx1, sz1), 0);
437 }
438 }
439
TEST_P(swspi,unidir_recv)440 TEST_P(swspi, unidir_recv) {
441 int rc;
442 void* rx;
443 uint8_t expected[128];
444 size_t sz = sizeof(expected);
445 struct spi_dev* dev = &_state->test_dev->dev;
446 bool loopback = _state->test_dev->loopback;
447
448 /* receive-only data transfers use seed 0 */
449 rand_buf(expected, sz, 0);
450
451 rc = spi_add_cs_assert_cmd(dev);
452 EXPECT_EQ(rc, 0);
453
454 rc = spi_add_data_xfer_cmd(dev, NULL, &rx, sz);
455 EXPECT_EQ(rc, 0);
456
457 rc = spi_add_cs_deassert_cmd(dev);
458 EXPECT_EQ(rc, 0);
459
460 rc = spi_exec_cmds(dev, NULL);
461 EXPECT_EQ(rc, 0);
462
463 /* check data */
464 if (!loopback) {
465 EXPECT_EQ(memcmp(expected, rx, sz), 0);
466 }
467 }
468
469 INSTANTIATE_TEST_SUITE_P(swspi, swspi, testing_Range(0, SPI_DEV_COUNT));
470
471 PORT_TEST(swspi, "com.android.trusty.swspi.test");
472