@@ -155,6 +155,37 @@ static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
155155 return true;
156156}
157157
158+ static bool __init __check_eq_clump (const char * srcfile , unsigned int line ,
159+ const unsigned int offset ,
160+ const unsigned int size ,
161+ const unsigned long * const clump_exp ,
162+ const unsigned long * const clump ,
163+ const unsigned long clump_size )
164+ {
165+ unsigned long exp ;
166+
167+ if (offset >= size ) {
168+ pr_warn ("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n" ,
169+ srcfile , line , size , offset );
170+ return false;
171+ }
172+
173+ exp = clump_exp [offset / clump_size ];
174+ if (!exp ) {
175+ pr_warn ("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0" ,
176+ srcfile , line , offset );
177+ return false;
178+ }
179+
180+ if (* clump != exp ) {
181+ pr_warn ("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX" ,
182+ srcfile , line , exp , * clump );
183+ return false;
184+ }
185+
186+ return true;
187+ }
188+
158189#define __expect_eq (suffix , ...) \
159190 ({ \
160191 int result = 0; \
@@ -172,6 +203,7 @@ static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
172203#define expect_eq_pbl (...) __expect_eq(pbl, ##__VA_ARGS__)
173204#define expect_eq_u32_array (...) __expect_eq(u32_array, ##__VA_ARGS__)
174205#define expect_eq_clump8 (...) __expect_eq(clump8, ##__VA_ARGS__)
206+ #define expect_eq_clump (...) __expect_eq(clump, ##__VA_ARGS__)
175207
176208static void __init test_zero_clear (void )
177209{
@@ -530,6 +562,28 @@ static void noinline __init test_mem_optimisations(void)
530562 }
531563}
532564
565+ static const unsigned long clump_bitmap_data [] __initconst = {
566+ 0x38000201 ,
567+ 0x05ff0f38 ,
568+ 0xeffedcba ,
569+ 0xbbbbabcd ,
570+ 0x000000aa ,
571+ 0x000000aa ,
572+ 0x00ff0000 ,
573+ 0xaaaaaa00 ,
574+ 0xff000000 ,
575+ 0x00aa0000 ,
576+ 0x00000000 ,
577+ 0x00000000 ,
578+ 0x00000000 ,
579+ 0x0f000000 ,
580+ 0x00ff0000 ,
581+ 0xaaaaaa00 ,
582+ 0xff000000 ,
583+ 0x00aa0000 ,
584+ 0x00000ac0 ,
585+ };
586+
533587static const unsigned char clump_exp [] __initconst = {
534588 0x01 , /* 1 bit set */
535589 0x02 , /* non-edge 1 bit set */
@@ -541,6 +595,95 @@ static const unsigned char clump_exp[] __initconst = {
541595 0x05 , /* non-adjacent 2 bits set */
542596};
543597
598+ static const unsigned long clump_exp1 [] __initconst = {
599+ 0x01 , /* 1 bit set */
600+ 0x02 , /* non-edge 1 bit set */
601+ 0x00 , /* zero bits set */
602+ 0x38 , /* 3 bits set across 4-bit boundary */
603+ 0x38 , /* Repeated clump */
604+ 0x0F , /* 4 bits set */
605+ 0xFF , /* all bits set */
606+ 0x05 , /* non-adjacent 2 bits set */
607+ };
608+
609+ static const unsigned long clump_exp2 [] __initconst = {
610+ 0xfedcba , /* 24 bits */
611+ 0xabcdef ,
612+ 0xaabbbb , /* Clump split between 2 words */
613+ 0x000000 , /* zeroes in between */
614+ 0x0000aa ,
615+ 0x000000 ,
616+ 0x0000ff ,
617+ 0xaaaaaa ,
618+ 0x000000 ,
619+ 0x0000ff ,
620+ };
621+
622+ static const unsigned long clump_exp3 [] __initconst = {
623+ 0x00000000 , /* starting with 0s*/
624+ 0x00000000 , /* All 0s */
625+ 0x00000000 ,
626+ 0x00000000 ,
627+ 0x3f00000f , /* Non zero set */
628+ 0x2aa80003 ,
629+ 0x00000aaa ,
630+ 0x00003fc0 ,
631+ };
632+
633+ static const unsigned long clump_exp4 [] __initconst = {
634+ 0x00 ,
635+ 0x2b ,
636+ };
637+
638+ struct clump_test_data_params {
639+ DECLARE_BITMAP (data , 256 );
640+ unsigned long count ;
641+ unsigned long offset ;
642+ unsigned long limit ;
643+ unsigned long clump_size ;
644+ unsigned long const * exp ;
645+ };
646+
647+ static struct clump_test_data_params clump_test_data [] __initdata =
648+ { {{0 }, 2 , 0 , 64 , 8 , clump_exp1 },
649+ {{0 }, 8 , 2 , 240 , 24 , clump_exp2 },
650+ {{0 }, 8 , 10 , 240 , 30 , clump_exp3 },
651+ {{0 }, 1 , 18 , 18 , 6 , clump_exp4 } };
652+
653+ static void __init prepare_test_data (unsigned int index )
654+ {
655+ int i ;
656+ unsigned long width = 0 ;
657+
658+ for (i = 0 ; i < clump_test_data [index ].count ; i ++ )
659+ {
660+ bitmap_set_value (clump_test_data [index ].data ,
661+ clump_bitmap_data [(clump_test_data [index ].offset )++ ], width , 32 );
662+ width += 32 ;
663+ }
664+ }
665+
666+ static void __init execute_for_each_set_clump_test (unsigned int index )
667+ {
668+ unsigned long start , clump ;
669+
670+ for_each_set_clump (start , clump , clump_test_data [index ].data ,
671+ clump_test_data [index ].limit ,
672+ clump_test_data [index ].clump_size )
673+ expect_eq_clump (start , clump_test_data [index ].limit , clump_test_data [index ].exp ,
674+ & clump , clump_test_data [index ].clump_size );
675+ }
676+
677+ static void __init test_for_each_set_clump (void )
678+ {
679+ unsigned int i ;
680+
681+ for (i = 0 ; i < ARRAY_SIZE (clump_test_data ); i ++ ) {
682+ prepare_test_data (i );
683+ execute_for_each_set_clump_test (i );
684+ }
685+ }
686+
544687static void __init test_for_each_set_clump8 (void )
545688{
546689#define CLUMP_EXP_NUMBITS 64
@@ -631,6 +774,7 @@ static void __init selftest(void)
631774 test_bitmap_parselist ();
632775 test_mem_optimisations ();
633776 test_for_each_set_clump8 ();
777+ test_for_each_set_clump ();
634778 test_bitmap_cut ();
635779}
636780
0 commit comments