From a31142a75e8e5d90301c0c6415c207362fc18205 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 5 Apr 2024 18:51:03 +0200 Subject: [PATCH 1/2] Add support for Transmeta(TM) Crusoe(TM) CPU --- src/common/ascii.h | 33 +++++++++++++++++++++++++++++++++ src/common/cpu.c | 6 +++--- src/common/cpu.h | 9 +++++---- src/common/printer.c | 3 +++ src/x86/cpuid.c | 38 ++++++++++++++++++++++++++++++++++++-- src/x86/uarch.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 9 deletions(-) diff --git a/src/common/ascii.h b/src/common/ascii.h index bbae1a98..16826ed1 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -492,6 +492,38 @@ struct ascii_logo { $C1 ################ \ $C1 ####### " +#define ASCII_TRANSMETA \ +"$C1 \ +$C1 \ +$C1 ########### \ +$C1 ################### \ +$C1 ######## ############ \ +$C1 ##### ######## \ +$C1 #### ####### \ +$C1 #### ########### ###### \ +$C1 #### ############## ##### \ +$C1 #### ###### ####### #### \ +$C1 ### ##### ##### #### \ +$C1 #### ###### #### #### \ +$C1 #### ###### ##### #### \ +$C1 #### ###### #### #### \ +$C1 ##### ####### ##### \ +$C1 ##### ################## \ +$C1 ###### ############# \ +$C1 ###### \ +$C1 ####### \ +$C1 ######## \ +$C1 ######## \ +$C1 ######### \ +$C1 ##################### \ +$C1 ################# \ +$C1 " + + + + + + typedef struct ascii_logo asciiL; // +-----------------------------------------------------------------------------------------------------------------+ @@ -516,6 +548,7 @@ asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_Y asciiL logo_sifive = { ASCII_SIFIVE, 48, 19, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_BLUE} }; asciiL logo_starfive = { ASCII_STARFIVE, 33, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; asciiL logo_sipeed = { ASCII_SIPEED, 41, 16, true, {C_BG_RED, C_BG_WHITE}, {C_FG_RED, C_FG_WHITE} }; +asciiL logo_transmeta = { ASCII_TRANSMETA, 50, 24, true, {C_BG_GREEN}, {C_FG_WHITE, C_FG_B_GREEN} }; // Long variants | ----------------------------------------------------------------------------------------------------------------| asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} }; diff --git a/src/common/cpu.c b/src/common/cpu.c index a7d53ca2..52dd5c19 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -175,11 +175,11 @@ char* get_str_peak_performance(int64_t flops) { str = ecalloc(max_size, sizeof(char)); if(flopsd >= (double)1000000000000.0) - snprintf(str, max_size, "%.2f TFLOP/s", flopsd/1000000000000); + snprintf(str, max_size, "%.2f TFLOP/s", (float)flopsd/1000000000000); else if(flopsd >= 1000000000.0) - snprintf(str, max_size, "%.2f GFLOP/s", flopsd/1000000000); + snprintf(str, max_size, "%.2f GFLOP/s", (float)flopsd/1000000000); else - snprintf(str, max_size, "%.2f MFLOP/s", flopsd/1000000); + snprintf(str, max_size, "%.2f MFLOP/s", (float)flopsd/1000000); return str; } diff --git a/src/common/cpu.h b/src/common/cpu.h index 4965747a..3834a783 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -8,6 +8,7 @@ enum { // ARCH_X86 CPU_VENDOR_INTEL, CPU_VENDOR_AMD, + CPU_VENDOR_TRANSMETA, // ARCH_ARM CPU_VENDOR_ARM, CPU_VENDOR_APPLE, @@ -82,7 +83,7 @@ struct cache { }; struct topology { - int32_t total_cores; + int32_t total_cores; struct cache* cach; #if defined(ARCH_X86) || defined(ARCH_PPC) int32_t physical_cores; @@ -98,7 +99,7 @@ struct topology { }; struct features { - bool AES; // Must be the first field of features struct! + bool AES; // Must be the first field of features struct! #ifdef ARCH_X86 bool AVX; bool AVX2; @@ -116,11 +117,11 @@ struct features { #elif ARCH_PPC bool altivec; #elif ARCH_ARM - bool NEON; + bool NEON; bool SHA1; bool SHA2; bool CRC32; -#endif +#endif }; struct extensions { diff --git a/src/common/printer.c b/src/common/printer.c index 81811084..c43d162e 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -357,6 +357,9 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter else if(art->vendor == CPU_VENDOR_AMD) { art->art = choose_ascii_art_aux(&logo_amd_l, &logo_amd, term, lf); } + else if (art->vendor == CPU_VENDOR_TRANSMETA) { + art->art = &logo_transmeta; + } else { art->art = &logo_unknown; } diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 26367070..021b4daf 100644 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -20,8 +20,9 @@ #include "uarch.h" #include "freq/freq.h" -#define CPU_VENDOR_INTEL_STRING "GenuineIntel" -#define CPU_VENDOR_AMD_STRING "AuthenticAMD" +#define CPU_VENDOR_INTEL_STRING "GenuineIntel" +#define CPU_VENDOR_AMD_STRING "AuthenticAMD" +#define CPU_VENDOR_TRANSMETA_STRING "GenuineTMx86" static const char *hv_vendors_string[] = { [HV_VENDOR_KVM] = "KVMKVMKVM", @@ -468,6 +469,8 @@ struct cpuInfo* get_cpu_info(void) { cpu->cpu_vendor = CPU_VENDOR_INTEL; else if (strcmp(CPU_VENDOR_AMD_STRING,name) == 0) cpu->cpu_vendor = CPU_VENDOR_AMD; + else if (strcmp(CPU_VENDOR_TRANSMETA_STRING,name) == 0) + cpu->cpu_vendor = CPU_VENDOR_TRANSMETA; else { cpu->cpu_vendor = CPU_VENDOR_INVALID; printErr("Unknown CPU vendor: %s", name); @@ -692,6 +695,7 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int switch(cpu->cpu_vendor) { case CPU_VENDOR_INTEL: + case CPU_VENDOR_TRANSMETA: if (cpu->maxLevels >= 0x00000004) { bool toporet = get_topology_from_apic(cpu, topo); if(!toporet) { @@ -767,6 +771,32 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int return topo; } +struct cache* get_cache_info_transmeta(struct cache* cach) { + uint32_t eax = 0x80000005; + uint32_t ebx = 0; + uint32_t ecx = 0; + uint32_t edx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + + cach->L1d->size = (ecx >> 24) * 1024; + cach->L1i->size = (edx >> 24) * 1024; + + eax = 0x80000006; + cpuid(&eax, &ebx, &ecx, &edx); + + cach->L2->size = (ecx >> 16) * 1024; + cach->L3->size = (edx >> 18) * 512 * 1024; + + cach->L1i->exists = cach->L1i->size > 0; + cach->L1d->exists = cach->L1d->size > 0; + cach->L2->exists = cach->L2->size > 0; + cach->L3->exists = 0; + + cach->max_cache_level = 3; + + return cach; +} + struct cache* get_cache_info_amd_fallback(struct cache* cach) { uint32_t eax = 0x80000005; uint32_t ebx = 0; @@ -890,6 +920,10 @@ struct cache* get_cache_info(struct cpuInfo* cpu) { cach = get_cache_info_general(cach, level); } } + else if (cpu->cpu_vendor == CPU_VENDOR_TRANSMETA) { + level = 0x00000001; + cach = get_cache_info_transmeta(cach); + } else { level = 0x8000001D; if(cpu->maxExtendedLevels < level || !cpu->topology_extensions) { diff --git a/src/x86/uarch.c b/src/x86/uarch.c index 7c22ef1c..288ac9cc 100644 --- a/src/x86/uarch.c +++ b/src/x86/uarch.c @@ -94,6 +94,8 @@ enum { UARCH_TIGER_LAKE, UARCH_ALDER_LAKE, UARCH_RAPTOR_LAKE, + // TRANSMETA // + UARCH_CRUSOE, // AMD // UARCH_AM486, UARCH_AM5X86, @@ -267,6 +269,21 @@ struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, u return arch; } +struct uarch* get_uarch_from_cpuid_transmeta(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) { + struct uarch* arch = emalloc(sizeof(struct uarch)); + // EF: Extended Family // + // F: Family // + // EM: Extended Model // + // M: Model // + // S: Stepping // + // ------------------------------------------------------------------------------- // + // EF F EM M S // + UARCH_START + CHECK_UARCH(arch, 0, 5, 0, 4, 3, "CRUSOE", UARCH_CRUSOE, 130) + UARCH_END + return arch; +} + // Inspired in Todd Allen's decode_uarch_amd struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) { struct uarch* arch = emalloc(sizeof(struct uarch)); @@ -435,6 +452,9 @@ struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t } return get_uarch_from_cpuid_intel(ef, f, em, m, s); } + else if (cpu->cpu_vendor == CPU_VENDOR_TRANSMETA) { + return get_uarch_from_cpuid_transmeta(ef, f, em, m, s); + } else return get_uarch_from_cpuid_amd(ef, f, em, m, s); } @@ -453,6 +473,8 @@ char* infer_cpu_name_from_uarch(struct uarch* arch) { if (arch->uarch == UARCH_P5) str = "Intel Pentium"; + else if (arch->uarch == UARCH_CRUSOE) + str = "Transmeta Crusoe"; else if (arch->uarch == UARCH_P5_MMX) str = "Intel Pentium MMX"; else if (arch->uarch == UARCH_P6_PENTIUM_II) @@ -533,6 +555,13 @@ bool choose_new_intel_logo_uarch(struct cpuInfo* cpu) { } } +bool choose_transmeta_crusoe_logo_uarch(struct cpuInfo* cpu) { + if (cpu->arch->uarch == UARCH_CRUSOE) + return true; + else + return false; +} + char* get_str_uarch(struct cpuInfo* cpu) { return cpu->arch->uarch_str; } From 477b565408c4054ead0d055f294ca7c1c72a71b8 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 5 Jul 2024 08:26:18 +0200 Subject: [PATCH 2/2] Addressed some style/dead code review comments --- src/common/ascii.h | 5 ----- src/common/cpu.c | 6 +++--- src/x86/cpuid.c | 6 +++--- src/x86/uarch.c | 7 ------- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/common/ascii.h b/src/common/ascii.h index 16826ed1..cf95bcfe 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -519,11 +519,6 @@ struct ascii_logo { $C1 ################# \ $C1 " - - - - - typedef struct ascii_logo asciiL; // +-----------------------------------------------------------------------------------------------------------------+ diff --git a/src/common/cpu.c b/src/common/cpu.c index 52dd5c19..a7d53ca2 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -175,11 +175,11 @@ char* get_str_peak_performance(int64_t flops) { str = ecalloc(max_size, sizeof(char)); if(flopsd >= (double)1000000000000.0) - snprintf(str, max_size, "%.2f TFLOP/s", (float)flopsd/1000000000000); + snprintf(str, max_size, "%.2f TFLOP/s", flopsd/1000000000000); else if(flopsd >= 1000000000.0) - snprintf(str, max_size, "%.2f GFLOP/s", (float)flopsd/1000000000); + snprintf(str, max_size, "%.2f GFLOP/s", flopsd/1000000000); else - snprintf(str, max_size, "%.2f MFLOP/s", (float)flopsd/1000000); + snprintf(str, max_size, "%.2f MFLOP/s", flopsd/1000000); return str; } diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 021b4daf..290f9e08 100644 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -20,9 +20,9 @@ #include "uarch.h" #include "freq/freq.h" -#define CPU_VENDOR_INTEL_STRING "GenuineIntel" -#define CPU_VENDOR_AMD_STRING "AuthenticAMD" -#define CPU_VENDOR_TRANSMETA_STRING "GenuineTMx86" +#define CPU_VENDOR_INTEL_STRING "GenuineIntel" +#define CPU_VENDOR_AMD_STRING "AuthenticAMD" +#define CPU_VENDOR_TRANSMETA_STRING "GenuineTMx86" static const char *hv_vendors_string[] = { [HV_VENDOR_KVM] = "KVMKVMKVM", diff --git a/src/x86/uarch.c b/src/x86/uarch.c index 288ac9cc..e262abe3 100644 --- a/src/x86/uarch.c +++ b/src/x86/uarch.c @@ -555,13 +555,6 @@ bool choose_new_intel_logo_uarch(struct cpuInfo* cpu) { } } -bool choose_transmeta_crusoe_logo_uarch(struct cpuInfo* cpu) { - if (cpu->arch->uarch == UARCH_CRUSOE) - return true; - else - return false; -} - char* get_str_uarch(struct cpuInfo* cpu) { return cpu->arch->uarch_str; }