@@ -23,6 +23,9 @@ int usage(char *progname)
23
23
printf (" CHAR5: a|b|c|d indicates the output matching EAX|EBX|ECX|EDX\n" );
24
24
printf (" NUM6: number of decimal digits in CHAR5 output register matching SPEC\n" );
25
25
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 );
26
29
exit (2 );
27
30
}
28
31
@@ -58,7 +61,7 @@ int h_to_b(long n)
58
61
return 0 ;
59
62
}
60
63
61
- /* Check that the cpuid target output bits are correct. */
64
+ /* Check that the cpuid target output of multi- bits are correct. */
62
65
int check_id (long n , int ex_number )
63
66
{
64
67
int i = 0 ;
@@ -81,11 +84,19 @@ int check_id(long n, int ex_number)
81
84
return 0 ;
82
85
}
83
86
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
+
84
95
int main (int argc , char * argv [])
85
96
{
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 ] ;
89
100
90
101
if (argc == 1 ) {
91
102
usage (argv [0 ]);
@@ -114,6 +125,45 @@ int main(int argc, char *argv[])
114
125
usage (argv [0 ]);
115
126
if (sscanf (argv [6 ], "%d" , & ex_n ) != 1 )
116
127
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 ]);
117
167
} else {
118
168
if (sscanf (argv [1 ], "%x" , & eax ) != 1 )
119
169
usage (argv [0 ]);
@@ -140,18 +190,34 @@ int main(int argc, char *argv[])
140
190
printf (" edx=%08x || Binary: " , edx );
141
191
h_to_b (edx );
142
192
143
- printf ("Now check cpuid e%cx, bit %d\n" , ex , ex_n );
144
193
if (ex == 'a' ) {
145
- test_result = check_id ( eax , ex_n ) ;
194
+ result_num = eax ;
146
195
} else if (ex == 'b' ) {
147
- test_result = check_id ( ebx , ex_n ) ;
196
+ result_num = ebx ;
148
197
} else if (ex == 'c' ) {
149
- test_result = check_id ( ecx , ex_n ) ;
198
+ result_num = ecx ;
150
199
} 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
+ }
152
218
} 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 ) ;
155
221
}
156
222
157
223
printf ("Done! Return:%d.\n\n" , test_result );
0 commit comments