xref: /linux/lib/packing_test.c (revision 3ed8d344e061f382069c27705543c1882aca468a)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024, Vladimir Oltean <olteanv@gmail.com>
3  * Copyright (c) 2024, Intel Corporation.
4  */
5 #include <kunit/test.h>
6 #include <linux/packing.h>
7 
8 struct packing_test_case {
9 	const char *desc;
10 	const u8 *pbuf;
11 	size_t pbuf_size;
12 	u64 uval;
13 	size_t start_bit;
14 	size_t end_bit;
15 	u8 quirks;
16 };
17 
18 #define NO_QUIRKS	0
19 
20 /**
21  * PBUF - Initialize .pbuf and .pbuf_size
22  * @array: elements of constant physical buffer
23  *
24  * Initializes the .pbuf and .pbuf_size fields of a struct packing_test_case
25  * with a constant array of the specified elements.
26  */
27 #define PBUF(array...)					\
28 	.pbuf = (const u8[]){ array },			\
29 	.pbuf_size = sizeof((const u8 []){ array })
30 
31 static const struct packing_test_case cases[] = {
32 	/* These tests pack and unpack a magic 64-bit value
33 	 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an
34 	 * otherwise zero array of 128 bits (16 bytes). They test all possible
35 	 * bit layouts of the 128 bit buffer.
36 	 */
37 	{
38 		.desc = "no quirks, 16 bytes",
39 		PBUF(0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad,
40 		     0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00),
41 		.uval = 0xcafedeadbeefcafe,
42 		.start_bit = 95,
43 		.end_bit = 32,
44 		.quirks = NO_QUIRKS,
45 	},
46 	{
47 		.desc = "lsw32 first, 16 bytes",
48 		PBUF(0x00, 0x00, 0x00, 0x00, 0xbe, 0xef, 0xca, 0xfe,
49 		     0xca, 0xfe, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00),
50 		.uval = 0xcafedeadbeefcafe,
51 		.start_bit = 95,
52 		.end_bit = 32,
53 		.quirks = QUIRK_LSW32_IS_FIRST,
54 	},
55 	{
56 		.desc = "little endian words, 16 bytes",
57 		PBUF(0x00, 0x00, 0x00, 0x00, 0xad, 0xde, 0xfe, 0xca,
58 		     0xfe, 0xca, 0xef, 0xbe, 0x00, 0x00, 0x00, 0x00),
59 		.uval = 0xcafedeadbeefcafe,
60 		.start_bit = 95,
61 		.end_bit = 32,
62 		.quirks = QUIRK_LITTLE_ENDIAN,
63 	},
64 	{
65 		.desc = "lsw32 first + little endian words, 16 bytes",
66 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
67 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00),
68 		.uval = 0xcafedeadbeefcafe,
69 		.start_bit = 95,
70 		.end_bit = 32,
71 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
72 	},
73 	{
74 		.desc = "msb right, 16 bytes",
75 		PBUF(0x00, 0x00, 0x00, 0x00, 0x53, 0x7f, 0x7b, 0xb5,
76 		     0x7d, 0xf7, 0x53, 0x7f, 0x00, 0x00, 0x00, 0x00),
77 		.uval = 0xcafedeadbeefcafe,
78 		.start_bit = 95,
79 		.end_bit = 32,
80 		.quirks = QUIRK_MSB_ON_THE_RIGHT,
81 	},
82 	{
83 		.desc = "msb right + lsw32 first, 16 bytes",
84 		PBUF(0x00, 0x00, 0x00, 0x00, 0x7d, 0xf7, 0x53, 0x7f,
85 		     0x53, 0x7f, 0x7b, 0xb5, 0x00, 0x00, 0x00, 0x00),
86 		.uval = 0xcafedeadbeefcafe,
87 		.start_bit = 95,
88 		.end_bit = 32,
89 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST,
90 	},
91 	{
92 		.desc = "msb right + little endian words, 16 bytes",
93 		PBUF(0x00, 0x00, 0x00, 0x00, 0xb5, 0x7b, 0x7f, 0x53,
94 		     0x7f, 0x53, 0xf7, 0x7d, 0x00, 0x00, 0x00, 0x00),
95 		.uval = 0xcafedeadbeefcafe,
96 		.start_bit = 95,
97 		.end_bit = 32,
98 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN,
99 	},
100 	{
101 		.desc = "msb right + lsw32 first + little endian words, 16 bytes",
102 		PBUF(0x00, 0x00, 0x00, 0x00, 0x7f, 0x53, 0xf7, 0x7d,
103 		     0xb5, 0x7b, 0x7f, 0x53, 0x00, 0x00, 0x00, 0x00),
104 		.uval = 0xcafedeadbeefcafe,
105 		.start_bit = 95,
106 		.end_bit = 32,
107 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
108 	},
109 	/* These tests pack and unpack a magic 64-bit value
110 	 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an
111 	 * otherwise zero array of varying size from 18 bytes to 24 bytes.
112 	 */
113 	{
114 		.desc = "no quirks, 18 bytes",
115 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfe,
116 		     0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00,
117 		     0x00, 0x00),
118 		.uval = 0xcafedeadbeefcafe,
119 		.start_bit = 95,
120 		.end_bit = 32,
121 		.quirks = NO_QUIRKS,
122 	},
123 	{
124 		.desc = "no quirks, 19 bytes",
125 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
126 		     0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00,
127 		     0x00, 0x00, 0x00),
128 		.uval = 0xcafedeadbeefcafe,
129 		.start_bit = 95,
130 		.end_bit = 32,
131 		.quirks = NO_QUIRKS,
132 	},
133 	{
134 		.desc = "no quirks, 20 bytes",
135 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 		     0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe,
137 		     0x00, 0x00, 0x00, 0x00),
138 		.uval = 0xcafedeadbeefcafe,
139 		.start_bit = 95,
140 		.end_bit = 32,
141 		.quirks = NO_QUIRKS,
142 	},
143 	{
144 		.desc = "no quirks, 22 bytes",
145 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 		     0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef,
147 		     0xca, 0xfe, 0x00, 0x00, 0x00, 0x00),
148 		.uval = 0xcafedeadbeefcafe,
149 		.start_bit = 95,
150 		.end_bit = 32,
151 		.quirks = NO_QUIRKS,
152 	},
153 	{
154 		.desc = "no quirks, 24 bytes",
155 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 		     0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad,
157 		     0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00),
158 		.uval = 0xcafedeadbeefcafe,
159 		.start_bit = 95,
160 		.end_bit = 32,
161 		.quirks = NO_QUIRKS,
162 	},
163 	{
164 		.desc = "lsw32 first + little endian words, 18 bytes",
165 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
166 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00,
167 		     0x00, 0x00),
168 		.uval = 0xcafedeadbeefcafe,
169 		.start_bit = 95,
170 		.end_bit = 32,
171 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
172 	},
173 	{
174 		.desc = "lsw32 first + little endian words, 19 bytes",
175 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
176 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00,
177 		     0x00, 0x00, 0x00),
178 		.uval = 0xcafedeadbeefcafe,
179 		.start_bit = 95,
180 		.end_bit = 32,
181 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
182 	},
183 	{
184 		.desc = "lsw32 first + little endian words, 20 bytes",
185 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
186 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00,
187 		     0x00, 0x00, 0x00, 0x00),
188 		.uval = 0xcafedeadbeefcafe,
189 		.start_bit = 95,
190 		.end_bit = 32,
191 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
192 	},
193 	{
194 		.desc = "lsw32 first + little endian words, 22 bytes",
195 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
196 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00,
197 		     0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
198 		.uval = 0xcafedeadbeefcafe,
199 		.start_bit = 95,
200 		.end_bit = 32,
201 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
202 	},
203 	{
204 		.desc = "lsw32 first + little endian words, 24 bytes",
205 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe,
206 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00,
207 		     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
208 		.uval = 0xcafedeadbeefcafe,
209 		.start_bit = 95,
210 		.end_bit = 32,
211 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
212 	},
213 	/* These tests pack and unpack a magic 64-bit value
214 	 * (0x1122334455667788) at an odd starting bit (43) within an
215 	 * otherwise zero array of 128 bits (16 bytes). They test all possible
216 	 * bit layouts of the 128 bit buffer.
217 	 */
218 	{
219 		.desc = "no quirks, 16 bytes, non-aligned",
220 		PBUF(0x00, 0x00, 0x00, 0x89, 0x11, 0x9a, 0x22, 0xab,
221 		     0x33, 0xbc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
222 		.uval = 0x1122334455667788,
223 		.start_bit = 106,
224 		.end_bit = 43,
225 		.quirks = NO_QUIRKS,
226 	},
227 	{
228 		.desc = "lsw32 first, 16 bytes, non-aligned",
229 		PBUF(0x00, 0x00, 0x00, 0x00, 0x33, 0xbc, 0x40, 0x00,
230 		     0x11, 0x9a, 0x22, 0xab, 0x00, 0x00, 0x00, 0x89),
231 		.uval = 0x1122334455667788,
232 		.start_bit = 106,
233 		.end_bit = 43,
234 		.quirks = QUIRK_LSW32_IS_FIRST,
235 	},
236 	{
237 		.desc = "little endian words, 16 bytes, non-aligned",
238 		PBUF(0x89, 0x00, 0x00, 0x00, 0xab, 0x22, 0x9a, 0x11,
239 		     0x00, 0x40, 0xbc, 0x33, 0x00, 0x00, 0x00, 0x00),
240 		.uval = 0x1122334455667788,
241 		.start_bit = 106,
242 		.end_bit = 43,
243 		.quirks = QUIRK_LITTLE_ENDIAN,
244 	},
245 	{
246 		.desc = "lsw32 first + little endian words, 16 bytes, non-aligned",
247 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbc, 0x33,
248 		     0xab, 0x22, 0x9a, 0x11, 0x89, 0x00, 0x00, 0x00),
249 		.uval = 0x1122334455667788,
250 		.start_bit = 106,
251 		.end_bit = 43,
252 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
253 	},
254 	{
255 		.desc = "msb right, 16 bytes, non-aligned",
256 		PBUF(0x00, 0x00, 0x00, 0x91, 0x88, 0x59, 0x44, 0xd5,
257 		     0xcc, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00),
258 		.uval = 0x1122334455667788,
259 		.start_bit = 106,
260 		.end_bit = 43,
261 		.quirks = QUIRK_MSB_ON_THE_RIGHT,
262 	},
263 	{
264 		.desc = "msb right + lsw32 first, 16 bytes, non-aligned",
265 		PBUF(0x00, 0x00, 0x00, 0x00, 0xcc, 0x3d, 0x02, 0x00,
266 		     0x88, 0x59, 0x44, 0xd5, 0x00, 0x00, 0x00, 0x91),
267 		.uval = 0x1122334455667788,
268 		.start_bit = 106,
269 		.end_bit = 43,
270 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST,
271 	},
272 	{
273 		.desc = "msb right + little endian words, 16 bytes, non-aligned",
274 		PBUF(0x91, 0x00, 0x00, 0x00, 0xd5, 0x44, 0x59, 0x88,
275 		     0x00, 0x02, 0x3d, 0xcc, 0x00, 0x00, 0x00, 0x00),
276 		.uval = 0x1122334455667788,
277 		.start_bit = 106,
278 		.end_bit = 43,
279 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN,
280 	},
281 	{
282 		.desc = "msb right + lsw32 first + little endian words, 16 bytes, non-aligned",
283 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3d, 0xcc,
284 		     0xd5, 0x44, 0x59, 0x88, 0x91, 0x00, 0x00, 0x00),
285 		.uval = 0x1122334455667788,
286 		.start_bit = 106,
287 		.end_bit = 43,
288 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
289 	},
290 	/* These tests pack and unpack a u64 with all bits set
291 	 * (0xffffffffffffffff) at an odd starting bit (43) within an
292 	 * otherwise zero array of 128 bits (16 bytes). They test all possible
293 	 * bit layouts of the 128 bit buffer.
294 	 */
295 	{
296 		.desc = "no quirks, 16 bytes, non-aligned, 0xff",
297 		PBUF(0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
298 		     0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00),
299 		.uval = 0xffffffffffffffff,
300 		.start_bit = 106,
301 		.end_bit = 43,
302 		.quirks = NO_QUIRKS,
303 	},
304 	{
305 		.desc = "lsw32 first, 16 bytes, non-aligned, 0xff",
306 		PBUF(0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00,
307 		     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xff),
308 		.uval = 0xffffffffffffffff,
309 		.start_bit = 106,
310 		.end_bit = 43,
311 		.quirks = QUIRK_LSW32_IS_FIRST,
312 	},
313 	{
314 		.desc = "little endian words, 16 bytes, non-aligned, 0xff",
315 		PBUF(0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
316 		     0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00),
317 		.uval = 0xffffffffffffffff,
318 		.start_bit = 106,
319 		.end_bit = 43,
320 		.quirks = QUIRK_LITTLE_ENDIAN,
321 	},
322 	{
323 		.desc = "lsw32 first + little endian words, 16 bytes, non-aligned, 0xff",
324 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff,
325 		     0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00),
326 		.uval = 0xffffffffffffffff,
327 		.start_bit = 106,
328 		.end_bit = 43,
329 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
330 	},
331 	{
332 		.desc = "msb right, 16 bytes, non-aligned, 0xff",
333 		PBUF(0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
334 		     0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00),
335 		.uval = 0xffffffffffffffff,
336 		.start_bit = 106,
337 		.end_bit = 43,
338 		.quirks = QUIRK_MSB_ON_THE_RIGHT,
339 	},
340 	{
341 		.desc = "msb right + lsw32 first, 16 bytes, non-aligned, 0xff",
342 		PBUF(0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x00,
343 		     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xe0, 0xff),
344 		.uval = 0xffffffffffffffff,
345 		.start_bit = 106,
346 		.end_bit = 43,
347 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST,
348 	},
349 	{
350 		.desc = "msb right + little endian words, 16 bytes, non-aligned, 0xff",
351 		PBUF(0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
352 		     0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00),
353 		.uval = 0xffffffffffffffff,
354 		.start_bit = 106,
355 		.end_bit = 43,
356 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN,
357 	},
358 	{
359 		.desc = "msb right + lsw32 first + little endian words, 16 bytes, non-aligned, 0xff",
360 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff,
361 		     0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00),
362 		.uval = 0xffffffffffffffff,
363 		.start_bit = 106,
364 		.end_bit = 43,
365 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN,
366 	},
367 };
368 
369 KUNIT_ARRAY_PARAM_DESC(packing, cases, desc);
370 
371 static void packing_test_pack(struct kunit *test)
372 {
373 	const struct packing_test_case *params = test->param_value;
374 	u8 *pbuf;
375 	int err;
376 
377 	pbuf = kunit_kzalloc(test, params->pbuf_size, GFP_KERNEL);
378 
379 	err = pack(pbuf, params->uval, params->start_bit, params->end_bit,
380 		   params->pbuf_size, params->quirks);
381 
382 	KUNIT_EXPECT_EQ_MSG(test, err, 0, "pack() returned %pe\n", ERR_PTR(err));
383 	KUNIT_EXPECT_MEMEQ(test, pbuf, params->pbuf, params->pbuf_size);
384 }
385 
386 static void packing_test_unpack(struct kunit *test)
387 {
388 	const struct packing_test_case *params = test->param_value;
389 	u64 uval;
390 	int err;
391 
392 	err = unpack(params->pbuf, &uval, params->start_bit, params->end_bit,
393 		     params->pbuf_size, params->quirks);
394 	KUNIT_EXPECT_EQ_MSG(test, err, 0, "unpack() returned %pe\n", ERR_PTR(err));
395 	KUNIT_EXPECT_EQ(test, uval, params->uval);
396 }
397 
398 static struct kunit_case packing_test_cases[] = {
399 	KUNIT_CASE_PARAM(packing_test_pack, packing_gen_params),
400 	KUNIT_CASE_PARAM(packing_test_unpack, packing_gen_params),
401 	{},
402 };
403 
404 static struct kunit_suite packing_test_suite = {
405 	.name = "packing",
406 	.test_cases = packing_test_cases,
407 };
408 
409 kunit_test_suite(packing_test_suite);
410 
411 MODULE_LICENSE("GPL");
412 MODULE_DESCRIPTION("KUnit tests for packing library");
413