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