@@ -23,6 +23,9 @@ int usage(char *progname)
2323 printf (" CHAR5: a|b|c|d indicates the output matching EAX|EBX|ECX|EDX\n" );
2424 printf (" NUM6: number of decimal digits in CHAR5 output register matching SPEC\n" );
2525 printf ("CET SHSTK cpuid check example:\n# %s 7 0 0 0 c 7\n" , progname );
26+ printf ("Or STR6: 4:7 bit 4 to 7, start from 0, right to left\n" );
27+ printf ("Or NUM7: num in decimal. Check num should be same as value of above bit 4:7\n" );
28+ printf ("Or sample:# %s 1 0 0 0 a 4:7 5\n" , progname );
2629 exit (2 );
2730}
2831
@@ -58,7 +61,7 @@ int h_to_b(long n)
5861 return 0 ;
5962}
6063
61- /* Check that the cpuid target output bits are correct. */
64+ /* Check that the cpuid target output of multi- bits are correct. */
6265int check_id (long n , int ex_number )
6366{
6467 int i = 0 ;
@@ -81,11 +84,19 @@ int check_id(long n, int ex_number)
8184 return 0 ;
8285}
8386
87+ unsigned int extract_bits (unsigned int num , int start , int end )
88+ {
89+ unsigned int mask = 0 ;
90+
91+ mask = ((1 << (end - start + 1 )) - 1 ) << start ;
92+ return (num & mask ) >> start ;
93+ }
94+
8495int main (int argc , char * argv [])
8596{
86- unsigned int eax = 0 , ebx = 0 , ecx = 0 , edx = 0 ;
87- int ex_n , test_result = 1 ;
88- char ex = 'e' ;
97+ unsigned int eax = 0 , ebx = 0 , ecx = 0 , edx = 0 , result_num = 0 ;
98+ int ex_n , test_result = 1 , start = 0 , end = 0 , extract_bits_num = 0 ;
99+ char ex = 'e' , n_bits [ 7 ] ;
89100
90101 if (argc == 1 ) {
91102 usage (argv [0 ]);
@@ -114,6 +125,45 @@ int main(int argc, char *argv[])
114125 usage (argv [0 ]);
115126 if (sscanf (argv [6 ], "%d" , & ex_n ) != 1 )
116127 usage (argv [0 ]);
128+ } else if (argc == 8 ) {
129+ if (sscanf (argv [1 ], "%x" , & eax ) != 1 )
130+ usage (argv [0 ]);
131+
132+ if (sscanf (argv [2 ], "%x" , & ebx ) != 1 )
133+ usage (argv [0 ]);
134+ if (sscanf (argv [3 ], "%x" , & ecx ) != 1 )
135+ usage (argv [0 ]);
136+ if (sscanf (argv [4 ], "%x" , & edx ) != 1 )
137+ usage (argv [0 ]);
138+ if (sscanf (argv [5 ], "%c" , & ex ) != 1 )
139+ usage (argv [0 ]);
140+
141+ memset (n_bits , 0 , sizeof (n_bits ));
142+ if (sscanf (argv [6 ], "%6s" , & n_bits ) != 1 )
143+ usage (argv [0 ]);
144+
145+ printf ("7 parameters: Check CPUID.(EAX=%dH, ECX=%dH):e%cx[bit %s]\n" ,
146+ eax , ecx , ex , n_bits );
147+
148+ /*
149+ * Check if n_bits contains ":", like bit 4:7
150+ */
151+ if (!strchr (n_bits , ':' )) {
152+ fprintf (stderr , "Error: n_bits must contain ':' char like 4:7\n" );
153+ usage (argv [0 ]);
154+ }
155+
156+ if (sscanf (n_bits , "%d:%d" , & start , & end ) != 2 ) {
157+ fprintf (stderr , "Invalid bit range format. Expected format: 4:7\n" );
158+ usage (argv [0 ]);
159+ } else if (start > end ) {
160+ printf ("start bit:%d should equal or less than end:%d\n" ,
161+ start , end );
162+ usage (argv [0 ]);
163+ }
164+
165+ if (sscanf (argv [7 ], "%d" , & ex_n ) != 1 )
166+ usage (argv [0 ]);
117167 } else {
118168 if (sscanf (argv [1 ], "%x" , & eax ) != 1 )
119169 usage (argv [0 ]);
@@ -140,18 +190,34 @@ int main(int argc, char *argv[])
140190 printf (" edx=%08x || Binary: " , edx );
141191 h_to_b (edx );
142192
143- printf ("Now check cpuid e%cx, bit %d\n" , ex , ex_n );
144193 if (ex == 'a' ) {
145- test_result = check_id ( eax , ex_n ) ;
194+ result_num = eax ;
146195 } else if (ex == 'b' ) {
147- test_result = check_id ( ebx , ex_n ) ;
196+ result_num = ebx ;
148197 } else if (ex == 'c' ) {
149- test_result = check_id ( ecx , ex_n ) ;
198+ result_num = ecx ;
150199 } else if (ex == 'd' ) {
151- test_result = check_id (edx , ex_n );
200+ result_num = edx ;
201+ } else {
202+ printf ("No check point, not in a-d, skip. Return 0.\n" );
203+ return test_result ;
204+ }
205+
206+ if (strchr (n_bits , ':' )) {
207+ printf ("Now check cpuid e%cx, bit %d:%d\n" , ex , start , end );
208+ extract_bits_num = extract_bits (result_num , start , end );
209+ if (extract_bits_num == ex_n ) {
210+ printf ("CPUID output: e%cx[bit %d:%d]:%d == %d, pass.\n" ,
211+ ex , start , end , extract_bits_num , ex_n );
212+ test_result = 0 ;
213+ } else {
214+ printf ("CPUID output: e%cx[bit %d:%d]:%d != %d, fail.\n" ,
215+ ex , start , end , extract_bits_num , ex_n );
216+ test_result = 1 ;
217+ }
152218 } else {
153- printf ("No check point, not in a-d, skip. \n" );
154- test_result = 0 ;
219+ printf ("Now check cpuid e%cx, bit %d \n" , ex , ex_n );
220+ test_result = check_id ( result_num , ex_n ) ;
155221 }
156222
157223 printf ("Done! Return:%d.\n\n" , test_result );
0 commit comments