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