1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022, Linaro Limited
4  *
5  * Tests introduce dummy test drivers and assiciated devices defined in
6  * dt_driver_test.dtsi file with device resource dependencies.
7  */
8 
9 #include <assert.h>
10 #include <config.h>
11 #include <crypto/crypto.h>
12 #include <drivers/clk.h>
13 #include <drivers/clk_dt.h>
14 #include <drivers/rstctrl.h>
15 #include <initcall.h>
16 #include <kernel/dt.h>
17 #include <kernel/dt_driver.h>
18 #include <libfdt.h>
19 #include <malloc.h>
20 #include <sys/queue.h>
21 #include <tee_api_defines_extensions.h>
22 #include <tee_api_types.h>
23 
24 #define DT_TEST_MSG(...)	FMSG("(dt-driver-test) " __VA_ARGS__)
25 
26 /* Test state IDs */
27 enum dt_test_sid { DEFAULT = 0, IN_PROGRESS, SUCCESS, FAILED };
28 
29 /*
30  * DT tests state to be reported from PTA_INVOKE_TESTS_CMD_DT_TEST_STATUS
31  * possibly printed to console. A test can be skipped (DEFAULT) or be
32  * successful (SUCCESS) orthewise it has failed (IN_PROGRESS, FAILED).
33  */
34 struct dt_test_state {
35 	enum dt_test_sid probe_deferral;
36 	enum dt_test_sid probe_clocks;
37 	enum dt_test_sid probe_resets;
38 	enum dt_test_sid crypto_dependencies;
39 };
40 
41 /*
42  * References allocated from heap to be free once test completed
43  * dt_test_alloc(), dt_test_free(), dt_test_free_all()
44  */
45 struct dt_test_free_ref {
46 	void *p;
47 	SLIST_ENTRY(dt_test_free_ref) link;
48 };
49 
50 static struct dt_test_state dt_test_state;
51 
52 static const char __maybe_unused * const dt_test_str_sid[] = {
53 	[DEFAULT] = "not passed",
54 	[IN_PROGRESS] = "in-progress",
55 	[SUCCESS] = "successful",
56 	[FAILED] = "failed",
57 };
58 
59 /* Reference allocations during test for release_init_resource initcall level */
60 static SLIST_HEAD(dt_test_free_refs, dt_test_free_ref) dt_test_free_list =
61 	SLIST_HEAD_INITIALIZER(dt_test_free_list);
62 
dt_test_alloc(size_t size)63 static void __maybe_unused *dt_test_alloc(size_t size)
64 {
65 	struct dt_test_free_ref *ref = NULL;
66 
67 	ref = calloc(1, sizeof(*ref) + size);
68 	if (!ref)
69 		return NULL;
70 
71 	ref->p = ref + 1;
72 	SLIST_INSERT_HEAD(&dt_test_free_list, ref, link);
73 
74 	return ref->p;
75 }
76 
dt_test_free(void * p)77 static void __maybe_unused dt_test_free(void *p)
78 {
79 	struct dt_test_free_ref *ref = NULL;
80 	struct dt_test_free_ref *t_ref = NULL;
81 
82 	if (!p)
83 		return;
84 
85 	SLIST_FOREACH_SAFE(ref, &dt_test_free_list, link, t_ref) {
86 		if (ref->p == p) {
87 			SLIST_REMOVE(&dt_test_free_list, ref,
88 				     dt_test_free_ref, link);
89 			free(ref);
90 			return;
91 		}
92 	}
93 
94 	panic();
95 }
96 
dt_test_free_all(void)97 static void dt_test_free_all(void)
98 {
99 	while (!SLIST_EMPTY(&dt_test_free_list)) {
100 		struct dt_test_free_ref *ref = SLIST_FIRST(&dt_test_free_list);
101 
102 		SLIST_REMOVE(&dt_test_free_list, ref, dt_test_free_ref, link);
103 		free(ref);
104 	}
105 }
106 
dt_test_release(void)107 static TEE_Result dt_test_release(void)
108 {
109 	dt_test_free_all();
110 
111 	DT_TEST_MSG("Probe deferral: %s",
112 		    dt_test_str_sid[dt_test_state.probe_deferral]);
113 	DT_TEST_MSG("Clocks probe: %s",
114 		    dt_test_str_sid[dt_test_state.probe_clocks]);
115 	DT_TEST_MSG("Reset ctrl probe: %s",
116 		    dt_test_str_sid[dt_test_state.probe_resets]);
117 	DT_TEST_MSG("Crypto deps.: %s",
118 		    dt_test_str_sid[dt_test_state.crypto_dependencies]);
119 
120 	return dt_driver_test_status();
121 }
122 
123 release_init_resource(dt_test_release);
124 
dt_driver_test_status(void)125 TEE_Result dt_driver_test_status(void)
126 {
127 	TEE_Result res = TEE_SUCCESS;
128 
129 	if (dt_test_state.probe_deferral != SUCCESS) {
130 		EMSG("Probe deferral test failed");
131 		res = TEE_ERROR_GENERIC;
132 	}
133 	if (IS_ENABLED(CFG_DRIVERS_CLK) &&
134 	    dt_test_state.probe_clocks != SUCCESS) {
135 		EMSG("Clocks probing test failed");
136 		res = TEE_ERROR_GENERIC;
137 	}
138 	if (IS_ENABLED(CFG_DRIVERS_RSTCTRL) &&
139 	    dt_test_state.probe_resets != SUCCESS) {
140 		EMSG("Reset controllers probing test failed");
141 		res = TEE_ERROR_GENERIC;
142 	}
143 	if (dt_test_state.crypto_dependencies != SUCCESS) {
144 		EMSG("Probe deferral on crypto dependencies test failed");
145 		res = TEE_ERROR_GENERIC;
146 	}
147 
148 	return res;
149 }
150 
151 /*
152  * Consumer test driver: instance probed from the compatible
153  * node parsed in the DT. It consumes emulated resource obtained
154  * from DT references. Probe shall succeed only once all resources
155  * are found.
156  */
dt_test_consumer_probe(const void * fdt,int node,const void * compat_data __unused)157 static TEE_Result dt_test_consumer_probe(const void *fdt, int node,
158 					 const void *compat_data __unused)
159 {
160 	TEE_Result res = TEE_ERROR_GENERIC;
161 
162 	if (IS_ENABLED(CFG_DRIVERS_CLK)) {
163 		struct clk *clk0 = NULL;
164 		struct clk *clk1 = NULL;
165 		struct clk *clk = NULL;
166 
167 		DT_TEST_MSG("Probe clocks");
168 
169 		res = clk_dt_get_by_index(fdt, node, 0, &clk0);
170 		if (res)
171 			goto err_probe;
172 		res = clk_dt_get_by_index(fdt, node, 1, &clk1);
173 		if (res)
174 			goto err_probe;
175 
176 		DT_TEST_MSG("Check valid clock references");
177 
178 		if (clk_enable(clk0)) {
179 			DT_TEST_MSG("Can't enable %s", clk_get_name(clk0));
180 			return TEE_ERROR_GENERIC;
181 		}
182 		clk_disable(clk0);
183 
184 		res = clk_dt_get_by_name(fdt, node, "clk0", &clk);
185 		if (res || clk != clk0) {
186 			DT_TEST_MSG("Unexpected clock reference");
187 			return TEE_ERROR_GENERIC;
188 		}
189 
190 		res = clk_dt_get_by_name(fdt, node, "clk1", &clk);
191 		if (res || clk != clk1) {
192 			DT_TEST_MSG("Unexpected clock reference");
193 			return TEE_ERROR_GENERIC;
194 		}
195 
196 		DT_TEST_MSG("Bad clock reference");
197 
198 		res = clk_dt_get_by_index(fdt, node, 3, &clk);
199 		if (!res) {
200 			DT_TEST_MSG("Unexpected clock found on invalid index");
201 			return TEE_ERROR_GENERIC;
202 		}
203 
204 		res = clk_dt_get_by_name(fdt, node, "clk2", &clk);
205 		if (!res) {
206 			DT_TEST_MSG("Unexpected clock found on invalid name");
207 			return TEE_ERROR_GENERIC;
208 		}
209 
210 		dt_test_state.probe_clocks = SUCCESS;
211 	}
212 
213 	if (IS_ENABLED(CFG_DRIVERS_RSTCTRL)) {
214 		struct rstctrl *rstctrl0 = NULL;
215 		struct rstctrl *rstctrl1 = NULL;
216 		struct rstctrl *rstctrl = NULL;
217 
218 		DT_TEST_MSG("Probe reset controllers");
219 
220 		res = rstctrl_dt_get_by_index(fdt, node, 0, &rstctrl0);
221 		if (res)
222 			goto err_probe;
223 
224 		DT_TEST_MSG("Check valid reset controller");
225 
226 		if (rstctrl_assert(rstctrl0)) {
227 			EMSG("Can't assert rstctrl %s", rstctrl_name(rstctrl0));
228 			return TEE_ERROR_GENERIC;
229 		}
230 
231 		res = rstctrl_dt_get_by_name(fdt, node, "rst0", &rstctrl);
232 		if (res)
233 			return res;
234 
235 		if (rstctrl != rstctrl0) {
236 			EMSG("Unexpected reset controller reference");
237 			return TEE_ERROR_GENERIC;
238 		}
239 
240 		res = rstctrl_dt_get_by_name(fdt, node, "rst1", &rstctrl1);
241 		if (res)
242 			goto err_probe;
243 
244 		if (!rstctrl1 || rstctrl1 == rstctrl0) {
245 			EMSG("Unexpected reset controller reference");
246 			return TEE_ERROR_GENERIC;
247 		}
248 
249 		dt_test_state.probe_resets = SUCCESS;
250 	}
251 
252 	if (dt_test_state.probe_deferral != IN_PROGRESS) {
253 		dt_test_state.probe_deferral = FAILED;
254 		return TEE_ERROR_GENERIC;
255 	}
256 
257 	dt_test_state.probe_deferral = SUCCESS;
258 
259 	return TEE_SUCCESS;
260 
261 err_probe:
262 	assert(res);
263 
264 	if (res == TEE_ERROR_DEFER_DRIVER_INIT &&
265 	    dt_test_state.probe_deferral == DEFAULT) {
266 		/* We expect at least a probe deferral */
267 		dt_test_state.probe_deferral = IN_PROGRESS;
268 	}
269 
270 	return res;
271 }
272 
273 static const struct dt_device_match dt_test_consumer_match_table[] = {
274 	{ .compatible = "linaro,dt-test-consumer", },
275 	{ }
276 };
277 
278 DEFINE_DT_DRIVER(dt_test_consumer_driver) = {
279 	.name = "dt-test-consumer",
280 	.match_table = dt_test_consumer_match_table,
281 	.probe = dt_test_consumer_probe,
282 };
283 
dt_test_crypt_consumer_probe(const void * fdt __unused,int node __unused,const void * compat_data __unused)284 static TEE_Result dt_test_crypt_consumer_probe(const void *fdt __unused,
285 					       int node __unused,
286 					       const void *compat_data __unused)
287 {
288 	TEE_Result res = dt_driver_get_crypto();
289 	uint8_t __maybe_unused byte = 0;
290 
291 	if (res == TEE_ERROR_DEFER_DRIVER_INIT &&
292 	    dt_test_state.crypto_dependencies == DEFAULT) {
293 		/* We expect to be deferred */
294 		dt_test_state.crypto_dependencies = IN_PROGRESS;
295 	}
296 
297 	if (res)
298 		return res;
299 
300 	if (dt_test_state.crypto_dependencies == DEFAULT) {
301 		EMSG("Test expects at least a driver probe deferral");
302 		dt_test_state.crypto_dependencies = FAILED;
303 		return TEE_ERROR_GENERIC;
304 	}
305 
306 	if (crypto_rng_read(&byte, sizeof(byte))) {
307 		dt_test_state.crypto_dependencies = FAILED;
308 		return TEE_ERROR_GENERIC;
309 	}
310 
311 	dt_test_state.crypto_dependencies = SUCCESS;
312 	return TEE_SUCCESS;
313 }
314 
315 static const struct dt_device_match dt_test_crypt_consumer_match_table[] = {
316 	{ .compatible = "linaro,dt-test-crypt-consumer", },
317 	{ }
318 };
319 
320 DEFINE_DT_DRIVER(dt_test_consumer_driver) = {
321 	.name = "dt-test-crypt-consumer",
322 	.match_table = dt_test_crypt_consumer_match_table,
323 	.probe = dt_test_crypt_consumer_probe,
324 };
325 
326 #ifdef CFG_DRIVERS_CLK
327 #define DT_TEST_CLK_COUNT		2
328 
329 #define DT_TEST_CLK0_BINDING_ID		3
330 #define DT_TEST_CLK1_BINDING_ID		7
331 
332 static const char *dt_test_clk_name[DT_TEST_CLK_COUNT] = {
333 	"dt_test-clk3",
334 	"dt_test-clk7",
335 };
336 
337 /* Emulating a clock does not require operators */
338 static const struct clk_ops dt_test_clock_provider_ops;
339 
dt_test_get_clk(struct dt_driver_phandle_args * args,void * data,TEE_Result * res)340 static struct clk *dt_test_get_clk(struct dt_driver_phandle_args *args,
341 				   void *data, TEE_Result *res)
342 {
343 	struct clk *clk_ref = data;
344 	struct clk *clk = NULL;
345 
346 	if (args->args_count != 1) {
347 		*res = TEE_ERROR_BAD_PARAMETERS;
348 		return NULL;
349 	}
350 
351 	switch (args->args[0]) {
352 	case DT_TEST_CLK0_BINDING_ID:
353 		clk = clk_ref;
354 		break;
355 	case DT_TEST_CLK1_BINDING_ID:
356 		clk = clk_ref + 1;
357 		break;
358 	default:
359 		EMSG("Unexpected binding ID %"PRIu32, args->args[0]);
360 		*res = TEE_ERROR_BAD_PARAMETERS;
361 		return NULL;
362 	}
363 
364 	DT_TEST_MSG("Providing clock %s", clk_get_name(clk));
365 
366 	*res = TEE_SUCCESS;
367 	return clk;
368 }
369 
dt_test_clock_provider_probe(const void * fdt,int node,const void * compat_data __unused)370 static TEE_Result dt_test_clock_provider_probe(const void *fdt, int node,
371 					       const void *compat_data __unused)
372 {
373 	TEE_Result res = TEE_ERROR_GENERIC;
374 	struct clk *clk = NULL;
375 	size_t n = 0;
376 
377 	DT_TEST_MSG("Register clocks");
378 
379 	clk = dt_test_alloc(DT_TEST_CLK_COUNT * sizeof(*clk));
380 	if (!clk)
381 		return TEE_ERROR_OUT_OF_MEMORY;
382 
383 	for (n = 0; n < DT_TEST_CLK_COUNT; n++) {
384 		clk[n].ops = &dt_test_clock_provider_ops;
385 		clk[n].name = dt_test_clk_name[n];
386 
387 		res = clk_register(clk + n);
388 		if (res)
389 			goto err;
390 	}
391 
392 	res = clk_dt_register_clk_provider(fdt, node, dt_test_get_clk, clk);
393 	if (res)
394 		goto err;
395 
396 	return TEE_SUCCESS;
397 
398 err:
399 	dt_test_free(clk);
400 	return res;
401 }
402 
403 CLK_DT_DECLARE(dt_test_clock_provider, "linaro,dt-test-provider",
404 	       dt_test_clock_provider_probe);
405 #endif /* CFG_DRIVERS_CLK */
406 
407 #ifdef CFG_DRIVERS_RSTCTRL
408 #define DT_TEST_RSTCTRL_COUNT		2
409 
410 #define DT_TEST_RSTCTRL0_BINDING_ID	5
411 #define DT_TEST_RSTCTRL1_BINDING_ID	35
412 
413 struct dt_test_rstctrl {
414 	unsigned int dt_binding;
415 	struct rstctrl rstctrl;
416 };
417 
to_test_rstctrl(struct rstctrl * rstctrl)418 static struct dt_test_rstctrl *to_test_rstctrl(struct rstctrl *rstctrl)
419 {
420 	return container_of(rstctrl, struct dt_test_rstctrl, rstctrl);
421 }
422 
dt_test_rstctrl_stub(struct rstctrl * rstctrl __maybe_unused,unsigned int to_us __unused)423 static TEE_Result dt_test_rstctrl_stub(struct rstctrl *rstctrl __maybe_unused,
424 				       unsigned int to_us __unused)
425 {
426 	struct dt_test_rstctrl *dev = to_test_rstctrl(rstctrl);
427 
428 	switch (dev->dt_binding) {
429 	case DT_TEST_RSTCTRL0_BINDING_ID:
430 	case DT_TEST_RSTCTRL1_BINDING_ID:
431 		return TEE_SUCCESS;
432 	default:
433 		EMSG("Unexpected rstctrl reference");
434 		return TEE_ERROR_GENERIC;
435 	}
436 }
437 
dt_test_rstctrl_name(struct rstctrl * rstctrl __maybe_unused)438 static const char *dt_test_rstctrl_name(struct rstctrl *rstctrl __maybe_unused)
439 {
440 	static const char *rstctrl_name[DT_TEST_RSTCTRL_COUNT] = {
441 		"dt_test-rstctrl5",
442 		"dt_test-rstctrl35",
443 	};
444 	struct dt_test_rstctrl *dev = to_test_rstctrl(rstctrl);
445 
446 	switch (dev->dt_binding) {
447 	case DT_TEST_RSTCTRL0_BINDING_ID:
448 		return rstctrl_name[0];
449 	case DT_TEST_RSTCTRL1_BINDING_ID:
450 		return rstctrl_name[1];
451 	default:
452 		EMSG("Unexpected rstctrl reference");
453 		return NULL;
454 	}
455 }
456 
457 const struct rstctrl_ops dt_test_rstctrl_ops = {
458 	.assert_level = dt_test_rstctrl_stub,
459 	.deassert_level = dt_test_rstctrl_stub,
460 	.get_name = dt_test_rstctrl_name,
461 };
462 
dt_test_get_rstctrl(struct dt_driver_phandle_args * args,void * data,TEE_Result * res)463 static struct rstctrl *dt_test_get_rstctrl(struct dt_driver_phandle_args *args,
464 					   void *data, TEE_Result *res)
465 {
466 	struct dt_test_rstctrl *ref = data;
467 	struct rstctrl *rstctrl = NULL;
468 
469 	if (args->args_count != 1) {
470 		*res = TEE_ERROR_BAD_PARAMETERS;
471 		return NULL;
472 	}
473 
474 	switch (args->args[0]) {
475 	case DT_TEST_RSTCTRL0_BINDING_ID:
476 		rstctrl = &ref[0].rstctrl;
477 		break;
478 	case DT_TEST_RSTCTRL1_BINDING_ID:
479 		rstctrl = &ref[1].rstctrl;
480 		break;
481 	default:
482 		EMSG("Unexpected binding ID %"PRIu32, args->args[0]);
483 		*res = TEE_ERROR_BAD_PARAMETERS;
484 		return NULL;
485 	}
486 
487 	DT_TEST_MSG("Providing reset controller %s", rstctrl_name(rstctrl));
488 
489 	*res = TEE_SUCCESS;
490 	return rstctrl;
491 }
492 
dt_test_rstctrl_provider_probe(const void * fdt,int offs,const void * data __unused)493 static TEE_Result dt_test_rstctrl_provider_probe(const void *fdt, int offs,
494 						 const void *data __unused)
495 {
496 	TEE_Result res = TEE_ERROR_GENERIC;
497 	struct dt_test_rstctrl *devices = NULL;
498 
499 	DT_TEST_MSG("Register reset controllers");
500 
501 	assert(rstctrl_ops_is_valid(&dt_test_rstctrl_ops));
502 
503 	devices = dt_test_alloc(DT_TEST_RSTCTRL_COUNT * sizeof(*devices));
504 	if (!devices)
505 		return TEE_ERROR_OUT_OF_MEMORY;
506 
507 	devices[0].rstctrl.ops = &dt_test_rstctrl_ops;
508 	devices[0].dt_binding = DT_TEST_RSTCTRL0_BINDING_ID;
509 
510 	devices[1].rstctrl.ops = &dt_test_rstctrl_ops;
511 	devices[1].dt_binding = DT_TEST_RSTCTRL1_BINDING_ID;
512 
513 	res = rstctrl_register_provider(fdt, offs, dt_test_get_rstctrl,
514 					devices);
515 	if (res) {
516 		dt_test_free(devices);
517 		return res;
518 	}
519 
520 	return TEE_SUCCESS;
521 }
522 
523 RSTCTRL_DT_DECLARE(dt_test_rstctrl_provider, "linaro,dt-test-provider",
524 		   dt_test_rstctrl_provider_probe);
525 #endif /* CFG_DRIVERS_RSTCTRL */
526