1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/init.h>
11 #include <zephyr/ztest.h>
12 #include <zephyr/sys/printk.h>
13 #include <zephyr/linker/sections.h>
14 #include "abstract_driver.h"
15 
16 
17 #define DUMMY_PORT_1    "dummy"
18 #define DUMMY_PORT_2    "dummy_driver"
19 #define DUMMY_NOINIT    "dummy_noinit"
20 #define BAD_DRIVER	"bad_driver"
21 #define DUMMY_DEINIT    "dummy_deinit"
22 
23 #define MY_DRIVER_A     "my_driver_A"
24 #define MY_DRIVER_B     "my_driver_B"
25 
26 #define FAKEDEFERDRIVER0	DEVICE_DT_GET(DT_PATH(fakedeferdriver_e7000000))
27 #define FAKEDEFERDRIVER1	DEVICE_DT_GET(DT_PATH(fakedeferdriver_e8000000))
28 
29 #define FAKEDRIVER0_NODEID    DT_PATH(fakedriver_e0000000)
30 #define FAKEDRIVER0_NODELABEL "fake_driver_label"
31 
32 /* A device without init call */
33 DEVICE_DEFINE(dummy_noinit, DUMMY_NOINIT, NULL, NULL, NULL, NULL,
34 	      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
35 
36 /* To access from userspace, the device needs an API. Use a dummy GPIO one */
37 static DEVICE_API(gpio, fakedeferdriverapi);
38 
39 /* Fake deferred devices */
40 DEVICE_DT_DEFINE(DT_INST(0, fakedeferdriver), NULL, NULL, NULL, NULL,
41 	      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
42 DEVICE_DT_DEFINE(DT_INST(1, fakedeferdriver), NULL, NULL, NULL, NULL,
43 	      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
44 	      &fakedeferdriverapi);
45 
46 /**
47  * @brief Test cases to verify device objects
48  *
49  * Verify zephyr device driver apis with different device types
50  *
51  * @defgroup kernel_device_tests Device
52  *
53  * @ingroup all_tests
54  *
55  * @{
56  */
57 
58 /**
59  * @brief Test device object binding
60  *
61  * Validates device binding for an existing and a non-existing device object.
62  * It creates a dummy_driver device object with basic init and configuration
63  * information and validates its binding.
64  *
65  * Validates three kinds situations of driver object:
66  * 1. A non-existing device object.
67  * 2. An existing device object with basic init and configuration information.
68  * 3. A failed init device object.
69  *
70  * @ingroup kernel_device_tests
71  *
72  * @see device_get_binding(), DEVICE_DEFINE()
73  */
ZTEST(device,test_dummy_device)74 ZTEST(device, test_dummy_device)
75 {
76 	const struct device *dev;
77 
78 	/* Validates device binding for a non-existing device object */
79 	dev = device_get_binding(DUMMY_PORT_1);
80 	zassert_is_null(dev);
81 
82 	/* Validates device binding for an existing device object */
83 	dev = device_get_binding(DUMMY_PORT_2);
84 	zassert_not_null(dev);
85 
86 	/* Validates device binding for an existing device object */
87 	dev = device_get_binding(DUMMY_NOINIT);
88 	zassert_not_null(dev);
89 
90 	/* device_get_binding() returns false for device object
91 	 * with failed init.
92 	 */
93 	dev = device_get_binding(BAD_DRIVER);
94 	zassert_is_null(dev);
95 }
96 
97 /**
98  * @brief Test device binding for existing device
99  *
100  * Validates device binding for an existing device object.
101  *
102  * @see device_get_binding(), DEVICE_DEFINE()
103  */
ZTEST_USER(device,test_dynamic_name)104 ZTEST_USER(device, test_dynamic_name)
105 {
106 	const struct device *mux;
107 	char name[sizeof(DUMMY_PORT_2)];
108 
109 	snprintk(name, sizeof(name), "%s", DUMMY_PORT_2);
110 	mux = device_get_binding(name);
111 	zassert_true(mux != NULL);
112 }
113 
114 /**
115  * @brief Test device binding for non-existing device
116  *
117  * Validates binding of a random device driver(non-defined driver) named
118  * "ANOTHER_BOGUS_NAME".
119  *
120  * @see device_get_binding(), DEVICE_DEFINE()
121  */
ZTEST_USER(device,test_bogus_dynamic_name)122 ZTEST_USER(device, test_bogus_dynamic_name)
123 {
124 	const struct device *mux;
125 	char name[64];
126 
127 	snprintk(name, sizeof(name), "ANOTHER_BOGUS_NAME");
128 	mux = device_get_binding(name);
129 	zassert_true(mux == NULL);
130 }
131 
132 /**
133  * @brief Test device binding for passing null name
134  *
135  * Validates device binding for device object when given dynamic name is null.
136  *
137  * @see device_get_binding(), DEVICE_DEFINE()
138  */
ZTEST_USER(device,test_null_dynamic_name)139 ZTEST_USER(device, test_null_dynamic_name)
140 {
141 	/* Supplying a NULL dynamic name may trigger a SecureFault and
142 	 * lead to system crash in TrustZone enabled Non-Secure builds.
143 	 */
144 #if defined(CONFIG_USERSPACE) && !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
145 	const struct device *mux;
146 	char *drv_name = NULL;
147 
148 	mux = device_get_binding(drv_name);
149 	zassert_equal(mux, 0);
150 #else
151 	ztest_test_skip();
152 #endif
153 }
154 
155 __pinned_bss
156 static struct init_record {
157 	bool pre_kernel;
158 	bool is_in_isr;
159 	bool is_pre_kernel;
160 	bool could_yield;
161 } init_records[4];
162 
163 __pinned_data
164 static struct init_record *rp = init_records;
165 
166 __pinned_func
add_init_record(bool pre_kernel)167 static int add_init_record(bool pre_kernel)
168 {
169 	rp->pre_kernel = pre_kernel;
170 	rp->is_pre_kernel = k_is_pre_kernel();
171 	rp->is_in_isr = k_is_in_isr();
172 	rp->could_yield = k_can_yield();
173 	++rp;
174 	return 0;
175 }
176 
177 __pinned_func
pre1_fn(void)178 static int pre1_fn(void)
179 {
180 	return add_init_record(true);
181 }
182 
183 __pinned_func
pre2_fn(void)184 static int pre2_fn(void)
185 {
186 	return add_init_record(true);
187 }
188 
post_fn(void)189 static int post_fn(void)
190 {
191 	return add_init_record(false);
192 }
193 
app_fn(void)194 static int app_fn(void)
195 {
196 	return add_init_record(false);
197 }
198 
199 SYS_INIT(pre1_fn, PRE_KERNEL_1, 0);
200 SYS_INIT(pre2_fn, PRE_KERNEL_2, 0);
201 SYS_INIT(post_fn, POST_KERNEL, 0);
202 SYS_INIT(app_fn, APPLICATION, 0);
203 
204 /* This is an error case which driver initializes failed in SYS_INIT .*/
null_driver_init(void)205 static int null_driver_init(void)
206 {
207 	return -EINVAL;
208 }
209 
210 SYS_INIT(null_driver_init, POST_KERNEL, 0);
211 
212 /**
213  * @brief Test detection of initialization before kernel services available.
214  *
215  * Confirms check is correct.
216  *
217  * @see k_is_pre_kernel()
218  */
ZTEST(device,test_pre_kernel_detection)219 ZTEST(device, test_pre_kernel_detection)
220 {
221 	struct init_record *rpe = rp;
222 
223 	zassert_equal(rp - init_records, 4U,
224 		      "bad record count");
225 	rp = init_records;
226 	while ((rp < rpe) && rp->pre_kernel) {
227 		zassert_equal(rp->is_in_isr, false,
228 			      "rec %zu isr", rp - init_records);
229 		zassert_equal(rp->is_pre_kernel, true,
230 			      "rec %zu pre-kernel", rp - init_records);
231 		zassert_equal(rp->could_yield, false,
232 			      "rec %zu could-yield", rp - init_records);
233 		++rp;
234 	}
235 	zassert_equal(rp - init_records, 2U,
236 		      "bad pre-kernel count");
237 
238 	while (rp < rpe) {
239 		zassert_equal(rp->is_in_isr, false,
240 			      "rec %zu isr", rp - init_records);
241 		zassert_equal(rp->is_pre_kernel, false,
242 			      "rec %zu post-kernel", rp - init_records);
243 		zassert_equal(rp->could_yield, true,
244 			      "rec %zu could-yield", rp - init_records);
245 		++rp;
246 	}
247 }
248 
249 /**
250  * @brief Test system device list query API.
251  *
252  * It queries the list of devices in the system, used to suspend or
253  * resume the devices in PM applications.
254  *
255  * @see z_device_get_all_static()
256  */
ZTEST(device,test_device_list)257 ZTEST(device, test_device_list)
258 {
259 	struct device const *devices;
260 	size_t devcount = z_device_get_all_static(&devices);
261 	bool found = false;
262 
263 	zassert_true(devcount > 0, "Should have at least one static device");
264 	zassert_not_null(devices);
265 	for (size_t i = 0; i < devcount; i++) {
266 		struct device const *dev = devices + i;
267 
268 		if (strcmp(dev->name, DUMMY_NOINIT) == 0) {
269 			found = true;
270 			break;
271 		}
272 	}
273 	zassert_true(found, "%s should be present in static device list", DUMMY_NOINIT);
274 }
275 
276 static int sys_init_counter;
277 
init_fn(void)278 static int init_fn(void)
279 {
280 	sys_init_counter++;
281 	return 0;
282 }
283 
284 SYS_INIT(init_fn, APPLICATION, 0);
285 SYS_INIT_NAMED(init1, init_fn, APPLICATION, 1);
286 SYS_INIT_NAMED(init2, init_fn, APPLICATION, 2);
287 SYS_INIT_NAMED(init3, init_fn, APPLICATION, 2);
288 SYS_INIT_NAMED(init4, init_fn, APPLICATION, 99);
289 SYS_INIT_NAMED(init5, init_fn, APPLICATION, 999);
290 
ZTEST(device,test_sys_init_multiple)291 ZTEST(device, test_sys_init_multiple)
292 {
293 	zassert_equal(sys_init_counter, 6, "");
294 }
295 
296 /* this is for storing sequence during initialization */
297 extern int init_level_sequence[4];
298 extern int init_priority_sequence[4];
299 extern int init_sub_priority_sequence[3];
300 extern unsigned int seq_level_cnt;
301 extern unsigned int seq_priority_cnt;
302 
303 /**
304  * @brief Test initialization level for device driver instances
305  *
306  * @details After the defined device instances have initialized, we check the
307  * sequence number that each driver stored during initialization. If the
308  * sequence of initial level stored is corresponding with our expectation, it
309  * means assigning the level for driver instance works.
310  *
311  * @ingroup kernel_device_tests
312  */
ZTEST(device,test_device_init_level)313 ZTEST(device, test_device_init_level)
314 {
315 	bool seq_correct = true;
316 
317 	/* we check if the stored executing sequence for different level is
318 	 * correct, and it should be 1, 2, 3
319 	 */
320 	for (int i = 0; i < 3; i++) {
321 		if (init_level_sequence[i] != (i + 1)) {
322 			seq_correct = false;
323 		}
324 	}
325 
326 	zassert_true((seq_correct == true),
327 			"init sequence is not correct");
328 }
329 
330 /**
331  * @brief Test initialization priorities for device driver instances
332  *
333  * @details After the defined device instances have initialized, we check the
334  * sequence number that each driver stored during initialization. If the
335  * sequence of initial priority stored is corresponding with our expectation, it
336  * means assigning the priority for driver instance works.
337  *
338  * @ingroup kernel_device_tests
339  */
ZTEST(device,test_device_init_priority)340 ZTEST(device, test_device_init_priority)
341 {
342 	bool sequence_correct = true;
343 
344 	/* we check if the stored pexecuting sequence for priority is correct,
345 	 * and it should be 1, 2, 3, 4
346 	 */
347 	for (int i = 0; i < 4; i++) {
348 		if (init_priority_sequence[i] != (i + 1)) {
349 			sequence_correct = false;
350 		}
351 	}
352 
353 	zassert_true((sequence_correct == true),
354 			"init sequence is not correct");
355 }
356 
357 /**
358  * @brief Test initialization sub-priorities for device driver instances
359  *
360  * @details After the defined device instances have initialized, we check the
361  * sequence number that each driver stored during initialization. If the
362  * sequence of initial priority stored is corresponding with our expectation, it
363  * means using the devicetree for sub-priority sorting works.
364  *
365  * @ingroup kernel_device_tests
366  */
ZTEST(device,test_device_init_sub_priority)367 ZTEST(device, test_device_init_sub_priority)
368 {
369 	/* fakedomain_1 depends on fakedomain_0 which depends on fakedomain_2,
370 	 * therefore we require that the initialisation runs in the reverse order.
371 	 */
372 	zassert_equal(init_sub_priority_sequence[0], 1, "");
373 	zassert_equal(init_sub_priority_sequence[1], 2, "");
374 	zassert_equal(init_sub_priority_sequence[2], 0, "");
375 }
376 
377 /**
378  * @brief Test abstraction of device drivers with common functionalities
379  *
380  * @details Abstraction of device drivers with common functionalities
381  * shall be provided as an intermediate interface between applications
382  * and device drivers, where such interface is implemented by individual
383  * device drivers. We verify this by following step:
384 
385  * 1. Define a subsystem api for drivers.
386  * 2. Define and create two driver instances.
387  * 3. Two drivers call the same subsystem API, and we verify that each
388  * driver instance will call their own implementations.
389  *
390  * @ingroup kernel_device_tests
391  */
ZTEST(device,test_abstraction_driver_common)392 ZTEST(device, test_abstraction_driver_common)
393 {
394 	const struct device *dev;
395 	int ret;
396 	int foo = 2;
397 	int bar = 1;
398 	unsigned int baz = 0;
399 
400 	/* verify driver A API has called */
401 	dev = device_get_binding(MY_DRIVER_A);
402 	zassert_false((dev == NULL));
403 
404 	ret = abstract_do_this(dev, foo, bar);
405 	zassert_true(ret == (foo + bar), "common API do_this fail");
406 
407 	abstract_do_that(dev, &baz);
408 	zassert_true(baz == 1, "common API do_that fail");
409 
410 	/* verify driver B API has called */
411 	dev = device_get_binding(MY_DRIVER_B);
412 	zassert_false((dev == NULL));
413 
414 	ret = abstract_do_this(dev, foo, bar);
415 	zassert_true(ret == (foo - bar), "common API do_this fail");
416 
417 	abstract_do_that(dev, &baz);
418 	zassert_true(baz == 2, "common API do_that fail");
419 }
420 
ZTEST(device,test_deferred_init)421 ZTEST(device, test_deferred_init)
422 {
423 	int ret;
424 
425 	zassert_false(device_is_ready(FAKEDEFERDRIVER0));
426 
427 	ret = device_init(FAKEDEFERDRIVER0);
428 	zassert_true(ret == 0);
429 
430 	zassert_true(device_is_ready(FAKEDEFERDRIVER0));
431 }
432 
ZTEST(device,test_device_api)433 ZTEST(device, test_device_api)
434 {
435 	const struct device *dev;
436 
437 	dev = device_get_binding(MY_DRIVER_A);
438 	zexpect_true(DEVICE_API_IS(abstract, dev));
439 
440 	dev = device_get_binding(MY_DRIVER_B);
441 	zexpect_true(DEVICE_API_IS(abstract, dev));
442 
443 	dev = device_get_binding(DUMMY_NOINIT);
444 	zexpect_false(DEVICE_API_IS(abstract, dev));
445 }
446 
ZTEST_USER(device,test_deferred_init_user)447 ZTEST_USER(device, test_deferred_init_user)
448 {
449 	int ret;
450 
451 	zassert_false(device_is_ready(FAKEDEFERDRIVER1));
452 
453 	ret = device_init(FAKEDEFERDRIVER1);
454 	zassert_true(ret == 0);
455 
456 	zassert_true(device_is_ready(FAKEDEFERDRIVER1));
457 }
458 
ZTEST(device,test_deinit_not_supported)459 ZTEST(device, test_deinit_not_supported)
460 {
461 	const struct device *dev = device_get_binding(DUMMY_NOINIT);
462 	int ret;
463 
464 	zassert_not_null(dev);
465 
466 	ret = device_deinit(dev);
467 	zassert_equal(ret, -ENOTSUP, "Expected -ENOTSUP for device_deinit when not supported");
468 }
469 
dummy_deinit(const struct device * dev)470 static int dummy_deinit(const struct device *dev)
471 {
472 	return 0;
473 }
474 
475 /* A device with de-initialization function */
476 DEVICE_DEINIT_DEFINE(dummy_deinit, DUMMY_DEINIT, NULL, dummy_deinit, NULL, NULL, NULL, POST_KERNEL,
477 		     CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
478 
ZTEST(device,test_deinit_success_and_redeinit)479 ZTEST(device, test_deinit_success_and_redeinit)
480 {
481 	const struct device *dev = device_get_binding(DUMMY_DEINIT);
482 	int ret;
483 
484 	zassert_not_null(dev);
485 
486 	ret = device_deinit(dev);
487 	zassert_equal(ret, 0, "device_deinit should succeed");
488 
489 	ret = device_deinit(dev);
490 	zassert_equal(ret, -EPERM, "device_deinit should fail when not init or already deinit");
491 }
492 
493 #ifdef CONFIG_DEVICE_DT_METADATA
494 DEVICE_DT_DEFINE(FAKEDRIVER0_NODEID, NULL, NULL, NULL, NULL, POST_KERNEL,
495 		 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
496 
ZTEST(device,test_device_get_by_dt_nodelabel)497 ZTEST(device, test_device_get_by_dt_nodelabel)
498 {
499 	const struct device *dev = DEVICE_DT_GET(FAKEDRIVER0_NODEID);
500 
501 	zassert_not_null(dev);
502 
503 	const struct device *valid = device_get_by_dt_nodelabel(FAKEDRIVER0_NODELABEL);
504 
505 	zassert_not_null(valid, "Valid DT nodelabel should return a device");
506 
507 	const struct device *invalid = device_get_by_dt_nodelabel("does_not_exist");
508 
509 	zassert_is_null(invalid, "Invalid DT nodelabel should return NULL");
510 }
511 #endif
512 
user_setup(void)513 void *user_setup(void)
514 {
515 #ifdef CONFIG_USERSPACE
516 	k_object_access_grant(FAKEDEFERDRIVER1, k_current_get());
517 #endif
518 
519 	return NULL;
520 }
521 
522 /**
523  * @}
524  */
525 
526 ZTEST_SUITE(device, NULL, user_setup, NULL, NULL, NULL);
527