xref: /linux/drivers/of/of_test.c (revision ad1b832bf1cf2df9304f8eb72943111625c7e5a7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * KUnit tests for OF APIs
4  */
5 #include <linux/ioport.h>
6 #include <linux/module.h>
7 #include <linux/of.h>
8 
9 #include <kunit/test.h>
10 
11 #include "of_private.h"
12 
13 /*
14  * Test that the root node "/" can be found by path.
15  */
of_dtb_root_node_found_by_path(struct kunit * test)16 static void of_dtb_root_node_found_by_path(struct kunit *test)
17 {
18 	struct device_node *np;
19 
20 	np = of_find_node_by_path("/");
21 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np);
22 	of_node_put(np);
23 }
24 
25 /*
26  * Test that the 'of_root' global variable is always populated when DT code is
27  * enabled. Remove this test once of_root is removed from global access.
28  */
of_dtb_root_node_populates_of_root(struct kunit * test)29 static void of_dtb_root_node_populates_of_root(struct kunit *test)
30 {
31 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, of_root);
32 }
33 
34 static struct kunit_case of_dtb_test_cases[] = {
35 	KUNIT_CASE(of_dtb_root_node_found_by_path),
36 	KUNIT_CASE(of_dtb_root_node_populates_of_root),
37 	{}
38 };
39 
of_dtb_test_init(struct kunit * test)40 static int of_dtb_test_init(struct kunit *test)
41 {
42 	of_root_kunit_skip(test);
43 	if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE))
44 		kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE");
45 
46 	return 0;
47 }
48 
49 /*
50  * Test suite to confirm a DTB is loaded.
51  */
52 static struct kunit_suite of_dtb_suite = {
53 	.name = "of_dtb",
54 	.test_cases = of_dtb_test_cases,
55 	.init = of_dtb_test_init,
56 };
57 
58 struct of_address_resource_bounds_case {
59 	u64 start;
60 	u64 size;
61 	int ret;
62 
63 	u64 res_start;
64 	u64 res_end;
65 };
66 
of_address_resource_bounds_case_desc(const struct of_address_resource_bounds_case * p,char * name)67 static void of_address_resource_bounds_case_desc(const struct of_address_resource_bounds_case *p,
68 						 char *name)
69 {
70 	snprintf(name, KUNIT_PARAM_DESC_SIZE, "start=0x%016llx,size=0x%016llx", p->start, p->size);
71 }
72 
73 static const struct of_address_resource_bounds_case of_address_resource_bounds_cases[] = {
74 	{
75 		.start = 0,
76 		.size = 0,
77 		.ret = 0,
78 		.res_start = 0,
79 		.res_end = -1,
80 	},
81 	{
82 		.start = 0,
83 		.size = 0x1000,
84 		.ret = 0,
85 		.res_start = 0,
86 		.res_end = 0xfff,
87 	},
88 	{
89 		.start = 0x1000,
90 		.size = 0,
91 		.ret = 0,
92 		.res_start = 0x1000,
93 		.res_end = 0xfff,
94 	},
95 	{
96 		.start = 0x1000,
97 		.size = 0x1000,
98 		.ret = 0,
99 		.res_start = 0x1000,
100 		.res_end = 0x1fff,
101 	},
102 	{
103 		.start = 1,
104 		.size = RESOURCE_SIZE_MAX,
105 		.ret = 0,
106 		.res_start = 1,
107 		.res_end = RESOURCE_SIZE_MAX,
108 	},
109 	{
110 		.start = RESOURCE_SIZE_MAX,
111 		.size = 1,
112 		.ret = 0,
113 		.res_start = RESOURCE_SIZE_MAX,
114 		.res_end = RESOURCE_SIZE_MAX,
115 	},
116 	{
117 		.start = 2,
118 		.size = RESOURCE_SIZE_MAX,
119 		.ret = -EOVERFLOW,
120 	},
121 	{
122 		.start = RESOURCE_SIZE_MAX,
123 		.size = 2,
124 		.ret = -EOVERFLOW,
125 	},
126 	{
127 		.start = ULL(0x100000000),
128 		.size = 1,
129 		.ret = sizeof(resource_size_t) > sizeof(u32) ? 0 : -EOVERFLOW,
130 		.res_start = ULL(0x100000000),
131 		.res_end = ULL(0x100000000),
132 	},
133 	{
134 		.start = 0x1000,
135 		.size = 0xffffffff,
136 		.ret = sizeof(resource_size_t) > sizeof(u32) ? 0 : -EOVERFLOW,
137 		.res_start = 0x1000,
138 		.res_end = ULL(0x100000ffe),
139 	},
140 };
141 
142 KUNIT_ARRAY_PARAM(of_address_resource_bounds,
143 		  of_address_resource_bounds_cases, of_address_resource_bounds_case_desc);
144 
of_address_resource_bounds(struct kunit * test)145 static void of_address_resource_bounds(struct kunit *test)
146 {
147 	const struct of_address_resource_bounds_case *param = test->param_value;
148 	struct resource r; /* Intentionally uninitialized */
149 	int ret;
150 
151 	if (!IS_ENABLED(CONFIG_OF_ADDRESS))
152 		kunit_skip(test, "CONFIG_OF_ADDRESS not enabled\n");
153 
154 	ret = __of_address_resource_bounds(&r, param->start, param->size);
155 	KUNIT_EXPECT_EQ(test, param->ret, ret);
156 	if (ret == 0) {
157 		KUNIT_EXPECT_EQ(test, (resource_size_t)param->res_start, r.start);
158 		KUNIT_EXPECT_EQ(test, (resource_size_t)param->res_end, r.end);
159 		KUNIT_EXPECT_EQ(test, param->size, resource_size(&r));
160 	}
161 }
162 
163 static struct kunit_case of_address_test_cases[] = {
164 	KUNIT_CASE_PARAM(of_address_resource_bounds, of_address_resource_bounds_gen_params),
165 	{}
166 };
167 
168 static struct kunit_suite of_address_suite = {
169 	.name = "of_address",
170 	.test_cases = of_address_test_cases,
171 };
172 
173 kunit_test_suites(
174 	&of_dtb_suite, &of_address_suite,
175 );
176 MODULE_DESCRIPTION("KUnit tests for OF APIs");
177 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
178 MODULE_LICENSE("GPL");
179