diff --git a/BM/tools/cpuid_check/cpuid_check.c b/BM/tools/cpuid_check/cpuid_check.c index d6798c0..13b957c 100644 --- a/BM/tools/cpuid_check/cpuid_check.c +++ b/BM/tools/cpuid_check/cpuid_check.c @@ -23,6 +23,9 @@ int usage(char *progname) printf(" CHAR5: a|b|c|d indicates the output matching EAX|EBX|ECX|EDX\n"); printf(" NUM6: number of decimal digits in CHAR5 output register matching SPEC\n"); printf("CET SHSTK cpuid check example:\n# %s 7 0 0 0 c 7\n", progname); + printf("Or STR6: 4:7 bit 4 to 7, start from 0, right to left\n"); + printf("Or NUM7: num in decimal. Check num should be same as value of above bit 4:7\n"); + printf("Or sample:# %s 1 0 0 0 a 4:7 5\n", progname); exit(2); } @@ -58,7 +61,7 @@ int h_to_b(long n) return 0; } -/* Check that the cpuid target output bits are correct. */ +/* Check that the cpuid target output of multi-bits are correct. */ int check_id(long n, int ex_number) { int i = 0; @@ -81,11 +84,19 @@ int check_id(long n, int ex_number) return 0; } +unsigned int extract_bits(unsigned int num, int start, int end) +{ + unsigned int mask = 0; + + mask = ((1 << (end - start + 1)) - 1) << start; + return (num & mask) >> start; +} + int main(int argc, char *argv[]) { - unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; - int ex_n, test_result = 1; - char ex = 'e'; + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0, result_num = 0; + int ex_n, test_result = 1, start = 0, end = 0, extract_bits_num = 0; + char ex = 'e', n_bits[7]; if (argc == 1) { usage(argv[0]); @@ -114,6 +125,45 @@ int main(int argc, char *argv[]) usage(argv[0]); if (sscanf(argv[6], "%d", &ex_n) != 1) usage(argv[0]); + } else if (argc == 8) { + if (sscanf(argv[1], "%x", &eax) != 1) + usage(argv[0]); + + if (sscanf(argv[2], "%x", &ebx) != 1) + usage(argv[0]); + if (sscanf(argv[3], "%x", &ecx) != 1) + usage(argv[0]); + if (sscanf(argv[4], "%x", &edx) != 1) + usage(argv[0]); + if (sscanf(argv[5], "%c", &ex) != 1) + usage(argv[0]); + + memset(n_bits, 0, sizeof(n_bits)); + if (sscanf(argv[6], "%6s", &n_bits) != 1) + usage(argv[0]); + + printf("7 parameters: Check CPUID.(EAX=%dH, ECX=%dH):e%cx[bit %s]\n", + eax, ecx, ex, n_bits); + + /* + * Check if n_bits contains ":", like bit 4:7 + */ + if (!strchr(n_bits, ':')) { + fprintf(stderr, "Error: n_bits must contain ':' char like 4:7\n"); + usage(argv[0]); + } + + if (sscanf(n_bits, "%d:%d", &start, &end) != 2) { + fprintf(stderr, "Invalid bit range format. Expected format: 4:7\n"); + usage(argv[0]); + } else if (start > end) { + printf("start bit:%d should equal or less than end:%d\n", + start, end); + usage(argv[0]); + } + + if (sscanf(argv[7], "%d", &ex_n) != 1) + usage(argv[0]); } else { if (sscanf(argv[1], "%x", &eax) != 1) usage(argv[0]); @@ -140,18 +190,34 @@ int main(int argc, char *argv[]) printf(" edx=%08x || Binary: ", edx); h_to_b(edx); - printf("Now check cpuid e%cx, bit %d\n", ex, ex_n); if (ex == 'a') { - test_result = check_id(eax, ex_n); + result_num = eax; } else if (ex == 'b') { - test_result = check_id(ebx, ex_n); + result_num = ebx; } else if (ex == 'c') { - test_result = check_id(ecx, ex_n); + result_num = ecx; } else if (ex == 'd') { - test_result = check_id(edx, ex_n); + result_num = edx; + } else { + printf("No check point, not in a-d, skip. Return 0.\n"); + return test_result; + } + + if (strchr(n_bits, ':')) { + printf("Now check cpuid e%cx, bit %d:%d\n", ex, start, end); + extract_bits_num = extract_bits(result_num, start, end); + if (extract_bits_num == ex_n) { + printf("CPUID output: e%cx[bit %d:%d]:%d == %d, pass.\n", + ex, start, end, extract_bits_num, ex_n); + test_result = 0; + } else { + printf("CPUID output: e%cx[bit %d:%d]:%d != %d, fail.\n", + ex, start, end, extract_bits_num, ex_n); + test_result = 1; + } } else { - printf("No check point, not in a-d, skip.\n"); - test_result = 0; + printf("Now check cpuid e%cx, bit %d\n", ex, ex_n); + test_result = check_id(result_num, ex_n); } printf("Done! Return:%d.\n\n", test_result);