1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include "xtest_test.h"
11 #include "xtest_helpers.h"
12 
13 #include <ta_storage_benchmark.h>
14 #include <util.h>
15 
16 #define DO_VERIFY 0
17 #define DEFAULT_DATA_SIZE (2 * 1024 * 1024) /* 2MB */
18 #define DEFAULT_CHUNK_SIZE (1 * 1024) /* 1KB */
19 #define DEFAULT_COUNT (10)
20 
21 size_t data_size_table[] = {
22 	256,
23 	512,
24 	1024,
25 	2 * 1024,
26 	4 * 1024,
27 	16 * 1024,
28 	512 * 1024,
29 	1024 * 1024,
30 	0
31 };
32 
33 static void xtest_tee_benchmark_1001(ADBG_Case_t *Case_p);
34 static void xtest_tee_benchmark_1002(ADBG_Case_t *Case_p);
35 static void xtest_tee_benchmark_1003(ADBG_Case_t *Case_p);
36 
run_test_with_args(enum storage_benchmark_cmd cmd,uint32_t arg0,uint32_t arg1,uint32_t arg2,uint32_t arg3,uint32_t * out0,uint32_t * out1)37 static TEEC_Result run_test_with_args(enum storage_benchmark_cmd cmd,
38 		uint32_t arg0, uint32_t arg1, uint32_t arg2,
39 		uint32_t arg3, uint32_t *out0, uint32_t *out1)
40 {
41 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
42 	TEEC_Result res = TEEC_ERROR_GENERIC;
43 	TEEC_Session sess = { };
44 	uint32_t orig = 0;
45 
46 	res = xtest_teec_open_session(&sess, &storage_benchmark_ta_uuid, NULL, &orig);
47 	if (res != TEEC_SUCCESS)
48 		return res;
49 
50 	op.params[0].value.a = arg0;
51 	op.params[0].value.b = arg1;
52 	op.params[1].value.a = arg2;
53 	op.params[1].value.b = arg3;
54 
55 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
56 			TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT, TEEC_NONE);
57 
58 	res = TEEC_InvokeCommand(&sess, cmd, &op, &orig);
59 
60 	if (out0)
61 		*out0 = op.params[2].value.a;
62 	if (out1)
63 		*out1 = op.params[2].value.b;
64 
65 	TEEC_CloseSession(&sess);
66 
67 	return res;
68 }
69 
70 struct test_record {
71 	size_t data_size;
72 	float spent_time;
73 	float speed_in_kb;
74 };
75 
run_chunk_access_test(enum storage_benchmark_cmd cmd,uint32_t data_size,uint32_t chunk_size,struct test_record * rec)76 static TEEC_Result run_chunk_access_test(enum storage_benchmark_cmd cmd,
77 		uint32_t data_size, uint32_t chunk_size, struct test_record *rec)
78 {
79 	TEE_Result res = TEEC_ERROR_GENERIC;
80 	uint32_t spent_time = 0;
81 
82 	res = run_test_with_args(cmd, data_size, chunk_size, DO_VERIFY, 0,
83 				&spent_time, NULL);
84 
85 	rec->data_size = data_size;
86 	rec->spent_time = (float)spent_time / 1000.0;
87 	rec->speed_in_kb = ((float)data_size / 1024.0) / rec->spent_time;
88 
89 	return res;
90 }
91 
show_test_result(struct test_record records[],size_t size)92 static void show_test_result(struct test_record records[], size_t size)
93 {
94 	size_t i = 0;
95 
96 	printf("-----------------+---------------+----------------\n");
97 	printf(" Data Size (B) \t | Time (s)\t | Speed (kB/s)\t \n");
98 	printf("-----------------+---------------+----------------\n");
99 
100 	for (i = 0; i < size; i++) {
101 		printf(" %8zd \t | %8.3f \t | %8.3f\n",
102 			records[i].data_size, records[i].spent_time,
103 			records[i].speed_in_kb);
104 	}
105 
106 	printf("-----------------+---------------+----------------\n");
107 
108 }
109 
chunk_test(ADBG_Case_t * c,enum storage_benchmark_cmd cmd)110 static void chunk_test(ADBG_Case_t *c, enum storage_benchmark_cmd cmd)
111 {
112 	uint32_t chunk_size = DEFAULT_CHUNK_SIZE;
113 	struct test_record records[ARRAY_SIZE(data_size_table) - 1];
114 	size_t i = 0;
115 
116 	for (i = 0; data_size_table[i]; i++) {
117 		ADBG_EXPECT_TEEC_SUCCESS(c,
118 			run_chunk_access_test(cmd, data_size_table[i],
119 				chunk_size, &records[i]));
120 	}
121 
122 	show_test_result(records, ARRAY_SIZE(records));
123 }
124 
xtest_tee_benchmark_1001(ADBG_Case_t * c)125 static void xtest_tee_benchmark_1001(ADBG_Case_t *c)
126 {
127 	chunk_test(c, TA_STORAGE_BENCHMARK_CMD_TEST_WRITE);
128 }
129 
xtest_tee_benchmark_1002(ADBG_Case_t * c)130 static void xtest_tee_benchmark_1002(ADBG_Case_t *c)
131 {
132 	chunk_test(c, TA_STORAGE_BENCHMARK_CMD_TEST_READ);
133 }
134 
xtest_tee_benchmark_1003(ADBG_Case_t * c)135 static void xtest_tee_benchmark_1003(ADBG_Case_t *c)
136 {
137 	chunk_test(c, TA_STORAGE_BENCHMARK_CMD_TEST_REWRITE);
138 }
139 
140 ADBG_CASE_DEFINE(benchmark, 1001, xtest_tee_benchmark_1001,
141 		"TEE Trusted Storage Performance Test (WRITE)");
142 ADBG_CASE_DEFINE(benchmark, 1002, xtest_tee_benchmark_1002,
143 		"TEE Trusted Storage Performance Test (READ)");
144 ADBG_CASE_DEFINE(benchmark, 1003, xtest_tee_benchmark_1003,
145 		"TEE Trusted Storage Performance Test (REWRITE)");
146