Skip to content

Commit

Permalink
[v0.97] Manually merge bugfix branch with latest fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Noob committed Apr 9, 2021
2 parents 32b035f + e8d2898 commit ecca042
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 33 deletions.
16 changes: 14 additions & 2 deletions src/common/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static const char *SYTLES_STR_LIST[] = {
struct args_struct {
bool debug_flag;
bool help_flag;
bool raw_flag;
bool verbose_flag;
bool version_flag;
STYLE style;
Expand All @@ -30,6 +31,7 @@ const char args_chr[] = {
/* [ARG_CHAR_STYLE] = */ 's',
/* [ARG_CHAR_COLOR] = */ 'c',
/* [ARG_CHAR_HELP] = */ 'h',
/* [ARG_CHAR_RAW] = */ 'r',
/* [ARG_CHAR_DEBUG] = */ 'd',
/* [ARG_CHAR_VERBOSE] = */ 'v',
/* [ARG_CHAR_VERSION] = */ 'V',
Expand All @@ -39,6 +41,7 @@ const char *args_str[] = {
/* [ARG_CHAR_STYLE] = */ "style",
/* [ARG_CHAR_COLOR] = */ "color",
/* [ARG_CHAR_HELP] = */ "help",
/* [ARG_CHAR_RAW] = */ "raw",
/* [ARG_CHAR_DEBUG] = */ "debug",
/* [ARG_CHAR_VERBOSE] = */ "verbose",
/* [ARG_CHAR_VERSION] = */ "version",
Expand Down Expand Up @@ -66,6 +69,10 @@ bool show_debug() {
return args.debug_flag;
}

bool show_raw() {
return args.raw_flag;
}

bool verbose_enabled() {
return args.verbose_flag;
}
Expand Down Expand Up @@ -182,8 +189,8 @@ char* build_short_options() {
char* str = (char *) malloc(sizeof(char) * (len*2 + 1));
memset(str, 0, sizeof(char) * (len*2 + 1));

sprintf(str, "%c:%c:%c%c%c%c",
c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP],
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]);

return str;
Expand All @@ -196,6 +203,7 @@ bool parse_args(int argc, char* argv[]) {

bool color_flag = false;
args.debug_flag = false;
args.raw_flag = false;
args.verbose_flag = false;
args.help_flag = false;
args.style = STYLE_EMPTY;
Expand All @@ -205,6 +213,7 @@ bool parse_args(int argc, char* argv[]) {
{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_HELP], no_argument, 0, args_chr[ARG_HELP] },
{args_str[ARG_RAW], no_argument, 0, args_chr[ARG_RAW] },
{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_VERSION], no_argument, 0, args_chr[ARG_VERSION] },
Expand Down Expand Up @@ -241,6 +250,9 @@ bool parse_args(int argc, char* argv[]) {
else if(opt == args_chr[ARG_HELP]) {
args.help_flag = true;
}
else if(opt == args_chr[ARG_RAW]) {
args.raw_flag = true;
}
else if(opt == args_chr[ARG_VERBOSE]) {
args.verbose_flag = true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/common/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum {
ARG_STYLE,
ARG_COLOR,
ARG_HELP,
ARG_RAW,
ARG_DEBUG,
ARG_VERBOSE,
ARG_VERSION
Expand All @@ -43,6 +44,7 @@ extern const char *args_str[];
int max_arg_str_length();
bool parse_args(int argc, char* argv[]);
bool show_help();
bool show_raw();
bool show_debug();
bool show_version();
bool verbose_enabled();
Expand Down
2 changes: 2 additions & 0 deletions src/common/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ struct cpuInfo {
uint32_t maxLevels;
// Max cpuids extended levels
uint32_t maxExtendedLevels;
// Topology Extensions (AMD only)
bool topology_extensions;
#elif ARCH_ARM
// Main ID register
uint32_t midr;
Expand Down
11 changes: 11 additions & 0 deletions src/common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ int main(int argc, char* argv[]) {
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()))
return EXIT_SUCCESS;
else
Expand Down
4 changes: 4 additions & 0 deletions src/x86/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ struct apic {
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo);
uint32_t is_smt_enabled_amd(struct topology* topo);

#ifndef __APPLE__
bool bind_to_cpu(int cpu_id);
#endif

#endif
133 changes: 102 additions & 31 deletions src/x86/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,26 @@ 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);
}

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->freq = get_frequency_info(cpu);
cpu->cach = get_cache_info(cpu);
cpu->topo = get_topology_info(cpu, cpu->cach);

if(cpu->cach == NULL || cpu->topo == NULL) {
return NULL;
}
return cpu;
}

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;

i = 0;
Expand Down Expand Up @@ -379,7 +386,7 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
} while (cache_type > 0);
}
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->L1d->num_caches = topo->physical_cores;

Expand Down Expand Up @@ -440,13 +447,13 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) {
cpuid(&eax, &ebx, &ecx, &edx);
topo->logical_cores = (ecx & 0xFF) + 1;

if (cpu->maxExtendedLevels >= 0x8000001E) {
if (cpu->maxExtendedLevels >= 0x8000001E && cpu->topology_extensions) {
eax = 0x8000001E;
cpuid(&eax, &ebx, &ecx, &edx);
topo->smt_supported = ((ebx >> 8) & 0x03) + 1;
}
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;
}
}
Expand Down Expand Up @@ -610,8 +617,8 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
}
else {
level = 0x8000001D;
if(cpu->maxExtendedLevels < level) {
printWarn("Can't read cache information from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", level, cpu->maxExtendedLevels);
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 and topology_extensions=%s)", level, cpu->maxExtendedLevels, cpu->topology_extensions ? "true" : "false");
level = 0x80000006;
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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -890,14 +874,101 @@ void print_debug(struct cpuInfo* cpu) {
cpuid(&eax, &ebx, &ecx, &edx);

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 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);

free_cpuinfo_struct(cpu);
}

// TODO: Fix on macOS
// 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++) {
if(!bind_to_cpu(c)) {
printErr("Failed binding to CPU %d", c);
return;
}

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) {
free(topo->apic->cache_select_mask);
free(topo->apic->cache_id_apic);
Expand Down
1 change: 1 addition & 0 deletions src/x86/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

void print_debug(struct cpuInfo* cpu);
void print_raw(struct cpuInfo* cpu);

void free_topo_struct(struct topology* topo);

Expand Down

0 comments on commit ecca042

Please sign in to comment.