1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2022, Arm Limited. All rights reserved.
4  */
5 
6 #include <CppUTestExt/MockSupport.h>
7 #include <CppUTest/TestHarness.h>
8 #include "mock_sp_memory_management.h"
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 static const struct sp_memory_descriptor expected_descriptor = {
14 	.sender_id = 0xfedc,
15 	.memory_type = sp_memory_type_normal_memory,
16 	.mem_region_attr = {.normal_memory = {
17 		.cacheability = sp_cacheability_write_back,
18 		.shareability = sp_shareability_inner_shareable
19 	}},
20 	.flags = {
21 		.zero_memory = true,
22 		.operation_time_slicing = true,
23 		.zero_memory_after_relinquish = true,
24 		.transaction_type = sp_memory_transaction_type_relayer_specified,
25 		.alignment_hint = 0x2000
26 	},
27 	.tag = 0x0123456789abcdefULL
28 };
29 static const struct sp_memory_access_descriptor expected_acc_desc[] = {
30 	{
31 		.receiver_id = 0xfafa,
32 		.instruction_access = sp_instruction_access_executable,
33 		.data_access = sp_data_access_read_only
34 	}, {
35 		.receiver_id = 0xc1ca,
36 		.instruction_access = sp_instruction_access_not_executable,
37 		.data_access = sp_data_access_read_write
38 	}
39 };
40 static const struct sp_memory_region expected_regions[2] = {
41 	{.address = (void *)0x01234567, .page_count = 0x89abcdef},
42 	{.address = (void *)0x12345670, .page_count = 0x9abcdef8},
43 };
44 static const uint64_t expected_handle = 0xabcdef0123456789ULL;
45 static const void *expected_address = (const void *)0x234567879;
46 static const struct sp_mem_perm expected_mem_perm = {
47 	.data_access = sp_mem_perm_data_perm_read_write,
48 	.instruction_access = sp_mem_perm_instruction_perm_non_executable,
49 };
50 
TEST_GROUP(mock_sp_memory_management)51 TEST_GROUP(mock_sp_memory_management)
52 {
53 	TEST_SETUP()
54 	{
55 		memset(&descriptor, 0x00, sizeof(descriptor));
56 		memset(&acc_desc, 0x00, sizeof(acc_desc));
57 		memset(&regions, 0x00, sizeof(regions));
58 		handle = 0;
59 		supported = false;
60 	}
61 
62 	TEST_TEARDOWN()
63 	{
64 		mock().checkExpectations();
65 		mock().clear();
66 	}
67 
68 	struct sp_memory_descriptor descriptor;
69 	struct sp_memory_access_descriptor acc_desc[2];
70 	struct sp_memory_region regions[2];
71 	uint64_t handle;
72 	bool supported;
73 	struct ffa_mem_transaction_buffer tr_buffer;
74 
75 	static const sp_result result = -1;
76 };
77 
TEST(mock_sp_memory_management,sp_memory_donate)78 TEST(mock_sp_memory_management, sp_memory_donate)
79 {
80 	descriptor = expected_descriptor;
81 	acc_desc[0] = expected_acc_desc[0];
82 	memcpy(regions, expected_regions, sizeof(regions));
83 
84 	expect_sp_memory_donate(&expected_descriptor, expected_acc_desc, expected_regions, 2,
85 				&expected_handle, result);
86 	LONGS_EQUAL(result, sp_memory_donate(&descriptor, acc_desc, regions, 2, &handle));
87 
88 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
89 }
90 
TEST(mock_sp_memory_management,sp_memory_donate_dynamic)91 TEST(mock_sp_memory_management, sp_memory_donate_dynamic)
92 {
93 	descriptor = expected_descriptor;
94 	acc_desc[0] = expected_acc_desc[0];
95 	memcpy(regions, expected_regions, sizeof(regions));
96 
97 	expect_sp_memory_donate_dynamic(&expected_descriptor, expected_acc_desc, expected_regions,
98 					2, &expected_handle, result);
99 	LONGS_EQUAL(result, sp_memory_donate_dynamic(&descriptor, acc_desc, regions, 2, &handle,
100 						     &tr_buffer));
101 
102 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
103 }
104 
TEST(mock_sp_memory_management,sp_memory_donate_dynamic_is_supported)105 TEST(mock_sp_memory_management, sp_memory_donate_dynamic_is_supported)
106 {
107 	const bool expected_supported = true;
108 	expect_sp_memory_donate_dynamic_is_supported(&expected_supported, result);
109 	LONGS_EQUAL(result, sp_memory_donate_dynamic_is_supported(&supported));
110 	CHECK_TRUE(supported);
111 }
112 
TEST(mock_sp_memory_management,sp_memory_lend)113 TEST(mock_sp_memory_management, sp_memory_lend)
114 {
115 	descriptor = expected_descriptor;
116 	memcpy(acc_desc, expected_acc_desc, sizeof(acc_desc));
117 	memcpy(regions, expected_regions, sizeof(regions));
118 
119 	expect_sp_memory_lend(&descriptor, acc_desc, 2, regions, 2, &expected_handle, result);
120 	LONGS_EQUAL(result, sp_memory_lend(&descriptor, acc_desc, 2, regions, 2, &handle));
121 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
122 }
123 
TEST(mock_sp_memory_management,sp_memory_lend_dynamic)124 TEST(mock_sp_memory_management, sp_memory_lend_dynamic)
125 {
126 	descriptor = expected_descriptor;
127 	memcpy(acc_desc, expected_acc_desc, sizeof(acc_desc));
128 	memcpy(regions, expected_regions, sizeof(regions));
129 
130 	expect_sp_memory_lend_dynamic(&descriptor, acc_desc, 2, regions, 2, &expected_handle,
131 				      result);
132 	LONGS_EQUAL(result, sp_memory_lend_dynamic(&descriptor, acc_desc, 2, regions, 2, &handle,
133 						   &tr_buffer));
134 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
135 }
136 
TEST(mock_sp_memory_management,sp_memory_lend_dynamic_is_supported)137 TEST(mock_sp_memory_management, sp_memory_lend_dynamic_is_supported)
138 {
139 	const bool expected_supported = true;
140 	expect_sp_memory_lend_dynamic_is_supported(&expected_supported, result);
141 	LONGS_EQUAL(result, sp_memory_lend_dynamic_is_supported(&supported));
142 	CHECK_TRUE(supported);
143 }
144 
TEST(mock_sp_memory_management,sp_memory_share)145 TEST(mock_sp_memory_management, sp_memory_share)
146 {
147 	descriptor = expected_descriptor;
148 	memcpy(acc_desc, expected_acc_desc, sizeof(acc_desc));
149 	memcpy(regions, expected_regions, sizeof(regions));
150 
151 	expect_sp_memory_share(&descriptor, acc_desc, 2, regions, 2, &expected_handle, result);
152 	LONGS_EQUAL(result, sp_memory_share(&descriptor, acc_desc, 2, regions, 2, &handle));
153 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
154 }
155 
TEST(mock_sp_memory_management,sp_memory_share_dynamic)156 TEST(mock_sp_memory_management, sp_memory_share_dynamic)
157 {
158 	descriptor = expected_descriptor;
159 	memcpy(acc_desc, expected_acc_desc, sizeof(acc_desc));
160 	memcpy(regions, expected_regions, sizeof(regions));
161 
162 	expect_sp_memory_share_dynamic(&descriptor, acc_desc, 2, regions, 2, &expected_handle,
163 				      result);
164 	LONGS_EQUAL(result, sp_memory_share_dynamic(&descriptor, acc_desc, 2, regions, 2, &handle,
165 						   &tr_buffer));
166 	UNSIGNED_LONGLONGS_EQUAL(expected_handle, handle);
167 }
168 
TEST(mock_sp_memory_management,sp_memory_share_dynamic_is_supported)169 TEST(mock_sp_memory_management, sp_memory_share_dynamic_is_supported)
170 {
171 	const bool expected_supported = true;
172 	expect_sp_memory_share_dynamic_is_supported(&expected_supported, result);
173 	LONGS_EQUAL(result, sp_memory_share_dynamic_is_supported(&supported));
174 	CHECK_TRUE(supported);
175 }
176 
TEST(mock_sp_memory_management,sp_memory_retrieve)177 TEST(mock_sp_memory_management, sp_memory_retrieve)
178 {
179 	const uint32_t expected_region_count = 1;
180 	struct sp_memory_access_descriptor acc_desc = expected_acc_desc[0];
181 	struct sp_memory_region region = expected_regions[0];
182 	uint32_t out_region_count = 0;
183 
184 	descriptor = expected_descriptor;
185 
186 	expect_sp_memory_retrieve(&expected_descriptor, &expected_acc_desc[0],
187 				  &expected_acc_desc[1], &expected_regions[0],
188 				  &expected_regions[1], 1, &expected_region_count, expected_handle,
189 				  result);
190 	LONGS_EQUAL(result, sp_memory_retrieve(&descriptor, &acc_desc, &region, 1,
191 					       &out_region_count, expected_handle));
192 	MEMCMP_EQUAL(&acc_desc, &expected_acc_desc[1], sizeof(acc_desc));
193 	MEMCMP_EQUAL(&region, &expected_regions[1], sizeof(region));
194 	UNSIGNED_LONGS_EQUAL(expected_region_count, out_region_count);
195 }
196 
TEST(mock_sp_memory_management,sp_memory_retrieve_dynamic)197 TEST(mock_sp_memory_management, sp_memory_retrieve_dynamic)
198 {
199 	const uint32_t expected_region_count = 1;
200 	struct sp_memory_access_descriptor acc_desc = expected_acc_desc[0];
201 	struct sp_memory_region region = expected_regions[0];
202 	uint32_t out_region_count = 0;
203 
204 	descriptor = expected_descriptor;
205 
206 	expect_sp_memory_retrieve_dynamic(&expected_descriptor, &expected_acc_desc[0],
207 					  &expected_acc_desc[1], &expected_regions[0],
208 					  &expected_regions[1], 1, &expected_region_count,
209 					  expected_handle, result);
210 	LONGS_EQUAL(result, sp_memory_retrieve_dynamic(&descriptor, &acc_desc, &region, 1,
211 						       &out_region_count, expected_handle,
212 						       &tr_buffer));
213 	MEMCMP_EQUAL(&acc_desc, &expected_acc_desc[1], sizeof(acc_desc));
214 	MEMCMP_EQUAL(&region, &expected_regions[1], sizeof(region));
215 	UNSIGNED_LONGS_EQUAL(expected_region_count, out_region_count);
216 }
217 
TEST(mock_sp_memory_management,sp_memory_retrieve_dynamic_is_supported)218 TEST(mock_sp_memory_management, sp_memory_retrieve_dynamic_is_supported)
219 {
220 	const bool expected_supported = true;
221 	expect_sp_memory_retrieve_dynamic_is_supported(&expected_supported, result);
222 	LONGS_EQUAL(result, sp_memory_retrieve_dynamic_is_supported(&supported));
223 	CHECK_TRUE(supported);
224 }
225 
TEST(mock_sp_memory_management,sp_memory_relinquish)226 TEST(mock_sp_memory_management, sp_memory_relinquish)
227 {
228 	uint16_t endpoints[3] = {1, 2, 3};
229 	struct sp_memory_transaction_flags flags = {0}; // TODO: flags
230 
231 	expect_sp_memory_relinquish(expected_handle, endpoints, 3, &flags, result);
232 	LONGS_EQUAL(result, sp_memory_relinquish(expected_handle, endpoints, 3, &flags));
233 }
234 
TEST(mock_sp_memory_management,sp_memory_reclaim)235 TEST(mock_sp_memory_management, sp_memory_reclaim)
236 {
237 	uint32_t flags = 0xffffffff;
238 
239 	expect_sp_memory_reclaim(expected_handle, flags, result);
240 	LONGS_EQUAL(result, sp_memory_reclaim(expected_handle, flags));
241 }
242 
TEST(mock_sp_memory_management,sp_memory_permission_get)243 TEST(mock_sp_memory_management, sp_memory_permission_get)
244 {
245 	struct sp_mem_perm mem_perm;
246 
247 	memset(&mem_perm, 0x00, sizeof(mem_perm));
248 
249 	expect_sp_memory_permission_get(expected_address, &expected_mem_perm, result);
250 	LONGS_EQUAL(result, sp_memory_permission_get(expected_address, &mem_perm));
251 	MEMCMP_EQUAL(&expected_mem_perm, &mem_perm, sizeof(expected_mem_perm));
252 }
253 
TEST(mock_sp_memory_management,sp_memory_permission_set)254 TEST(mock_sp_memory_management, sp_memory_permission_set)
255 {
256 	size_t size = 0x7654;
257 
258 	expect_sp_memory_permission_set(expected_address, size, &expected_mem_perm, result);
259 	LONGS_EQUAL(result, sp_memory_permission_set(expected_address, size, &expected_mem_perm));
260 }
261