1 /*
2  * Copyright (c) 2021 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/sys/iterable_sections.h>
9 
10 struct test_ram {
11 	long i;
12 };
13 
14 struct test_ram_named {
15 	long i;
16 };
17 
18 struct test_ram_numeric {
19 	long i;
20 };
21 
22 #define CHECK_BIT 0x80
23 
24 /* declare in random order to check that the linker is sorting by name */
25 STRUCT_SECTION_ITERABLE(test_ram, ram3) = {0x03};
26 STRUCT_SECTION_ITERABLE(test_ram, ram2) = {0x02};
27 STRUCT_SECTION_ITERABLE(test_ram, ram4) = {0x04};
28 STRUCT_SECTION_ITERABLE(test_ram, ram1) = {0x01};
29 
30 #define RAM_EXPECT 0x01020304
31 
32 /* iterable section items can also be static */
33 static const STRUCT_SECTION_ITERABLE_ALTERNATE(test_ram2, test_ram, ram5) = {RAM_EXPECT};
34 
35 /* declare in random order to check that the linker is sorting by custom name */
36 const STRUCT_SECTION_ITERABLE_NAMED(test_ram_named, A, ram6) = {0x01};
37 const STRUCT_SECTION_ITERABLE_NAMED(test_ram_named, C, ram7) = {0x03};
38 const STRUCT_SECTION_ITERABLE_NAMED(test_ram_named, D, ram8) = {0x04};
39 const STRUCT_SECTION_ITERABLE_NAMED(test_ram_named, B, ram9) = {0x02};
40 
41 /* declare in random order to check that the linker is sorting numerically */
42 const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_1) = {0x01};
43 const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_10) = {0x03};
44 const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_11) = {0x04};
45 const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_3) = {0x02};
46 
47 #define NAMED_ALT_EXPECT 0x4273
48 
49 /* alternate naming */
50 const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, R, ramn_42) = {0x42};
51 const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, W, ramn_73) = {0x73};
52 
53 /**
54  *
55  * @brief Test iterable in read write section.
56  *
57  */
ZTEST(iterable_sections,test_ram)58 ZTEST(iterable_sections, test_ram)
59 {
60 	int out = 0;
61 
62 	STRUCT_SECTION_FOREACH(test_ram, t) {
63 		out = (out << 8) | t->i;
64 		t->i |= CHECK_BIT;
65 	}
66 
67 	zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%08x)", out);
68 
69 	zassert_equal(ram1.i & CHECK_BIT, CHECK_BIT,
70 		      "ram1.i check bit incorrect (got: 0x%x)", ram1.i);
71 	zassert_equal(ram2.i & CHECK_BIT, CHECK_BIT,
72 		      "ram2.i check bit incorrect (got: 0x%x)", ram2.i);
73 	zassert_equal(ram3.i & CHECK_BIT, CHECK_BIT,
74 		      "ram3.i check bit incorrect (got: 0x%x)", ram3.i);
75 	zassert_equal(ram4.i & CHECK_BIT, CHECK_BIT,
76 		      "ram4.i check bit incorrect (got: 0x%x)", ram4.i);
77 
78 	out = 0;
79 	STRUCT_SECTION_FOREACH_ALTERNATE(test_ram2, test_ram, t) {
80 		out = (out << 8) | t->i;
81 	}
82 
83 	zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%08x)", out);
84 
85 	out = 0;
86 	STRUCT_SECTION_FOREACH(test_ram_named, t) {
87 		out = (out << 8) | t->i;
88 	}
89 
90 	zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%x)", out);
91 
92 	out = 0;
93 	STRUCT_SECTION_FOREACH(test_ram_numeric, t) {
94 		out = (out << 8) | t->i;
95 	}
96 
97 	zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%x)", out);
98 
99 	out = 0;
100 	STRUCT_SECTION_FOREACH_ALTERNATE(ramn_alt, test_ram_named, t) {
101 		out = (out << 8) | t->i;
102 	}
103 
104 	zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out);
105 }
106 
107 struct test_rom {
108 	long i;
109 };
110 
111 struct test_rom_named {
112 	long i;
113 };
114 
115 struct test_rom_numeric {
116 	long i;
117 };
118 
119 /* declare in random order to check that the linker is sorting by name */
120 const STRUCT_SECTION_ITERABLE(test_rom, rom1) = {0x10};
121 const STRUCT_SECTION_ITERABLE(test_rom, rom3) = {0x30};
122 const STRUCT_SECTION_ITERABLE(test_rom, rom4) = {0x40};
123 const STRUCT_SECTION_ITERABLE(test_rom, rom2) = {0x20};
124 
125 #define ROM_EXPECT 0x10203040
126 
127 /* iterable section items can also be static */
128 static const STRUCT_SECTION_ITERABLE_ALTERNATE(test_rom2, test_rom, rom5) = {ROM_EXPECT};
129 
130 /* declare in random order to check that the linker is sorting by custom name */
131 const STRUCT_SECTION_ITERABLE_NAMED(test_rom_named, A, rom6) = {0x10};
132 const STRUCT_SECTION_ITERABLE_NAMED(test_rom_named, C, rom7) = {0x30};
133 const STRUCT_SECTION_ITERABLE_NAMED(test_rom_named, D, rom8) = {0x40};
134 const STRUCT_SECTION_ITERABLE_NAMED(test_rom_named, B, rom9) = {0x20};
135 
136 /* declare in random order to check that the linker is sorting numerically */
137 const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_1) = {0x10};
138 const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_10) = {0x30};
139 const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_11) = {0x40};
140 const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_3) = {0x20};
141 
142 /* alternate naming */
143 const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, R, romn_73) = {0x73};
144 const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, O, romn_42) = {0x42};
145 
146 /**
147  *
148  * @brief Test iterable in read only section.
149  *
150  */
ZTEST(iterable_sections,test_rom)151 ZTEST(iterable_sections, test_rom)
152 {
153 	int out = 0;
154 
155 	STRUCT_SECTION_FOREACH(test_rom, t) {
156 		out = (out << 8) | t->i;
157 	}
158 
159 	zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out);
160 
161 	out = 0;
162 	STRUCT_SECTION_FOREACH_ALTERNATE(test_rom2, test_rom, t) {
163 		out = (out << 8) | t->i;
164 	}
165 
166 	zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out);
167 
168 	out = 0;
169 	STRUCT_SECTION_FOREACH(test_rom_named, t) {
170 		out = (out << 8) | t->i;
171 	}
172 
173 	zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out);
174 
175 	out = 0;
176 	STRUCT_SECTION_FOREACH(test_rom_numeric, t) {
177 		out = (out << 8) | t->i;
178 	}
179 
180 	zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out);
181 
182 	out = 0;
183 	STRUCT_SECTION_FOREACH_ALTERNATE(romn_alt, test_rom_named, t) {
184 		out = (out << 8) | t->i;
185 	}
186 
187 	zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out);
188 }
189 
190 ZTEST_SUITE(iterable_sections, NULL, NULL, NULL, NULL, NULL);
191