mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 07:50:40 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f2f3d3a16 | ||
|
|
6dd041bf9f | ||
|
|
b45c09efff | ||
|
|
ec5f80adc1 | ||
|
|
ecca042d86 | ||
|
|
e8d2898ae3 | ||
|
|
044608f31f | ||
|
|
7420792ef5 | ||
|
|
db32cccd91 | ||
|
|
a8d8ac2e91 |
@@ -1,7 +1,7 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.2.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.2.
|
||||||
.TH CPUFETCH "1" "March 2021" "cpufetch v0.96 (x86_64 build)" "User Commands"
|
.TH CPUFETCH "1" "March 2021" "cpufetch v0.97 (x86_64 build)" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cpufetch \- manual page for cpufetch v0.96 (x86_64 build)
|
cpufetch \- manual page for cpufetch v0.97 (x86_64 build)
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B cpufetch
|
.B cpufetch
|
||||||
[\fI\,OPTION\/\fR]...
|
[\fI\,OPTION\/\fR]...
|
||||||
@@ -21,6 +21,9 @@ Prints CPU model and cpuid levels (debug purposes)
|
|||||||
\fB\-v\fR, \fB\-\-verbose\fR
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
Prints extra information (if available) about how cpufetch tried fetching information
|
Prints extra information (if available) about how cpufetch tried fetching information
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-r\fR, \fB\-\-raw\fR
|
||||||
|
Prints raw cpuid data
|
||||||
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
Prints this help and exit
|
Prints this help and exit
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ static const char *SYTLES_STR_LIST[] = {
|
|||||||
struct args_struct {
|
struct args_struct {
|
||||||
bool debug_flag;
|
bool debug_flag;
|
||||||
bool help_flag;
|
bool help_flag;
|
||||||
|
bool raw_flag;
|
||||||
bool verbose_flag;
|
bool verbose_flag;
|
||||||
bool version_flag;
|
bool version_flag;
|
||||||
STYLE style;
|
STYLE style;
|
||||||
@@ -30,6 +31,7 @@ const char args_chr[] = {
|
|||||||
/* [ARG_CHAR_STYLE] = */ 's',
|
/* [ARG_CHAR_STYLE] = */ 's',
|
||||||
/* [ARG_CHAR_COLOR] = */ 'c',
|
/* [ARG_CHAR_COLOR] = */ 'c',
|
||||||
/* [ARG_CHAR_HELP] = */ 'h',
|
/* [ARG_CHAR_HELP] = */ 'h',
|
||||||
|
/* [ARG_CHAR_RAW] = */ 'r',
|
||||||
/* [ARG_CHAR_DEBUG] = */ 'd',
|
/* [ARG_CHAR_DEBUG] = */ 'd',
|
||||||
/* [ARG_CHAR_VERBOSE] = */ 'v',
|
/* [ARG_CHAR_VERBOSE] = */ 'v',
|
||||||
/* [ARG_CHAR_VERSION] = */ 'V',
|
/* [ARG_CHAR_VERSION] = */ 'V',
|
||||||
@@ -39,6 +41,7 @@ const char *args_str[] = {
|
|||||||
/* [ARG_CHAR_STYLE] = */ "style",
|
/* [ARG_CHAR_STYLE] = */ "style",
|
||||||
/* [ARG_CHAR_COLOR] = */ "color",
|
/* [ARG_CHAR_COLOR] = */ "color",
|
||||||
/* [ARG_CHAR_HELP] = */ "help",
|
/* [ARG_CHAR_HELP] = */ "help",
|
||||||
|
/* [ARG_CHAR_RAW] = */ "raw",
|
||||||
/* [ARG_CHAR_DEBUG] = */ "debug",
|
/* [ARG_CHAR_DEBUG] = */ "debug",
|
||||||
/* [ARG_CHAR_VERBOSE] = */ "verbose",
|
/* [ARG_CHAR_VERBOSE] = */ "verbose",
|
||||||
/* [ARG_CHAR_VERSION] = */ "version",
|
/* [ARG_CHAR_VERSION] = */ "version",
|
||||||
@@ -66,6 +69,10 @@ bool show_debug() {
|
|||||||
return args.debug_flag;
|
return args.debug_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool show_raw() {
|
||||||
|
return args.raw_flag;
|
||||||
|
}
|
||||||
|
|
||||||
bool verbose_enabled() {
|
bool verbose_enabled() {
|
||||||
return args.verbose_flag;
|
return args.verbose_flag;
|
||||||
}
|
}
|
||||||
@@ -182,9 +189,15 @@ char* build_short_options() {
|
|||||||
char* str = (char *) malloc(sizeof(char) * (len*2 + 1));
|
char* str = (char *) malloc(sizeof(char) * (len*2 + 1));
|
||||||
memset(str, 0, sizeof(char) * (len*2 + 1));
|
memset(str, 0, sizeof(char) * (len*2 + 1));
|
||||||
|
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
sprintf(str, "%c:%c:%c%c%c%c%c",
|
||||||
|
c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP], c[ARG_RAW],
|
||||||
|
c[ARG_DEBUG], c[ARG_VERBOSE], c[ARG_VERSION]);
|
||||||
|
#else
|
||||||
sprintf(str, "%c:%c:%c%c%c%c",
|
sprintf(str, "%c:%c:%c%c%c%c",
|
||||||
c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP],
|
c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP],
|
||||||
c[ARG_DEBUG], c[ARG_VERBOSE], c[ARG_VERSION]);
|
c[ARG_DEBUG], c[ARG_VERBOSE], c[ARG_VERSION]);
|
||||||
|
#endif
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -196,6 +209,7 @@ bool parse_args(int argc, char* argv[]) {
|
|||||||
|
|
||||||
bool color_flag = false;
|
bool color_flag = false;
|
||||||
args.debug_flag = false;
|
args.debug_flag = false;
|
||||||
|
args.raw_flag = false;
|
||||||
args.verbose_flag = false;
|
args.verbose_flag = false;
|
||||||
args.help_flag = false;
|
args.help_flag = false;
|
||||||
args.style = STYLE_EMPTY;
|
args.style = STYLE_EMPTY;
|
||||||
@@ -205,6 +219,9 @@ bool parse_args(int argc, char* argv[]) {
|
|||||||
{args_str[ARG_STYLE], required_argument, 0, args_chr[ARG_STYLE] },
|
{args_str[ARG_STYLE], required_argument, 0, args_chr[ARG_STYLE] },
|
||||||
{args_str[ARG_COLOR], required_argument, 0, args_chr[ARG_COLOR] },
|
{args_str[ARG_COLOR], required_argument, 0, args_chr[ARG_COLOR] },
|
||||||
{args_str[ARG_HELP], no_argument, 0, args_chr[ARG_HELP] },
|
{args_str[ARG_HELP], no_argument, 0, args_chr[ARG_HELP] },
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
{args_str[ARG_RAW], no_argument, 0, args_chr[ARG_RAW] },
|
||||||
|
#endif
|
||||||
{args_str[ARG_DEBUG], no_argument, 0, args_chr[ARG_DEBUG] },
|
{args_str[ARG_DEBUG], no_argument, 0, args_chr[ARG_DEBUG] },
|
||||||
{args_str[ARG_VERBOSE], no_argument, 0, args_chr[ARG_VERBOSE] },
|
{args_str[ARG_VERBOSE], no_argument, 0, args_chr[ARG_VERBOSE] },
|
||||||
{args_str[ARG_VERSION], no_argument, 0, args_chr[ARG_VERSION] },
|
{args_str[ARG_VERSION], no_argument, 0, args_chr[ARG_VERSION] },
|
||||||
@@ -241,6 +258,9 @@ bool parse_args(int argc, char* argv[]) {
|
|||||||
else if(opt == args_chr[ARG_HELP]) {
|
else if(opt == args_chr[ARG_HELP]) {
|
||||||
args.help_flag = true;
|
args.help_flag = true;
|
||||||
}
|
}
|
||||||
|
else if(opt == args_chr[ARG_RAW]) {
|
||||||
|
args.raw_flag = true;
|
||||||
|
}
|
||||||
else if(opt == args_chr[ARG_VERBOSE]) {
|
else if(opt == args_chr[ARG_VERBOSE]) {
|
||||||
args.verbose_flag = true;
|
args.verbose_flag = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ enum {
|
|||||||
ARG_STYLE,
|
ARG_STYLE,
|
||||||
ARG_COLOR,
|
ARG_COLOR,
|
||||||
ARG_HELP,
|
ARG_HELP,
|
||||||
|
ARG_RAW,
|
||||||
ARG_DEBUG,
|
ARG_DEBUG,
|
||||||
ARG_VERBOSE,
|
ARG_VERBOSE,
|
||||||
ARG_VERSION
|
ARG_VERSION
|
||||||
@@ -43,6 +44,7 @@ extern const char *args_str[];
|
|||||||
int max_arg_str_length();
|
int max_arg_str_length();
|
||||||
bool parse_args(int argc, char* argv[]);
|
bool parse_args(int argc, char* argv[]);
|
||||||
bool show_help();
|
bool show_help();
|
||||||
|
bool show_raw();
|
||||||
bool show_debug();
|
bool show_debug();
|
||||||
bool show_version();
|
bool show_version();
|
||||||
bool verbose_enabled();
|
bool verbose_enabled();
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ struct cpuInfo {
|
|||||||
uint32_t maxLevels;
|
uint32_t maxLevels;
|
||||||
// Max cpuids extended levels
|
// Max cpuids extended levels
|
||||||
uint32_t maxExtendedLevels;
|
uint32_t maxExtendedLevels;
|
||||||
|
// Topology Extensions (AMD only)
|
||||||
|
bool topology_extensions;
|
||||||
#elif ARCH_ARM
|
#elif ARCH_ARM
|
||||||
// Main ID register
|
// Main ID register
|
||||||
uint32_t midr;
|
uint32_t midr;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "../arm/midr.h"
|
#include "../arm/midr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char* VERSION = "0.96";
|
static const char* VERSION = "0.97";
|
||||||
|
|
||||||
void print_help(char *argv[]) {
|
void print_help(char *argv[]) {
|
||||||
const char **t = args_str;
|
const char **t = args_str;
|
||||||
@@ -33,6 +33,9 @@ void print_help(char *argv[]) {
|
|||||||
printf(" -%c, --%s %*s Prints main ID register values for all cores (debug purposes)\n", c[ARG_DEBUG], t[ARG_DEBUG], (int) (max_len-strlen(t[ARG_DEBUG])), "");
|
printf(" -%c, --%s %*s Prints main ID register values for all cores (debug purposes)\n", c[ARG_DEBUG], t[ARG_DEBUG], (int) (max_len-strlen(t[ARG_DEBUG])), "");
|
||||||
#endif
|
#endif
|
||||||
printf(" -%c, --%s %*s Prints extra information (if available) about how cpufetch tried fetching information\n", c[ARG_VERBOSE], t[ARG_VERBOSE], (int) (max_len-strlen(t[ARG_VERBOSE])), "");
|
printf(" -%c, --%s %*s Prints extra information (if available) about how cpufetch tried fetching information\n", c[ARG_VERBOSE], t[ARG_VERBOSE], (int) (max_len-strlen(t[ARG_VERBOSE])), "");
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
printf(" -%c, --%s %*s Prints raw cpuid data\n", c[ARG_RAW], t[ARG_RAW], (int) (max_len-strlen(t[ARG_RAW])), "");
|
||||||
|
#endif
|
||||||
printf(" -%c, --%s %*s Prints this help and exit\n", c[ARG_HELP], t[ARG_HELP], (int) (max_len-strlen(t[ARG_HELP])), "");
|
printf(" -%c, --%s %*s Prints this help and exit\n", c[ARG_HELP], t[ARG_HELP], (int) (max_len-strlen(t[ARG_HELP])), "");
|
||||||
printf(" -%c, --%s %*s Prints cpufetch version and exit\n", c[ARG_VERSION], t[ARG_VERSION], (int) (max_len-strlen(t[ARG_VERSION])), "");
|
printf(" -%c, --%s %*s Prints cpufetch version and exit\n", c[ARG_VERSION], t[ARG_VERSION], (int) (max_len-strlen(t[ARG_VERSION])), "");
|
||||||
|
|
||||||
@@ -95,6 +98,17 @@ int main(int argc, char* argv[]) {
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(show_raw()) {
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
print_version();
|
||||||
|
print_raw(cpu);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
#else
|
||||||
|
printErr("raw option is valid only in x86_64");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if(print_cpufetch(cpu, get_style(), get_colors()))
|
if(print_cpufetch(cpu, get_style(), get_colors()))
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -17,4 +17,8 @@ struct apic {
|
|||||||
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo);
|
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo);
|
||||||
uint32_t is_smt_enabled_amd(struct topology* topo);
|
uint32_t is_smt_enabled_amd(struct topology* topo);
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
bool bind_to_cpu(int cpu_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
132
src/x86/cpuid.c
132
src/x86/cpuid.c
@@ -310,6 +310,13 @@ struct cpuInfo* get_cpu_info() {
|
|||||||
printWarn("Can't read cpu name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
|
printWarn("Can't read cpu name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpu->topology_extensions = false;
|
||||||
|
if(cpu->cpu_vendor == CPU_VENDOR_AMD && cpu->maxExtendedLevels >= 0x80000001) {
|
||||||
|
eax = 0x80000001;
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
cpu->topology_extensions = (ecx >> 22) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
cpu->arch = get_cpu_uarch(cpu);
|
cpu->arch = get_cpu_uarch(cpu);
|
||||||
cpu->freq = get_frequency_info(cpu);
|
cpu->freq = get_frequency_info(cpu);
|
||||||
cpu->cach = get_cache_info(cpu);
|
cpu->cach = get_cache_info(cpu);
|
||||||
@@ -322,7 +329,7 @@ struct cpuInfo* get_cpu_info() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
||||||
if(cpu->maxExtendedLevels >= 0x8000001D) {
|
if(cpu->maxExtendedLevels >= 0x8000001D && cpu->topology_extensions) {
|
||||||
uint32_t i, eax, ebx, ecx, edx, num_sharing_cache, cache_type, cache_level;
|
uint32_t i, eax, ebx, ecx, edx, num_sharing_cache, cache_type, cache_level;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -379,7 +386,7 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
|||||||
} while (cache_type > 0);
|
} while (cache_type > 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X). Guessing cache sizes", 0x8000001D, cpu->maxExtendedLevels);
|
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s). Guessing cache topology", 0x8000001D, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
|
||||||
topo->cach->L1i->num_caches = topo->physical_cores;
|
topo->cach->L1i->num_caches = topo->physical_cores;
|
||||||
topo->cach->L1d->num_caches = topo->physical_cores;
|
topo->cach->L1d->num_caches = topo->physical_cores;
|
||||||
|
|
||||||
@@ -440,13 +447,13 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) {
|
|||||||
cpuid(&eax, &ebx, &ecx, &edx);
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
topo->logical_cores = (ecx & 0xFF) + 1;
|
topo->logical_cores = (ecx & 0xFF) + 1;
|
||||||
|
|
||||||
if (cpu->maxExtendedLevels >= 0x8000001E) {
|
if (cpu->maxExtendedLevels >= 0x8000001E && cpu->topology_extensions) {
|
||||||
eax = 0x8000001E;
|
eax = 0x8000001E;
|
||||||
cpuid(&eax, &ebx, &ecx, &edx);
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
topo->smt_supported = ((ebx >> 8) & 0x03) + 1;
|
topo->smt_supported = ((ebx >> 8) & 0x03) + 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x8000001E, cpu->maxExtendedLevels);
|
printWarn("Can't read topology information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", 0x8000001E, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
|
||||||
topo->smt_supported = 1;
|
topo->smt_supported = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -610,8 +617,8 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
level = 0x8000001D;
|
level = 0x8000001D;
|
||||||
if(cpu->maxExtendedLevels < level) {
|
if(cpu->maxExtendedLevels < level || !cpu->topology_extensions) {
|
||||||
printWarn("Can't read cache information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", level, cpu->maxExtendedLevels);
|
printWarn("Can't read cache information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X and topology_extensions=%s)", level, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
|
||||||
level = 0x80000006;
|
level = 0x80000006;
|
||||||
if(cpu->maxExtendedLevels < level) {
|
if(cpu->maxExtendedLevels < level) {
|
||||||
printWarn("Can't read cache information from cpuid using old method (needed extended level is 0x%.8X, max is 0x%.8X)", level, cpu->maxExtendedLevels);
|
printWarn("Can't read cache information from cpuid using old method (needed extended level is 0x%.8X, max is 0x%.8X)", level, cpu->maxExtendedLevels);
|
||||||
@@ -625,29 +632,6 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity checks. If we read values greater than this, they can't be valid ones
|
|
||||||
// The values were chosen by me
|
|
||||||
if(cach->L1i->size > 64 * 1024) {
|
|
||||||
printBug("Invalid L1i size: %dKB", cach->L1i->size/1024);
|
|
||||||
}
|
|
||||||
if(cach->L1d->size > 64 * 1024) {
|
|
||||||
printBug("Invalid L1d size: %dKB", cach->L1d->size/1024);
|
|
||||||
}
|
|
||||||
if(cach->L2->exists) {
|
|
||||||
if(cach->L3->exists && cach->L2->size > 2 * 1048576) {
|
|
||||||
printBug("Invalid L2 size: %dMB", cach->L2->size/(1048576));
|
|
||||||
}
|
|
||||||
else if(cach->L2->size > 100 * 1048576) {
|
|
||||||
printBug("Invalid L2 size: %dMB", cach->L2->size/(1048576));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(cach->L3->exists && cach->L3->size > 100 * 1048576) {
|
|
||||||
printBug("Invalid L3 size: %dMB", cach->L3->size/(1048576));
|
|
||||||
}
|
|
||||||
if(!cach->L2->exists) {
|
|
||||||
printBug("Could not find L2 cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
return cach;
|
return cach;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,14 +874,102 @@ void print_debug(struct cpuInfo* cpu) {
|
|||||||
cpuid(&eax, &ebx, &ecx, &edx);
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
printf("%s\n", cpu->cpu_name);
|
printf("%s\n", cpu->cpu_name);
|
||||||
if(cpu->hv->present) printf("- Hypervisor: %s\n", cpu->hv->hv_name);
|
if(cpu->hv->present) {
|
||||||
|
printf("- Hypervisor: %s\n", cpu->hv->hv_name);
|
||||||
|
}
|
||||||
printf("- Max standard level: 0x%.8X\n", cpu->maxLevels);
|
printf("- Max standard level: 0x%.8X\n", cpu->maxLevels);
|
||||||
printf("- Max extended level: 0x%.8X\n", cpu->maxExtendedLevels);
|
printf("- Max extended level: 0x%.8X\n", cpu->maxExtendedLevels);
|
||||||
|
if(cpu->cpu_vendor == CPU_VENDOR_AMD) {
|
||||||
|
printf("- AMD topology extensions: %d\n", cpu->topology_extensions);
|
||||||
|
}
|
||||||
printf("- CPUID dump: 0x%.8X\n", eax);
|
printf("- CPUID dump: 0x%.8X\n", eax);
|
||||||
|
|
||||||
free_cpuinfo_struct(cpu);
|
free_cpuinfo_struct(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Query HV and Xeon Phi levels
|
||||||
|
void print_raw(struct cpuInfo* cpu) {
|
||||||
|
uint32_t eax;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t edx;
|
||||||
|
printf("%s\n\n", cpu->cpu_name);
|
||||||
|
printf(" CPUID leaf sub EAX EBX ECX EDX \n");
|
||||||
|
printf("--------------------------------------------------------------\n");
|
||||||
|
|
||||||
|
for(int c=0; c < cpu->topo->total_cores; c++) {
|
||||||
|
#ifndef __APPLE__
|
||||||
|
if(!bind_to_cpu(c)) {
|
||||||
|
printErr("Failed binding to CPU %d", c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("CPU %d:\n", c);
|
||||||
|
|
||||||
|
for(uint32_t reg=0x00000000; reg <= cpu->maxLevels; reg++) {
|
||||||
|
if(reg == 0x00000004) {
|
||||||
|
for(uint32_t reg2=0x00000000; reg2 < cpu->cach->max_cache_level; reg2++) {
|
||||||
|
eax = reg;
|
||||||
|
ebx = 0;
|
||||||
|
ecx = reg2;
|
||||||
|
edx = 0;
|
||||||
|
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(reg == 0x0000000B) {
|
||||||
|
for(uint32_t reg2=0x00000000; reg2 < cpu->topo->smt_supported; reg2++) {
|
||||||
|
eax = reg;
|
||||||
|
ebx = 0;
|
||||||
|
ecx = reg2;
|
||||||
|
edx = 0;
|
||||||
|
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eax = reg;
|
||||||
|
ebx = 0;
|
||||||
|
ecx = 0;
|
||||||
|
edx = 0;
|
||||||
|
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, 0x00, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(uint32_t reg=0x80000000; reg <= cpu->maxExtendedLevels; reg++) {
|
||||||
|
if(reg == 0x8000001D) {
|
||||||
|
for(uint32_t reg2=0x00000000; reg2 < cpu->cach->max_cache_level; reg2++) {
|
||||||
|
eax = reg;
|
||||||
|
ebx = 0;
|
||||||
|
ecx = reg2;
|
||||||
|
edx = 0;
|
||||||
|
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, reg2, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eax = reg;
|
||||||
|
ebx = 0;
|
||||||
|
ecx = 0;
|
||||||
|
edx = 0;
|
||||||
|
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
printf(" 0x%.8X 0x%.2X: 0x%.8X 0x%.8X 0x%.8X 0x%.8X\n", reg, 0x00, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void free_topo_struct(struct topology* topo) {
|
void free_topo_struct(struct topology* topo) {
|
||||||
free(topo->apic->cache_select_mask);
|
free(topo->apic->cache_select_mask);
|
||||||
free(topo->apic->cache_id_apic);
|
free(topo->apic->cache_id_apic);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc
|
|||||||
char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq);
|
char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq);
|
||||||
|
|
||||||
void print_debug(struct cpuInfo* cpu);
|
void print_debug(struct cpuInfo* cpu);
|
||||||
|
void print_raw(struct cpuInfo* cpu);
|
||||||
|
|
||||||
void free_topo_struct(struct topology* topo);
|
void free_topo_struct(struct topology* topo);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user