summaryrefslogtreecommitdiffstats
path: root/userspace
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2018-06-27 17:45:21 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-08-10 02:11:17 -0400
commit542e6a0ab4fe3839633a3a86c80b394fd046ac79 (patch)
tree4e754e0a4e74d20b624670741347eb3aaeda9980 /userspace
parent98d092e73679be792f99bb6debb9ecffbf403987 (diff)
gpu: nvgpu: unit: Add a posix-bitmap impl unit test
Add a unit test to test the nvgpu-posix bitmap implementation. This unit test aims to both verify the functionality of this low level set of APIs and provide a reference for how to use the basic unit test functionality. JIRA NVGPU-525 Change-Id: Ide5263e5ce49f18f5f2a3d4a6f9e494395299386 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1695007 GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'userspace')
-rw-r--r--userspace/Makefile.sources7
-rw-r--r--userspace/units/posix-bitops/Makefile26
-rw-r--r--userspace/units/posix-bitops/posix-bitops.c672
3 files changed, 703 insertions, 2 deletions
diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources
index e0ad3eb4..329871f8 100644
--- a/userspace/Makefile.sources
+++ b/userspace/Makefile.sources
@@ -45,5 +45,8 @@ CORE_HEADERS := \
45 $(CORE_SRC)/../include/unit/*.h 45 $(CORE_SRC)/../include/unit/*.h
46 46
47# Each directory under the UNIT_SRC directory should correspond to one module. 47# Each directory under the UNIT_SRC directory should correspond to one module.
48UNITS := \ 48UNITS := \
49 $(UNIT_SRC)/test 49 $(UNIT_SRC)/posix-bitops
50
51# A test unit. Not really needed any more...
52# $(UNIT_SRC)/test
diff --git a/userspace/units/posix-bitops/Makefile b/userspace/units/posix-bitops/Makefile
new file mode 100644
index 00000000..1b4d091e
--- /dev/null
+++ b/userspace/units/posix-bitops/Makefile
@@ -0,0 +1,26 @@
1# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
2#
3# Permission is hereby granted, free of charge, to any person obtaining a
4# copy of this software and associated documentation files (the "Software"),
5# to deal in the Software without restriction, including without limitation
6# the rights to use, copy, modify, merge, publish, distribute, sublicense,
7# and/or sell copies of the Software, and to permit persons to whom the
8# Software is furnished to do so, subject to the following conditions:
9#
10# The above copyright notice and this permission notice shall be included in
11# all copies or substantial portions of the Software.
12#
13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19# DEALINGS IN THE SOFTWARE.
20
21.SUFFIXES:
22
23OBJS = posix-bitops.o
24MODULE = posix-bitops
25
26include ../Makefile.units
diff --git a/userspace/units/posix-bitops/posix-bitops.c b/userspace/units/posix-bitops/posix-bitops.c
new file mode 100644
index 00000000..4ebef7b5
--- /dev/null
+++ b/userspace/units/posix-bitops/posix-bitops.c
@@ -0,0 +1,672 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdlib.h>
24
25#include <unit/io.h>
26#include <unit/unit.h>
27
28#include <nvgpu/posix/bitops.h>
29
30#define NUM_WORDS 4
31
32static unsigned long single_ulong_maps[] = {
33 0UL,
34 ~0UL,
35 0xff00ff00UL,
36 0x00ff00ffUL,
37 0xa5a5a5a5UL,
38 0x0000ffffUL,
39 0xffff0000UL,
40 0x1UL,
41 0x80000000UL,
42 BIT(16),
43};
44
45/*
46 * Can't fail - just some info prints.
47 */
48static int test_bitmap_info(struct unit_module *m, struct gk20a *g, void *args)
49{
50 unit_info(m, "sizeof(unsigned long) = %zu\n", sizeof(unsigned long));
51 unit_info(m, "BITS_PER_LONG = %lu\n", BITS_PER_LONG);
52
53 return UNIT_SUCCESS;
54}
55
56static int test_ffs(struct unit_module *m, struct gk20a *g, void *args)
57{
58#define CHECK_FFS_WORD(w, answer) \
59 do { \
60 unsigned long ret = ffs(w); \
61 \
62 if (ret != (answer)) \
63 unit_return_fail(m, \
64 "ffs(0x%016lx) = %lu " \
65 "[expected %lu]\n", \
66 w, ret, answer); \
67 } while (0)
68
69 unsigned long i;
70
71 CHECK_FFS_WORD(single_ulong_maps[0], BITS_PER_LONG - 1UL);
72 CHECK_FFS_WORD(single_ulong_maps[1], 0UL);
73 CHECK_FFS_WORD(single_ulong_maps[2], 8UL);
74 CHECK_FFS_WORD(single_ulong_maps[3], 0UL);
75 CHECK_FFS_WORD(single_ulong_maps[4], 0UL);
76 CHECK_FFS_WORD(single_ulong_maps[5], 0UL);
77 CHECK_FFS_WORD(single_ulong_maps[6], 16UL);
78 CHECK_FFS_WORD(single_ulong_maps[7], 0UL);
79 CHECK_FFS_WORD(single_ulong_maps[8], 31UL);
80 CHECK_FFS_WORD(single_ulong_maps[9], 16UL);
81
82#undef CHECK_FFS_WORD
83
84 /*
85 * Also just test every bit to make sure we definitely cover all
86 * possible return values of the function.
87 */
88 for (i = 0; i < BITS_PER_LONG; i++) {
89 if (ffs(BIT(i)) != i)
90 unit_return_fail(m, "ffs(1 << %lu) != %lu [%lu]!\n",
91 i, i, ffs(BIT(i)));
92 }
93
94 return UNIT_SUCCESS;
95}
96
97static int test_fls(struct unit_module *m, struct gk20a *g, void *args)
98{
99#define CHECK_FLS_WORD(w, answer) \
100 do { \
101 unsigned long ret = fls(w); \
102 \
103 if (ret != (answer)) \
104 unit_return_fail(m, \
105 "fls(0x%016lx) = %lu " \
106 "[expected = %lu]\n", \
107 w, ret, answer); \
108 } while (0)
109
110 unsigned long i;
111
112 CHECK_FLS_WORD(single_ulong_maps[0], 0UL);
113 CHECK_FLS_WORD(single_ulong_maps[1], BITS_PER_LONG - 1UL);
114 CHECK_FLS_WORD(single_ulong_maps[2], 31UL);
115 CHECK_FLS_WORD(single_ulong_maps[3], 23UL);
116 CHECK_FLS_WORD(single_ulong_maps[4], 31UL);
117 CHECK_FLS_WORD(single_ulong_maps[5], 15UL);
118 CHECK_FLS_WORD(single_ulong_maps[6], 31UL);
119 CHECK_FLS_WORD(single_ulong_maps[7], 0UL);
120 CHECK_FLS_WORD(single_ulong_maps[8], 31UL);
121 CHECK_FLS_WORD(single_ulong_maps[9], 16UL);
122
123#undef CHECK_FLS_WORD
124
125 for (i = 0; i < BITS_PER_LONG; i++) {
126 if (fls(BIT(i)) != i)
127 unit_return_fail(m, "fls(1 << %lu) != %lu! [%lu]\n",
128 i, i, fls(BIT(i)));
129 }
130
131 return UNIT_SUCCESS;
132}
133
134static int test_ffz(struct unit_module *m, struct gk20a *g, void *args)
135{
136 unsigned long i;
137
138 /*
139 * Since ffz(w) is implemented as ffs(~w) this does less extensive
140 * testing; but it should still cover every line of ffs().
141 */
142
143 for (i = 0; i < BITS_PER_LONG; i++) {
144 if (ffz(~BIT(i)) != i)
145 unit_return_fail(m, "ffz(~(1 << %lu)) != %lu! [%lu]\n",
146 i, i, ffz(BIT(i)));
147 }
148
149 return UNIT_SUCCESS;
150}
151
152struct test_find_bit_args {
153 bool find_zeros;
154};
155
156static struct test_find_bit_args first_bit_args = {
157 .find_zeros = false
158};
159
160static struct test_find_bit_args first_zero_args = {
161 .find_zeros = true
162};
163
164static int test_find_first_bit(struct unit_module *m,
165 struct gk20a *g, void *__args)
166{
167 struct test_find_bit_args *args = __args;
168 unsigned long words[NUM_WORDS];
169 unsigned long word_idx, bit_idx;
170 unsigned long (*finder_function)(const unsigned long *, unsigned long);
171 unsigned long result;
172
173 if (args->find_zeros)
174 finder_function = find_first_zero_bit;
175 else
176 finder_function = find_first_bit;
177
178 /*
179 * First test: verify that the size parameter works. We only need the
180 * first word for this.
181 */
182 words[0] = ~0xffffUL;
183 if (args->find_zeros)
184 words[0] = 0xffff;
185
186 if (finder_function(words, 8UL) != 8UL)
187 unit_return_fail(m,
188 "find_first_%s(0x%lx, 8) -> %lu [WRONG]\n",
189 args->find_zeros ? "zero_bit" : "bit",
190 words[0], finder_function(words, 8UL));
191
192 if (finder_function(words, 20UL) != 16UL)
193 unit_return_fail(m,
194 "find_first_%s(0x%lx, 16) -> %lu [WRONG]\n",
195 args->find_zeros ? "zero_bit" : "bit",
196 words[0], finder_function(words, 20UL));
197
198 /*
199 * Now make sure that for full/empty bitmap find_next_*() returns
200 * the size parameter.
201 */
202 memset(words, args->find_zeros ? 0xff : 0x00, sizeof(words));
203 result = finder_function(words, NUM_WORDS * BITS_PER_LONG);
204 if (result != NUM_WORDS * BITS_PER_LONG)
205 unit_return_fail(m, "find_first_%s() failed with empty map\n",
206 args->find_zeros ? "zero_bit" : "bit");
207
208 /*
209 * Third test: set (or zero) the entire bitmap and incrementally clear
210 * bits. Check that we are correct even with multiple words.
211 */
212
213 memset(words, args->find_zeros ? 0x00 : 0xff, sizeof(words));
214 for (word_idx = 0; word_idx < NUM_WORDS; word_idx++) {
215 for (bit_idx = 0; bit_idx < BITS_PER_LONG; bit_idx++) {
216 unsigned long check =
217 (word_idx * BITS_PER_LONG) + bit_idx;
218 unsigned long answer =
219 finder_function(words,
220 NUM_WORDS * BITS_PER_LONG);
221
222 if (answer != check)
223 unit_return_fail(m,
224 "find_first_%s loop: "
225 "word_idx = %lu bit_idx = %lu "
226 "-> %lu [WRONG]\n",
227 args->find_zeros ? "zero_bit" : "bit",
228 word_idx, bit_idx, answer);
229
230 /*
231 * Now set/clear this bit in preparation for the next
232 * test.
233 */
234 if (args->find_zeros)
235 words[word_idx] |= BIT(bit_idx);
236 else
237 words[word_idx] &= ~BIT(bit_idx);
238 }
239 }
240
241 return UNIT_SUCCESS;
242}
243
244/*
245 * Note: the find_first_bit() test also effectively tests the underlying
246 * find_next_bit() code since find_first_bit() is just find_next_bit()
247 * with a 0 start.
248 */
249
250static int test_find_next_bit(struct unit_module *m,
251 struct gk20a *g, void *__args)
252{
253 unsigned long words[NUM_WORDS];
254 unsigned long i, result;
255
256 /*
257 * Fully unset list. Should always return size.
258 */
259 memset(words, 0x00, sizeof(words));
260 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++) {
261 result = find_next_bit(words, NUM_WORDS * BITS_PER_LONG, i);
262
263 if (result != NUM_WORDS * BITS_PER_LONG)
264 unit_return_fail(m, "Fail: empty map (%lu)\n", i);
265 }
266
267 /*
268 * Use a fully set list but increment the offset.
269 */
270 memset(words, 0xff, sizeof(words));
271 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++) {
272 unsigned long first =
273 find_next_bit(words, NUM_WORDS * BITS_PER_LONG, i);
274
275 if (first != i)
276 unit_return_fail(m,
277 "Fail: first = %lu; should be %lu\n",
278 first, i);
279 }
280
281 /*
282 * Start > n should return n.
283 */
284#define TEST_START_GREATER_THAN_N(m, map, n, start) \
285 do { \
286 if (find_next_bit(map, n, start) != n) \
287 unit_return_fail(m, \
288 "Start not greater than N ?? " \
289 "start=%lu, N=%lu\n", \
290 start, n); \
291 } while (0)
292
293 TEST_START_GREATER_THAN_N(m, words, BITS_PER_LONG, BITS_PER_LONG + 1);
294 TEST_START_GREATER_THAN_N(m, words, 32UL, 64UL);
295 TEST_START_GREATER_THAN_N(m, words,
296 BITS_PER_LONG * 2, (BITS_PER_LONG * 2) + 1);
297 TEST_START_GREATER_THAN_N(m, words, 0UL, 1UL);
298 TEST_START_GREATER_THAN_N(m, words, 0UL, BITS_PER_LONG * 2);
299 TEST_START_GREATER_THAN_N(m, words, 0UL, BITS_PER_LONG * NUM_WORDS + 1);
300
301#undef TEST_START_GREATER_THAN_N
302
303 return UNIT_SUCCESS;
304}
305
306#define TEST_BITMAP_SIZE (BITS_PER_LONG * 4)
307/*
308 * 32/64 bit invarient.
309 */
310static DECLARE_BITMAP(bmap_all_zeros, TEST_BITMAP_SIZE) =
311{
312 0x0UL, 0x0UL, 0x0UL, 0x0UL
313};
314static DECLARE_BITMAP(bmap_all_ones, TEST_BITMAP_SIZE) =
315{
316 ~0x0UL, ~0x0UL, ~0x0UL, ~0x0UL
317};
318
319static int test_find_zero_area(struct unit_module *m,
320 struct gk20a *g, void *unused)
321{
322#define FAIL_MSG "Fail: bmap-test='%s' (i=%lu)\n"
323#define FAIL_MSG_EX "Fail: bmap-test='%s' (i=%lu, j=%lu)\n"
324 unsigned long i, j, result;
325 unsigned long words[NUM_WORDS];
326
327 for (i = 0; i < TEST_BITMAP_SIZE; i++) {
328 result = bitmap_find_next_zero_area_off(bmap_all_zeros,
329 TEST_BITMAP_SIZE,
330 i,
331 TEST_BITMAP_SIZE - i,
332 0, 0);
333 if (result != i)
334 unit_return_fail(m, FAIL_MSG,
335 "all_zeros: alloc-to-end", i);
336
337 result = bitmap_find_next_zero_area_off(bmap_all_zeros,
338 TEST_BITMAP_SIZE,
339 i,
340 1,
341 0, 0);
342 if (result != i)
343 unit_return_fail(m, FAIL_MSG,
344 "all_zeros: alloc-one-bit", i);
345
346 result = bitmap_find_next_zero_area_off(bmap_all_zeros,
347 TEST_BITMAP_SIZE,
348 0,
349 TEST_BITMAP_SIZE - i,
350 0, 0);
351 if (result != 0)
352 unit_return_fail(m, FAIL_MSG,
353 "all_zeros: alloc-i-bits-at-0", i);
354 }
355
356 /*
357 * For the all ones bit map not a single alloc should succeed. We can
358 * just iterate through them all and make sure they all fail.
359 */
360 for (i = 0; i < TEST_BITMAP_SIZE; i++) {
361 for (j = 0; j < (TEST_BITMAP_SIZE - i); j++) {
362 result = bitmap_find_next_zero_area_off(bmap_all_ones,
363 TEST_BITMAP_SIZE,
364 i,
365 j,
366 0, 0);
367 if (result != TEST_BITMAP_SIZE)
368 unit_return_fail(m, FAIL_MSG_EX,
369 "all_ones: failed", i, j);
370 }
371 }
372
373 /*
374 * Alternating nibbles (4 bits). Make sure we don't start searching from
375 * too high in the bitmap since that will cause failures that are
376 * actually valid. This keeps the logic in the below loop a little more
377 * simple.
378 */
379 memset(words, 0x0f, sizeof(words));
380 for (i = 0; i < ((NUM_WORDS * BITS_PER_LONG) - 8); i++) {
381 for (j = 0; j < ((NUM_WORDS * BITS_PER_LONG) - i - 8); j++) {
382 result = bitmap_find_next_zero_area_off(words,
383 NUM_WORDS * BITS_PER_LONG,
384 i,
385 j,
386 0, 0);
387
388 /*
389 * Should only return a valid result when j < 4 (since
390 * the map consists of 4 ones, then 4 zeros,
391 * alternating.
392 */
393 if (j <= 4 && result >= (NUM_WORDS * BITS_PER_LONG))
394 unit_return_fail(m, FAIL_MSG_EX,
395 "alternating-nibbles: failed",
396 i, j);
397 if (j > 4 && result != (NUM_WORDS * BITS_PER_LONG))
398 unit_return_fail(m, FAIL_MSG_EX,
399 "alternating-nibbles: failed",
400 i, j);
401
402 result = bitmap_find_next_zero_area_off(words,
403 NUM_WORDS * BITS_PER_LONG,
404 i,
405 (j % 4) + 1,
406 0x3, 0);
407 if (result % 8 != 4)
408 unit_return_fail(m, FAIL_MSG_EX,
409 "basic-align_mask: failed",
410 i, j);
411
412
413 result = bitmap_find_next_zero_area_off(words,
414 NUM_WORDS * BITS_PER_LONG,
415 i,
416 (j % 2) + 1,
417 0x7, 2);
418
419 if (result % 8 != 6)
420 unit_return_fail(m, FAIL_MSG_EX,
421 "basic-align_offset: failed",
422 i, j);
423 }
424 }
425
426#undef FAIL_MSG
427#undef FAIL_MSG_EX
428 return UNIT_SUCCESS;
429}
430
431struct test_setclear_args {
432 bool clear;
433};
434
435static struct test_setclear_args set_args = {
436 .clear = false,
437};
438
439static struct test_setclear_args clear_args = {
440 .clear = true,
441};
442
443static void __print_bitmap(unsigned long *map, unsigned long length)
444{
445 unsigned int idx, bidx;
446
447 for (idx = 0; idx < (length / BITS_PER_LONG); idx++) {
448 printf(" ");
449 for (bidx = 0; bidx < BITS_PER_LONG; bidx++) {
450 printf("%c", (map[idx] & BIT(bidx)) ? '1' : '0');
451 if (bidx % 4 == 3)
452 printf(" ");
453 }
454 printf("\n");
455 }
456
457 printf("\n");
458}
459
460/*
461 * Verify the bits from i to i + len are set and no others are set. 'size' is in
462 * bits (not words).
463 */
464static bool verify_set_buf(unsigned long *words, unsigned long size,
465 unsigned long i, unsigned long len,
466 bool invert)
467{
468 unsigned int idx, bidx;
469 unsigned int bit, bit_value;
470 unsigned int set_start, set_end;
471 unsigned int set_value = invert ? 0 : 1;
472 unsigned int clear_value = invert ? 1 : 0;
473
474 set_start = i;
475 set_end = i + len;
476
477 for (idx = 0; idx < (size / BITS_PER_LONG); idx++) {
478 for (bidx = 0; bidx < BITS_PER_LONG; bidx++) {
479 bit = idx * BITS_PER_LONG + bidx;
480 bit_value = !!(words[idx] & BIT(bidx));
481
482 /*
483 * Bit inside set zone.
484 */
485 if ((bit >= set_start && bit < set_end) &&
486 bit_value != set_value)
487 return false;
488
489 /*
490 * Bit outside set zone.
491 */
492 if ((bit < set_start || bit >= set_end) &&
493 bit_value != clear_value)
494 return false;
495 }
496 }
497
498 return true;
499}
500
501static int test_single_bitops(struct unit_module *m,
502 struct gk20a *g, void *__args)
503{
504 unsigned long words[NUM_WORDS];
505 unsigned int i;
506
507 /*
508 * First set all the bits and make sure the words are set.
509 */
510 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++)
511 set_bit(i, words);
512
513 if (!verify_set_buf(words, NUM_WORDS * BITS_PER_LONG,
514 0, NUM_WORDS * BITS_PER_LONG, false)) {
515 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
516 unit_return_fail(m, "set_bit: Failed to set a bit!\n");
517 }
518
519 /*
520 * Now make sure the test_bit works for set bits.
521 */
522 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++)
523 if (!test_bit(i, words))
524 unit_return_fail(m, "test_bit: bit %d failed!\n", i);
525
526 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++)
527 clear_bit(i, words);
528
529 if (!verify_set_buf(words, NUM_WORDS * BITS_PER_LONG,
530 0, NUM_WORDS * BITS_PER_LONG, true)) {
531 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
532 unit_return_fail(m, "clear_bit: Failed to set a bit!\n");
533 }
534
535 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++)
536 if (test_bit(i, words))
537 unit_return_fail(m, "test_bit: bit %d failed!\n", i);
538
539 return UNIT_SUCCESS;
540}
541
542static int test_bit_setclear(struct unit_module *m,
543 struct gk20a *g, void *__args)
544{
545 struct test_setclear_args *args = __args;
546 void (*testfn)(int, volatile unsigned long *) =
547 args->clear ? clear_bit : set_bit;
548 unsigned long words[NUM_WORDS];
549 unsigned int i;
550
551 memset(words, args->clear ? 0xff : 0x0, sizeof(words));
552
553 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++)
554 testfn(i, words);
555
556 if (!verify_set_buf(words, NUM_WORDS * BITS_PER_LONG,
557 0, NUM_WORDS * BITS_PER_LONG, args->clear)) {
558 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
559 unit_return_fail(m, "%s_bit: Failed to %s a bit!\n",
560 args->clear ? "clear" : "set",
561 args->clear ? "clear" : "set");
562 }
563
564 return UNIT_SUCCESS;
565}
566
567static int test_test_and_setclear_bit(struct unit_module *m,
568 struct gk20a *g, void *__args)
569{
570 struct test_setclear_args *args = __args;
571 bool (*testfn)(int, volatile unsigned long *) =
572 args->clear ? test_and_clear_bit : test_and_set_bit;
573 bool (*testfn_reset)(int, volatile unsigned long *) =
574 args->clear ? test_and_set_bit : test_and_clear_bit;
575 unsigned long words[NUM_WORDS];
576 unsigned int i;
577
578 memset(words, args->clear ? 0xff : 0x0, sizeof(words));
579
580 /*
581 * First we will set/clear the bits. Then we will clear/set the bits
582 * (i.e do the opposite of this loop).
583 */
584 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++) {
585 bool status = testfn(i, words);
586
587 if (status != args->clear) {
588 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
589 unit_return_fail(m, "test_and_%s_bit: Failed at %d\n",
590 args->clear ? "clear" : "set", i);
591 }
592 }
593
594 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++) {
595 bool status = testfn_reset(i, words);
596
597 if (status == args->clear) {
598 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
599 unit_return_fail(m, "test_and_%s_bit: Failed at %d\n",
600 args->clear ? "set" : "clear", i);
601 }
602 }
603
604 /* The bitmap should be the same as we started with. */
605 if (!verify_set_buf(words, NUM_WORDS * BITS_PER_LONG,
606 0, NUM_WORDS * BITS_PER_LONG, !args->clear)) {
607 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
608 unit_return_fail(m,
609 "test_and_%s_bit: Final bitmap is wrong!\n",
610 args->clear ? "set" : "clear");
611 }
612
613 return UNIT_SUCCESS;
614}
615
616static int test_bitmap_setclear(struct unit_module *m,
617 struct gk20a *g, void *__args)
618{
619 struct test_setclear_args *args = __args;
620 void (*testfn)(unsigned long *, unsigned int, int) =
621 args->clear ? bitmap_clear : bitmap_set;
622 unsigned long words[NUM_WORDS];
623 unsigned long i, j;
624 int set_char = args->clear ? 0xff : 0x0;
625
626 /*
627 * Run through all combos of set/clear for a 4 word bitmap.
628 */
629 for (i = 0; i < NUM_WORDS * BITS_PER_LONG; i++) {
630 for (j = 0; j < (NUM_WORDS * BITS_PER_LONG) - i; j++) {
631 /*
632 * Just make sure we start in a known state.
633 */
634 memset(words, set_char, sizeof(words));
635
636 testfn(words, i, j);
637
638 if (!verify_set_buf(words, NUM_WORDS * BITS_PER_LONG,
639 i, j, args->clear)) {
640 __print_bitmap(words, NUM_WORDS * BITS_PER_LONG);
641 unit_return_fail(m,
642 "%s: fail at i,j = %lu,%lu\n",
643 args->clear ? "clear" : "set",
644 i, j);
645 }
646 }
647 }
648
649 return UNIT_SUCCESS;
650}
651
652
653
654struct unit_module_test posix_bitops_tests[] = {
655 UNIT_TEST(info, test_bitmap_info, NULL),
656 UNIT_TEST(ffs, test_ffs, NULL),
657 UNIT_TEST(fls, test_fls, NULL),
658 UNIT_TEST(ffz, test_ffz, NULL),
659 UNIT_TEST(find_first_bit, test_find_first_bit, &first_bit_args),
660 UNIT_TEST(find_first_zero_bit, test_find_first_bit, &first_zero_args),
661 UNIT_TEST(find_next_bit, test_find_next_bit, NULL),
662 UNIT_TEST(find_zero_area, test_find_zero_area, NULL),
663 UNIT_TEST(single_bitops, test_single_bitops, NULL),
664 UNIT_TEST(bit_set, test_bit_setclear, &set_args),
665 UNIT_TEST(bit_clear, test_bit_setclear, &clear_args),
666 UNIT_TEST(test_and_set_bit, test_test_and_setclear_bit, &set_args),
667 UNIT_TEST(test_and_clear_bit, test_test_and_setclear_bit, &clear_args),
668 UNIT_TEST(bitmap_set, test_bitmap_setclear, &set_args),
669 UNIT_TEST(bitmap_clear, test_bitmap_setclear, &clear_args),
670};
671
672UNIT_MODULE(posix_bitops, posix_bitops_tests, UNIT_PRIO_POSIX_TEST);