From 1f450b23a1a9f7f12b5d023ce0547d170abd79f3 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Fri, 31 Mar 2023 17:57:01 +0200 Subject: [PATCH 01/12] [v1.03][RISCV] Add support for compiling to RISC-V --- Makefile | 5 +++++ src/common/cpu.c | 2 ++ src/common/global.c | 3 +++ src/common/printer.c | 13 ++++++++++++- src/common/printer.h | 2 ++ src/riscv/riscv.c | 12 ++++++++++++ src/riscv/riscv.h | 9 +++++++++ src/riscv/uarch.c | 11 +++++++++++ src/riscv/uarch.h | 11 +++++++++++ 9 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/riscv/riscv.c create mode 100644 src/riscv/riscv.h create mode 100644 src/riscv/uarch.c create mode 100644 src/riscv/uarch.h diff --git a/Makefile b/Makefile index 6a9d913..0d7b6e7 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,11 @@ ifneq ($(OS),Windows_NT) SOURCE += $(SRC_DIR)sysctl.c HEADERS += $(SRC_DIR)sysctl.h endif + else ifeq ($(arch), $(filter $(arch), riscv64 riscv32)) + SRC_DIR=src/riscv/ + SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c + HEADERS += $(COMMON_SRC) $(SRC_DIR)riscv.h $(SRC_DIR)uarch.h + CFLAGS += -DARCH_RISCV -Wno-unused-parameter -std=c99 -fstack-protector-all else # Error lines should not be tabulated because Makefile complains about it $(warning Unsupported arch detected: $(arch). See https://github.com/Dr-Noob/cpufetch#1-support) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2faa4bb..1987420 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -14,6 +14,8 @@ #include "../ppc/uarch.h" #elif ARCH_ARM #include "../arm/uarch.h" +#elif ARCH_RISCV + #include "../riscv/uarch.h" #endif #define STRING_YES "Yes" diff --git a/src/common/global.c b/src/common/global.c index 2ed88ba..e62e695 100644 --- a/src/common/global.c +++ b/src/common/global.c @@ -29,6 +29,9 @@ #elif ARCH_ARM static const char* ARCH_STR = "ARM build"; #include "../arm/midr.h" +#elif ARCH_RISCV + static const char* ARCH_STR = "RISC-V build"; + #include "../riscv/riscv.h" #endif #ifdef __linux__ diff --git a/src/common/printer.c b/src/common/printer.c index cb0b4a8..dd73a8c 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -16,10 +16,12 @@ #elif ARCH_PPC #include "../ppc/uarch.h" #include "../ppc/ppc.h" -#else +#elif ARCH_ARM #include "../arm/uarch.h" #include "../arm/midr.h" #include "../arm/soc.h" +#elif ARCH_RISCV + #include "../riscv/riscv.h" #endif #ifdef _WIN32 @@ -911,6 +913,13 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct color** cs, struct } #endif +#ifdef ARCH_RISCV +bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struct terminal* term) { + printf("Unimplemented\n"); + return true; +} +#endif + struct terminal* get_terminal_size(void) { struct terminal* term = emalloc(sizeof(struct terminal)); @@ -948,5 +957,7 @@ bool print_cpufetch(struct cpuInfo* cpu, STYLE s, struct color** cs, bool show_f return print_cpufetch_ppc(cpu, s, cs, term, show_full_cpu_name); #elif ARCH_ARM return print_cpufetch_arm(cpu, s, cs, term); +#elif ARCH_RISCV + return print_cpufetch_riscv(cpu, s, cs, term); #endif } diff --git a/src/common/printer.h b/src/common/printer.h index 6863d4b..21dd906 100644 --- a/src/common/printer.h +++ b/src/common/printer.h @@ -11,6 +11,8 @@ typedef int STYLE; #include "../ppc/ppc.h" #elif ARCH_ARM #include "../arm/midr.h" +#elif ARCH_RISCV + #include "../riscv/riscv.h" #endif // +-----------------------------------+-----------------------+ diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c new file mode 100644 index 0000000..d4859a9 --- /dev/null +++ b/src/riscv/riscv.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +struct cpuInfo* get_cpu_info(void) { + return NULL; +} + +void print_debug(struct cpuInfo* cpu) { + printf("Unimplemented!\n"); +} diff --git a/src/riscv/riscv.h b/src/riscv/riscv.h new file mode 100644 index 0000000..25dd7a5 --- /dev/null +++ b/src/riscv/riscv.h @@ -0,0 +1,9 @@ +#ifndef __RISCV__ +#define __RISCV__ + +#include "../common/cpu.h" + +struct cpuInfo* get_cpu_info(void); +void print_debug(struct cpuInfo* cpu); + +#endif diff --git a/src/riscv/uarch.c b/src/riscv/uarch.c new file mode 100644 index 0000000..a7f579b --- /dev/null +++ b/src/riscv/uarch.c @@ -0,0 +1,11 @@ +#include + +struct uarch { + //MICROARCH uarch; + char* uarch_str; + int32_t process; // measured in nanometers +}; + +void free_uarch_struct(struct uarch* arch) { + +} diff --git a/src/riscv/uarch.h b/src/riscv/uarch.h new file mode 100644 index 0000000..7b37e26 --- /dev/null +++ b/src/riscv/uarch.h @@ -0,0 +1,11 @@ +#ifndef __UARCH__ +#define __UARCH__ + +#include +#include "riscv.h" + +struct uarch; + +void free_uarch_struct(struct uarch* arch); + +#endif From 9a69a7f58d647cb52a39df86dd200fb6d1c27430 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sat, 1 Apr 2023 16:46:54 +0200 Subject: [PATCH 02/12] [v1.03][RISCV] Implementing basic skeleton for RISC-V backend --- Makefile | 4 ++-- src/common/ascii.h | 21 ++++++++++++++++++ src/common/cpu.h | 4 +++- src/common/printer.c | 51 ++++++++++++++++++++++++++++++++++++++++++-- src/riscv/riscv.c | 29 ++++++++++++++++++++++++- src/riscv/riscv.h | 1 + src/riscv/soc.c | 9 ++++++++ src/riscv/soc.h | 20 +++++++++++++++++ src/riscv/uarch.c | 7 ++++++ src/riscv/uarch.h | 1 + 10 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 src/riscv/soc.c create mode 100644 src/riscv/soc.h diff --git a/Makefile b/Makefile index 0d7b6e7..dbd9c3c 100644 --- a/Makefile +++ b/Makefile @@ -43,8 +43,8 @@ ifneq ($(OS),Windows_NT) endif else ifeq ($(arch), $(filter $(arch), riscv64 riscv32)) SRC_DIR=src/riscv/ - SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c - HEADERS += $(COMMON_SRC) $(SRC_DIR)riscv.h $(SRC_DIR)uarch.h + SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c $(SRC_DIR)soc.c + HEADERS += $(COMMON_SRC) $(SRC_DIR)riscv.h $(SRC_DIR)uarch.h $(SRC_DIR)soc.h CFLAGS += -DARCH_RISCV -Wno-unused-parameter -std=c99 -fstack-protector-all else # Error lines should not be tabulated because Makefile complains about it diff --git a/src/common/ascii.h b/src/common/ascii.h index 1c8e96e..fe7b692 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -246,6 +246,26 @@ $C1##. ###. ####. #### ### .## #### ### ### #.##### \ $C1 ## \ $C1 " +#define ASCII_RISCV \ +"$C1 \ +$C1 ************ \ +$C1 %%%%%%%%% *********** \ +$C1 %%%%%%%%%% ********** \ +$C1 %%%%%%%%% ********* \ +$C1 % ******** \ +$C1 %% .********* % \ +$C1 %%%% ******* %%% \ +$C1 %%%%%%. **** %%%%% \ +$C1 %%%%%%%%. %%%%%%% \ +$C1 \ +$C1 \ +$C1 ########### ## .######### ######### .## ## \ +$C1 ## ## ## ## ## ### ### \ +$C1 ########### ## ##########. ## #### .## ## \ +$C1 ## ### ## ##. ## ### ### \ +$C1 ## ### ## ##########. ########## ### \ +$C1 " + // --------------------- LONG LOGOS ------------------------- // #define ASCII_AMD_L \ "$C1 \ @@ -348,6 +368,7 @@ asciiL logo_ibm = { ASCII_IBM, 42, 9, false, {C_FG_CYAN, C_FG_W asciiL logo_apple = { ASCII_APPLE, 32, 17, false, {C_FG_WHITE}, {C_FG_CYAN, C_FG_B_WHITE} }; asciiL logo_allwinner = { ASCII_ALLWINNER, 47, 16, false, {C_FG_CYAN}, {C_FG_B_BLACK, C_FG_B_CYAN } }; asciiL logo_rockchip = { ASCII_ROCKCHIP, 58, 8, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; +asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; // 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.h b/src/common/cpu.h index ed08fc7..011e1e6 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -20,6 +20,8 @@ enum { CPU_VENDOR_SAMSUNG, CPU_VENDOR_MARVELL, CPU_VENDOR_PHYTIUM, +// ARCH_RISCV + CPU_VENDOR_RISCV, // OTHERS CPU_VENDOR_UNKNOWN, CPU_VENDOR_INVALID @@ -149,7 +151,7 @@ struct cpuInfo { uint32_t midr; #endif -#ifdef ARCH_ARM +#if defined(ARCH_ARM) || defined(ARCH_RISCV) struct system_on_chip* soc; #endif diff --git a/src/common/printer.c b/src/common/printer.c index dd73a8c..da106b0 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -22,6 +22,8 @@ #include "../arm/soc.h" #elif ARCH_RISCV #include "../riscv/riscv.h" + #include "../riscv/uarch.h" + #include "../riscv/soc.h" #endif #ifdef _WIN32 @@ -366,6 +368,8 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter else { art->art = choose_ascii_art_aux(&logo_arm_l, &logo_arm, term, lf); } +#elif ARCH_RISCV + art->art = &logo_riscv; #endif // 2. Choose colors @@ -431,7 +435,7 @@ uint32_t longest_field_length(struct ascii* art, int la) { return max; } -#if defined(ARCH_X86) || defined(ARCH_PPC) +#if defined(ARCH_X86) || defined(ARCH_PPC) || defined(ARCH_RISCV) void print_ascii_generic(struct ascii* art, uint32_t la, int32_t termw, const char** attribute_fields, bool hybrid_architecture) { struct ascii_logo* logo = art->art; int attr_to_print = 0; @@ -915,7 +919,50 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct color** cs, struct #ifdef ARCH_RISCV bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struct terminal* term) { - printf("Unimplemented\n"); + struct ascii* art = set_ascii(get_cpu_vendor(cpu), s); + if(art == NULL) + return false; + + // Step 1. Retrieve attributes + char* uarch = get_str_uarch(cpu); + char* manufacturing_process = get_str_process(cpu->soc); + char* max_frequency = get_str_freq(cpu->freq); + char* n_cores = get_str_topology(cpu, cpu->topo); + + /*char* l1i = get_str_l1i(cpu->cach); + char* l1d = get_str_l1d(cpu->cach); + char* l2 = get_str_l2(cpu->cach); + char* l3 = get_str_l3(cpu->cach);*/ + char* pp = get_str_peak_performance(cpu->peak_performance); + + // Step 2. Set attributes + setAttribute(art,ATTRIBUTE_UARCH,uarch); + setAttribute(art,ATTRIBUTE_TECHNOLOGY,manufacturing_process); + setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); + setAttribute(art,ATTRIBUTE_NCORES, n_cores); + /*setAttribute(art,ATTRIBUTE_L1i,l1i); + setAttribute(art,ATTRIBUTE_L1d,l1d); + setAttribute(art,ATTRIBUTE_L2,l2); + if(l3 != NULL) { + setAttribute(art,ATTRIBUTE_L3,l3); + }*/ + setAttribute(art,ATTRIBUTE_PEAK,pp); + + // Step 3. Print output + const char** attribute_fields = ATTRIBUTE_FIELDS; + uint32_t longest_attribute = longest_attribute_length(art, attribute_fields); + uint32_t longest_field = longest_field_length(art, longest_attribute); + choose_ascii_art(art, cs, term, longest_field); + + if(!ascii_fits_screen(term->w, *art->art, longest_field)) { + // Despite of choosing the smallest logo, the output does not fit + // Choose the shorter field names and recalculate the longest attr + attribute_fields = ATTRIBUTE_FIELDS_SHORT; + longest_attribute = longest_attribute_length(art, attribute_fields); + } + + print_ascii_generic(art, longest_attribute, term->w, attribute_fields, false); + return true; } #endif diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index d4859a9..4a3a203 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -3,8 +3,35 @@ #include #include +#include "../common/global.h" +#include "../common/udev.h" + +struct frequency* get_frequency_info(uint32_t core) { + struct frequency* freq = emalloc(sizeof(struct frequency)); + + freq->base = UNKNOWN_DATA; + freq->max = get_max_freq_from_file(core); + + return freq; +} + struct cpuInfo* get_cpu_info(void) { - return NULL; + struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); + //init_cpu_info(cpu); + int ncores = get_ncores_from_cpuinfo(); + cpu->hv = emalloc(sizeof(struct hypervisor)); + cpu->hv->present = false; + //cpu->soc = get_soc(); + //cpu->peak_performance = get_peak_performance(cpu); + cpu->peak_performance = 0; + cpu->freq = get_frequency_info(0); + cpu->cpu_vendor = CPU_VENDOR_RISCV; + + return cpu; +} + +char* get_str_topology(struct cpuInfo* cpu, struct topology* topo) { + return "Many cores"; } void print_debug(struct cpuInfo* cpu) { diff --git a/src/riscv/riscv.h b/src/riscv/riscv.h index 25dd7a5..367c56e 100644 --- a/src/riscv/riscv.h +++ b/src/riscv/riscv.h @@ -4,6 +4,7 @@ #include "../common/cpu.h" struct cpuInfo* get_cpu_info(void); +char* get_str_topology(struct cpuInfo* cpu, struct topology* topo); void print_debug(struct cpuInfo* cpu); #endif diff --git a/src/riscv/soc.c b/src/riscv/soc.c new file mode 100644 index 0000000..6f6f115 --- /dev/null +++ b/src/riscv/soc.c @@ -0,0 +1,9 @@ +#include "soc.h" + +char* get_str_process(struct system_on_chip* soc) { + return "-1 nm"; +} + +char* get_soc_name(struct system_on_chip* soc) { + return "Unknown"; +} diff --git a/src/riscv/soc.h b/src/riscv/soc.h new file mode 100644 index 0000000..9f55c1b --- /dev/null +++ b/src/riscv/soc.h @@ -0,0 +1,20 @@ +#ifndef __SOC__ +#define __SOC__ + +#include "../common/cpu.h" +#include + +typedef int32_t SOC; + +struct system_on_chip { + SOC soc_model; + VENDOR soc_vendor; + int32_t process; + char* soc_name; + char* raw_name; +}; + +char* get_soc_name(struct system_on_chip* soc); +char* get_str_process(struct system_on_chip* soc); + +#endif diff --git a/src/riscv/uarch.c b/src/riscv/uarch.c index a7f579b..a9aa42e 100644 --- a/src/riscv/uarch.c +++ b/src/riscv/uarch.c @@ -1,11 +1,18 @@ #include +#include "uarch.h" +#include "../common/global.h" + struct uarch { //MICROARCH uarch; char* uarch_str; int32_t process; // measured in nanometers }; +char* get_str_uarch(struct cpuInfo* cpu) { + return "Unknown"; +} + void free_uarch_struct(struct uarch* arch) { } diff --git a/src/riscv/uarch.h b/src/riscv/uarch.h index 7b37e26..02548f9 100644 --- a/src/riscv/uarch.h +++ b/src/riscv/uarch.h @@ -6,6 +6,7 @@ struct uarch; +char* get_str_uarch(struct cpuInfo* cpu); void free_uarch_struct(struct uarch* arch); #endif From 14819c350e9939192fd519b858f97f47164e58fc Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Mon, 3 Apr 2023 12:41:59 +0200 Subject: [PATCH 03/12] [v1.03][RISCV] Add basic SoC detection backend --- Makefile | 4 +- src/common/printer.c | 11 +++-- src/riscv/riscv.c | 33 +++++++++++-- src/riscv/riscv.h | 1 + src/riscv/soc.c | 113 ++++++++++++++++++++++++++++++++++++++++++- src/riscv/soc.h | 7 +++ src/riscv/socs.h | 19 ++++++++ src/riscv/udev.c | 44 +++++++++++++++++ src/riscv/udev.h | 10 ++++ 9 files changed, 229 insertions(+), 13 deletions(-) create mode 100644 src/riscv/socs.h create mode 100644 src/riscv/udev.c create mode 100644 src/riscv/udev.h diff --git a/Makefile b/Makefile index dbd9c3c..66e9adb 100644 --- a/Makefile +++ b/Makefile @@ -43,8 +43,8 @@ ifneq ($(OS),Windows_NT) endif else ifeq ($(arch), $(filter $(arch), riscv64 riscv32)) SRC_DIR=src/riscv/ - SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c $(SRC_DIR)soc.c - HEADERS += $(COMMON_SRC) $(SRC_DIR)riscv.h $(SRC_DIR)uarch.h $(SRC_DIR)soc.h + SOURCE += $(COMMON_SRC) $(SRC_DIR)riscv.c $(SRC_DIR)uarch.c $(SRC_DIR)soc.c $(SRC_DIR)udev.c + HEADERS += $(COMMON_SRC) $(SRC_DIR)riscv.h $(SRC_DIR)uarch.h $(SRC_DIR)soc.h $(SRC_DIR)udev.h $(SRC_DIR)socs.h CFLAGS += -DARCH_RISCV -Wno-unused-parameter -std=c99 -fstack-protector-all else # Error lines should not be tabulated because Makefile complains about it diff --git a/src/common/printer.c b/src/common/printer.c index da106b0..a5909f2 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -46,7 +46,7 @@ enum { #if defined(ARCH_X86) || defined(ARCH_PPC) ATTRIBUTE_NAME, -#elif ARCH_ARM +#elif defined(ARCH_ARM) || defined(ARCH_RISCV) ATTRIBUTE_SOC, #endif #if defined(ARCH_X86) || defined(ARCH_ARM) @@ -79,7 +79,7 @@ static const char* ATTRIBUTE_FIELDS [] = { "Name:", #elif ARCH_PPC "Part Number:", -#elif ARCH_ARM +#elif defined(ARCH_ARM) || defined(ARCH_RISCV) "SoC:", #endif #if defined(ARCH_X86) || defined(ARCH_ARM) @@ -926,6 +926,8 @@ bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struc // Step 1. Retrieve attributes char* uarch = get_str_uarch(cpu); char* manufacturing_process = get_str_process(cpu->soc); + char* soc_name = get_soc_name(cpu->soc); + char* features = get_str_features(cpu); char* max_frequency = get_str_freq(cpu->freq); char* n_cores = get_str_topology(cpu, cpu->topo); @@ -936,10 +938,11 @@ bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struc char* pp = get_str_peak_performance(cpu->peak_performance); // Step 2. Set attributes - setAttribute(art,ATTRIBUTE_UARCH,uarch); + setAttribute(art,ATTRIBUTE_SOC,soc_name); setAttribute(art,ATTRIBUTE_TECHNOLOGY,manufacturing_process); - setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); + setAttribute(art,ATTRIBUTE_UARCH,uarch); setAttribute(art,ATTRIBUTE_NCORES, n_cores); + setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); /*setAttribute(art,ATTRIBUTE_L1i,l1i); setAttribute(art,ATTRIBUTE_L1d,l1d); setAttribute(art,ATTRIBUTE_L2,l2); diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index 4a3a203..987ee1d 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -5,6 +5,7 @@ #include "../common/global.h" #include "../common/udev.h" +#include "soc.h" struct frequency* get_frequency_info(uint32_t core) { struct frequency* freq = emalloc(sizeof(struct frequency)); @@ -15,23 +16,45 @@ struct frequency* get_frequency_info(uint32_t core) { return freq; } +int64_t get_peak_performance(struct cpuInfo* cpu) { + //First check we have consistent data + if(get_freq(cpu->freq) == UNKNOWN_DATA) { + return -1; + } + + int64_t flops = cpu->topo->total_cores * (get_freq(cpu->freq) * 1000000); + return flops; +} + struct cpuInfo* get_cpu_info(void) { struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); //init_cpu_info(cpu); - int ncores = get_ncores_from_cpuinfo(); + struct topology* topo = emalloc(sizeof(struct topology)); + topo->total_cores = get_ncores_from_cpuinfo(); + topo->cach = NULL; + cpu->topo = topo; + cpu->hv = emalloc(sizeof(struct hypervisor)); cpu->hv->present = false; - //cpu->soc = get_soc(); - //cpu->peak_performance = get_peak_performance(cpu); - cpu->peak_performance = 0; + cpu->soc = get_soc(); cpu->freq = get_frequency_info(0); cpu->cpu_vendor = CPU_VENDOR_RISCV; + cpu->peak_performance = get_peak_performance(cpu); return cpu; } +//TODO: Might be worth refactoring with other archs char* get_str_topology(struct cpuInfo* cpu, struct topology* topo) { - return "Many cores"; + uint32_t size = 3+7+1; + char* string = emalloc(sizeof(char)*size); + snprintf(string, size, "%d cores", topo->total_cores); + + return string; +} + +char* get_str_features(struct cpuInfo* cpu) { + return NULL; } void print_debug(struct cpuInfo* cpu) { diff --git a/src/riscv/riscv.h b/src/riscv/riscv.h index 367c56e..e644077 100644 --- a/src/riscv/riscv.h +++ b/src/riscv/riscv.h @@ -5,6 +5,7 @@ struct cpuInfo* get_cpu_info(void); char* get_str_topology(struct cpuInfo* cpu, struct topology* topo); +char* get_str_features(struct cpuInfo* cpu); void print_debug(struct cpuInfo* cpu); #endif diff --git a/src/riscv/soc.c b/src/riscv/soc.c index 6f6f115..45d8a43 100644 --- a/src/riscv/soc.c +++ b/src/riscv/soc.c @@ -1,9 +1,118 @@ #include "soc.h" +#include "socs.h" +#include "udev.h" +#include "../common/global.h" + +#include char* get_str_process(struct system_on_chip* soc) { - return "-1 nm"; + char* str; + + if(soc->process == UNKNOWN) { + str = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1)); + snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN); + } + else { + str = emalloc(sizeof(char) * 5); + memset(str, 0, sizeof(char) * 5); + snprintf(str, 5, "%dnm", soc->process); + } + return str; } char* get_soc_name(struct system_on_chip* soc) { - return "Unknown"; + if(soc->soc_model == SOC_MODEL_UNKNOWN) + return soc->raw_name; + return soc->soc_name; +} + +static char* soc_trademark_string[] = { + [SOC_VENDOR_SIFIVE] = "SiFive " +}; + +void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t process) { + soc->soc_model = soc_model; + soc->soc_vendor = get_soc_vendor_from_soc(soc_model); + soc->process = process; + int len = strlen(soc_name) + strlen(soc_trademark_string[soc->soc_vendor]) + 1; + soc->soc_name = emalloc(sizeof(char) * len); + memset(soc->soc_name, 0, sizeof(char) * len); + sprintf(soc->soc_name, "%s%s", soc_trademark_string[soc->soc_vendor], soc_name); +} + +bool match_soc(struct system_on_chip* soc, char* raw_name, char* expected_name, char* soc_name, SOC soc_model, int32_t process) { + int len1 = strlen(raw_name); + int len2 = strlen(expected_name); + int len = min(len1, len2); + + if(strncmp(raw_name, expected_name, len) != 0) { + return false; + } + else { + fill_soc(soc, soc_name, soc_model, process); + return true; + } +} + +#define SOC_START if (false) {} +#define SOC_EQ(raw_name, expected_name, soc_name, soc_model, soc, process) \ + else if (match_soc(soc, raw_name, expected_name, soc_name, soc_model, process)) return true; +#define SOC_END else { return false; } + +bool match_sifive(char* soc_name, struct system_on_chip* soc) { + char* tmp = soc_name; + + // Dont know if it makes sense in RISC-V + /*if((tmp = strstr(soc_name, "???")) == NULL) + return false;*/ + + //soc->soc_vendor = ??? + + SOC_START + SOC_EQ(tmp, "fu740", "Freedom U740", SOC_SIFIVE_U740, soc, 40) + SOC_END +} + +struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) { + char* raw_name = soc->raw_name; + match_sifive(raw_name, soc); + return soc; +} + +struct system_on_chip* guess_soc_from_devtree(struct system_on_chip* soc) { + char* tmp = get_hardware_from_devtree(); + + if(tmp != NULL) { + soc->raw_name = tmp; + return parse_soc_from_string(soc); + } + + return soc; +} + +struct system_on_chip* get_soc(void) { + struct system_on_chip* soc = emalloc(sizeof(struct system_on_chip)); + soc->raw_name = NULL; + soc->soc_vendor = SOC_VENDOR_UNKNOWN; + soc->soc_model = SOC_MODEL_UNKNOWN; + soc->process = UNKNOWN; + + soc = guess_soc_from_devtree(soc); + if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) { + if(soc->raw_name != NULL) { + printWarn("SoC detection failed using device tree: Found '%s' string", soc->raw_name); + } + else { + printWarn("SoC detection failed using device tree"); + } + } + + if(soc->soc_model == SOC_MODEL_UNKNOWN) { + // raw_name might not be NULL, but if we were unable to find + // the exact SoC, just print "Unkwnown" + soc->raw_name = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN)+1)); + snprintf(soc->raw_name, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN); + } + + return soc; } diff --git a/src/riscv/soc.h b/src/riscv/soc.h index 9f55c1b..f71a35b 100644 --- a/src/riscv/soc.h +++ b/src/riscv/soc.h @@ -6,6 +6,11 @@ typedef int32_t SOC; +enum { + SOC_VENDOR_UNKNOWN, + SOC_VENDOR_SIFIVE +}; + struct system_on_chip { SOC soc_model; VENDOR soc_vendor; @@ -14,7 +19,9 @@ struct system_on_chip { char* raw_name; }; +struct system_on_chip* get_soc(void); char* get_soc_name(struct system_on_chip* soc); +//VENDOR get_soc_vendor(struct system_on_chip* soc); char* get_str_process(struct system_on_chip* soc); #endif diff --git a/src/riscv/socs.h b/src/riscv/socs.h new file mode 100644 index 0000000..cf587f6 --- /dev/null +++ b/src/riscv/socs.h @@ -0,0 +1,19 @@ +#ifndef __SOCS__ +#define __SOCS__ + +#include "soc.h" + +// List of supported SOCs +enum { + // SIFIVE + SOC_SIFIVE_U740, + // UNKNOWN + SOC_MODEL_UNKNOWN +}; + +inline static VENDOR get_soc_vendor_from_soc(SOC soc) { + if(soc >= SOC_SIFIVE_U740 && soc <= SOC_SIFIVE_U740) return SOC_VENDOR_SIFIVE; + return SOC_VENDOR_UNKNOWN; +} + +#endif diff --git a/src/riscv/udev.c b/src/riscv/udev.c new file mode 100644 index 0000000..45a52bd --- /dev/null +++ b/src/riscv/udev.c @@ -0,0 +1,44 @@ +#include +#include + +#include "../common/global.h" +#include "udev.h" + +#define _PATH_DEVTREE "/proc/device-tree/compatible" +#define DEVTREE_HARDWARE_FIELD 3 + +// TODO: Works only for DEVTREE_FIELD == DEVTREE_HARDWARE_FIELD +char* get_field_from_devtree(int DEVTREE_FIELD) { + int filelen; + char* buf; + if((buf = read_file(_PATH_DEVTREE, &filelen)) == NULL) { + printWarn("read_file: %s: %s:\n", _PATH_DEVTREE, strerror(errno)); + return NULL; + } + + // Here we would use strstr to find the comma + // However, the device-tree file may contain NULL + // bytes in the middle of the string, which would + // cause strstr to return NULL even when there might + // be an occurence after the NULL byte + int i=0; + char* tmp1 = buf; + do { + tmp1++; + if(*tmp1 == ',') i++; + } while(filelen > (tmp1-buf) && i < DEVTREE_FIELD); + + tmp1++; + if((tmp1-buf) >= filelen) return NULL; + + int strlen = filelen-(tmp1-buf); + char* hardware = emalloc(sizeof(char) * strlen); + memset(hardware, 0, sizeof(char) * strlen); + strncpy(hardware, tmp1, strlen-1); + + return hardware; +} + +char* get_hardware_from_devtree(void) { + return get_field_from_devtree(DEVTREE_HARDWARE_FIELD); +} diff --git a/src/riscv/udev.h b/src/riscv/udev.h new file mode 100644 index 0000000..343489f --- /dev/null +++ b/src/riscv/udev.h @@ -0,0 +1,10 @@ +#ifndef __UDEV_RISCV__ +#define __UDEV_RISCV__ + +#include "../common/udev.h" + +#define UNKNOWN -1 + +char* get_hardware_from_devtree(void); + +#endif From a496f694a665e5dcc50e5499040ff1c417c6405f Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Mon, 3 Apr 2023 13:25:51 +0200 Subject: [PATCH 04/12] [v1.03][RISCV] Add SiFive ascii art --- src/common/ascii.h | 22 ++++++++++++++++++++++ src/common/printer.c | 7 +++++-- src/riscv/riscv.c | 1 - src/riscv/soc.c | 4 ++++ src/riscv/soc.h | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/common/ascii.h b/src/common/ascii.h index fe7b692..7c1b17e 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -266,6 +266,27 @@ $C1 ## ### ## ##. ## ### ### \ $C1 ## ### ## ##########. ########## ### \ $C1 " +#define ASCII_SIFIVE \ +"$C1 ########################### \ +$C1 ############################### \ +$C1 #### #### \ +$C1 ##### ##### \ +$C1 ##### ##### \ +$C1 #### ######################### \ +$C1 #### ########################### \ +$C1 #### #### \ +$C1 ##### ##### \ +$C1 ##### ##### \ +$C1 ################################# #### \ +$C1 ############################## ##### \ +$C1 ###### ####### ####### \ +$C1 ###### # ###### \ +$C1 ###### ###### \ +$C1 ###### ###### \ +$C1 ###### ###### \ +$C1 ########### \ +$C1 ### " + // --------------------- LONG LOGOS ------------------------- // #define ASCII_AMD_L \ "$C1 \ @@ -369,6 +390,7 @@ asciiL logo_apple = { ASCII_APPLE, 32, 17, false, {C_FG_WHITE}, asciiL logo_allwinner = { ASCII_ALLWINNER, 47, 16, false, {C_FG_CYAN}, {C_FG_B_BLACK, C_FG_B_CYAN } }; asciiL logo_rockchip = { ASCII_ROCKCHIP, 58, 8, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; +asciiL logo_sifive = { ASCII_SIFIVE, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_B_CYAN} }; // 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/printer.c b/src/common/printer.c index a5909f2..82b7f66 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -369,7 +369,10 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter art->art = choose_ascii_art_aux(&logo_arm_l, &logo_arm, term, lf); } #elif ARCH_RISCV - art->art = &logo_riscv; + if(art->vendor == SOC_VENDOR_SIFIVE) + art->art = &logo_sifive; + else + art->art = &logo_riscv; #endif // 2. Choose colors @@ -919,7 +922,7 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct color** cs, struct #ifdef ARCH_RISCV bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struct terminal* term) { - struct ascii* art = set_ascii(get_cpu_vendor(cpu), s); + struct ascii* art = set_ascii(get_soc_vendor(cpu->soc), s); if(art == NULL) return false; diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index 987ee1d..ee0ec02 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -38,7 +38,6 @@ struct cpuInfo* get_cpu_info(void) { cpu->hv->present = false; cpu->soc = get_soc(); cpu->freq = get_frequency_info(0); - cpu->cpu_vendor = CPU_VENDOR_RISCV; cpu->peak_performance = get_peak_performance(cpu); return cpu; diff --git a/src/riscv/soc.c b/src/riscv/soc.c index 45d8a43..1e23ef0 100644 --- a/src/riscv/soc.c +++ b/src/riscv/soc.c @@ -5,6 +5,10 @@ #include +VENDOR get_soc_vendor(struct system_on_chip* soc) { + return soc->soc_vendor; +} + char* get_str_process(struct system_on_chip* soc) { char* str; diff --git a/src/riscv/soc.h b/src/riscv/soc.h index f71a35b..368c3b9 100644 --- a/src/riscv/soc.h +++ b/src/riscv/soc.h @@ -21,7 +21,7 @@ struct system_on_chip { struct system_on_chip* get_soc(void); char* get_soc_name(struct system_on_chip* soc); -//VENDOR get_soc_vendor(struct system_on_chip* soc); +VENDOR get_soc_vendor(struct system_on_chip* soc); char* get_str_process(struct system_on_chip* soc); #endif From 30a2493ad9f1df0c9d2013ca818fb11641c89715 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Mon, 3 Apr 2023 14:08:58 +0200 Subject: [PATCH 05/12] [v1.03][RISCV] Add basic StarFive support --- src/common/ascii.h | 28 +++++++++++++++++++++++++++- src/common/printer.c | 2 ++ src/riscv/soc.c | 14 +++++++++++++- src/riscv/soc.h | 3 ++- src/riscv/socs.h | 3 +++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/common/ascii.h b/src/common/ascii.h index 7c1b17e..66aebc3 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -287,6 +287,31 @@ $C1 ###### ###### \ $C1 ########### \ $C1 ### " +#define ASCII_STARFIVE \ +"$C1 ####### \ +$C1 ################. \ +$C1 ############ ########### \ +$C1 ############ ##########. \ +$C1 ############ # ###### \ +$C1 ########### ##### ## \ +$C1 #######. ########## \ +$C1 ###### ### *########### \ +$C1 ###### #######. ########## \ +$C1 ######### ############ ###### \ +$C1 ###########. ###########* # \ +$C1 ############ ############ \ +$C1 # ############. .########### \ +$C1 ###### ########### ######### \ +$C1 ########## .######, ##### \ +$C1 ############ ##. #####. \ +$C1 ######### ######## \ +$C1 ## ##### ##########. \ +$C1 ####### # ############ \ +$C1 ########### ###########. \ +$C1 ###########. ############ \ +$C1 ################ \ +$C1 ####### " + // --------------------- LONG LOGOS ------------------------- // #define ASCII_AMD_L \ "$C1 \ @@ -390,7 +415,8 @@ asciiL logo_apple = { ASCII_APPLE, 32, 17, false, {C_FG_WHITE}, asciiL logo_allwinner = { ASCII_ALLWINNER, 47, 16, false, {C_FG_CYAN}, {C_FG_B_BLACK, C_FG_B_CYAN } }; asciiL logo_rockchip = { ASCII_ROCKCHIP, 58, 8, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; -asciiL logo_sifive = { ASCII_SIFIVE, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_B_CYAN} }; +asciiL logo_sifive = { ASCII_SIFIVE, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; +asciiL logo_starfive = { ASCII_STARFIVE, 50, 24, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; // 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/printer.c b/src/common/printer.c index 82b7f66..e9a1d96 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -371,6 +371,8 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter #elif ARCH_RISCV if(art->vendor == SOC_VENDOR_SIFIVE) art->art = &logo_sifive; + else if(art->vendor == SOC_VENDOR_STARFIVE) + art->art = &logo_starfive; else art->art = &logo_riscv; #endif diff --git a/src/riscv/soc.c b/src/riscv/soc.c index 1e23ef0..469e2fd 100644 --- a/src/riscv/soc.c +++ b/src/riscv/soc.c @@ -31,7 +31,8 @@ char* get_soc_name(struct system_on_chip* soc) { } static char* soc_trademark_string[] = { - [SOC_VENDOR_SIFIVE] = "SiFive " + [SOC_VENDOR_SIFIVE] = "SiFive ", + [SOC_VENDOR_STARFIVE] = "StarFive " }; void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t process) { @@ -77,8 +78,19 @@ bool match_sifive(char* soc_name, struct system_on_chip* soc) { SOC_END } +bool match_starfive(char* soc_name, struct system_on_chip* soc) { + SOC_START + SOC_EQ(soc_name, "jh7110#", "VisionFive 2", SOC_STARFIVE_VF2, soc, 28) // https://blog.bitsofnetworks.org/benchmarking-risc-v-visionfive-2-vs-the-world.html + SOC_EQ(soc_name, "jh7110", "VisionFive 2", SOC_STARFIVE_VF2, soc, 28) + SOC_END +} + struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) { char* raw_name = soc->raw_name; + + if(match_starfive(raw_name, soc)) + return soc; + match_sifive(raw_name, soc); return soc; } diff --git a/src/riscv/soc.h b/src/riscv/soc.h index 368c3b9..007d370 100644 --- a/src/riscv/soc.h +++ b/src/riscv/soc.h @@ -8,7 +8,8 @@ typedef int32_t SOC; enum { SOC_VENDOR_UNKNOWN, - SOC_VENDOR_SIFIVE + SOC_VENDOR_SIFIVE, + SOC_VENDOR_STARFIVE }; struct system_on_chip { diff --git a/src/riscv/socs.h b/src/riscv/socs.h index cf587f6..56cff72 100644 --- a/src/riscv/socs.h +++ b/src/riscv/socs.h @@ -7,12 +7,15 @@ enum { // SIFIVE SOC_SIFIVE_U740, + // STARFIVE + SOC_STARFIVE_VF2, // UNKNOWN SOC_MODEL_UNKNOWN }; inline static VENDOR get_soc_vendor_from_soc(SOC soc) { if(soc >= SOC_SIFIVE_U740 && soc <= SOC_SIFIVE_U740) return SOC_VENDOR_SIFIVE; + if(soc >= SOC_STARFIVE_VF2 && soc <= SOC_STARFIVE_VF2) return SOC_VENDOR_STARFIVE; return SOC_VENDOR_UNKNOWN; } From 0ef08ef53e6ac68f57797d51ac314249cdd202d4 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Fri, 7 Apr 2023 10:37:02 +0200 Subject: [PATCH 06/12] [v1.03][RISCV] Add basic Allwinner support --- src/common/printer.c | 2 ++ src/riscv/soc.c | 12 +++++++++++- src/riscv/soc.h | 3 ++- src/riscv/socs.h | 3 +++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/common/printer.c b/src/common/printer.c index e9a1d96..686201c 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -373,6 +373,8 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter art->art = &logo_sifive; else if(art->vendor == SOC_VENDOR_STARFIVE) art->art = &logo_starfive; + else if(art->vendor == SOC_VENDOR_ALLWINNER) + art->art = &logo_allwinner; else art->art = &logo_riscv; #endif diff --git a/src/riscv/soc.c b/src/riscv/soc.c index 469e2fd..6f3c7c9 100644 --- a/src/riscv/soc.c +++ b/src/riscv/soc.c @@ -32,7 +32,8 @@ char* get_soc_name(struct system_on_chip* soc) { static char* soc_trademark_string[] = { [SOC_VENDOR_SIFIVE] = "SiFive ", - [SOC_VENDOR_STARFIVE] = "StarFive " + [SOC_VENDOR_STARFIVE] = "StarFive ", + [SOC_VENDOR_ALLWINNER] = "Allwinner " }; void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t process) { @@ -85,12 +86,21 @@ bool match_starfive(char* soc_name, struct system_on_chip* soc) { SOC_END } +bool match_allwinner(char* soc_name, struct system_on_chip* soc) { + SOC_START + SOC_EQ(soc_name, "sun20i-d1", "D1-H", SOC_ALLWINNER_D1H, soc, 22) + SOC_END +} + struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) { char* raw_name = soc->raw_name; if(match_starfive(raw_name, soc)) return soc; + if(match_allwinner(raw_name, soc)) + return soc; + match_sifive(raw_name, soc); return soc; } diff --git a/src/riscv/soc.h b/src/riscv/soc.h index 007d370..b6ba2dd 100644 --- a/src/riscv/soc.h +++ b/src/riscv/soc.h @@ -9,7 +9,8 @@ typedef int32_t SOC; enum { SOC_VENDOR_UNKNOWN, SOC_VENDOR_SIFIVE, - SOC_VENDOR_STARFIVE + SOC_VENDOR_STARFIVE, + SOC_VENDOR_ALLWINNER }; struct system_on_chip { diff --git a/src/riscv/socs.h b/src/riscv/socs.h index 56cff72..0833c77 100644 --- a/src/riscv/socs.h +++ b/src/riscv/socs.h @@ -9,6 +9,8 @@ enum { SOC_SIFIVE_U740, // STARFIVE SOC_STARFIVE_VF2, + // ALLWINNER + SOC_ALLWINNER_D1H, // UNKNOWN SOC_MODEL_UNKNOWN }; @@ -16,6 +18,7 @@ enum { inline static VENDOR get_soc_vendor_from_soc(SOC soc) { if(soc >= SOC_SIFIVE_U740 && soc <= SOC_SIFIVE_U740) return SOC_VENDOR_SIFIVE; if(soc >= SOC_STARFIVE_VF2 && soc <= SOC_STARFIVE_VF2) return SOC_VENDOR_STARFIVE; + if(soc >= SOC_ALLWINNER_D1H && soc <= SOC_ALLWINNER_D1H) return SOC_VENDOR_ALLWINNER; return SOC_VENDOR_UNKNOWN; } From 69dd47bab0ab4f897ac964192c065c433847ce48 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Fri, 7 Apr 2023 15:24:33 +0200 Subject: [PATCH 07/12] [v1.03][RISCV] Search backwards in device-tree string --- src/riscv/udev.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/riscv/udev.c b/src/riscv/udev.c index 45a52bd..8724801 100644 --- a/src/riscv/udev.c +++ b/src/riscv/udev.c @@ -5,32 +5,38 @@ #include "udev.h" #define _PATH_DEVTREE "/proc/device-tree/compatible" -#define DEVTREE_HARDWARE_FIELD 3 +#define DEVTREE_HARDWARE_FIELD 0 -// TODO: Works only for DEVTREE_FIELD == DEVTREE_HARDWARE_FIELD char* get_field_from_devtree(int DEVTREE_FIELD) { int filelen; char* buf; if((buf = read_file(_PATH_DEVTREE, &filelen)) == NULL) { - printWarn("read_file: %s: %s:\n", _PATH_DEVTREE, strerror(errno)); + printWarn("read_file: %s: %s", _PATH_DEVTREE, strerror(errno)); return NULL; } - // Here we would use strstr to find the comma + // Here we would use strstr to find the comma. // However, the device-tree file may contain NULL // bytes in the middle of the string, which would // cause strstr to return NULL even when there might // be an occurence after the NULL byte + // + // We iterate the string backwards to find the field + // in position n-DEVTREE_HARDWARE_FIELD where n + // is the number of fields. int i=0; - char* tmp1 = buf; + char* tmp1 = buf+filelen-1; do { - tmp1++; + tmp1--; if(*tmp1 == ',') i++; - } while(filelen > (tmp1-buf) && i < DEVTREE_FIELD); + } while(tmp1 != buf && i <= DEVTREE_FIELD); + + if(tmp1 == buf) { + printWarn("get_field_from_devtree: Unable to find field %d", DEVTREE_FIELD); + return NULL; + } tmp1++; - if((tmp1-buf) >= filelen) return NULL; - int strlen = filelen-(tmp1-buf); char* hardware = emalloc(sizeof(char) * strlen); memset(hardware, 0, sizeof(char) * strlen); From 13e86d7f14eb087fbfd5eb07bb36881a92c0e2bf Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Fri, 7 Apr 2023 16:19:43 +0200 Subject: [PATCH 08/12] [v1.03][RISCV] Add preeliminary uarch detection --- src/common/cpu.h | 1 + src/riscv/riscv.c | 6 +++++- src/riscv/uarch.c | 48 ++++++++++++++++++++++++++++++++++++++++++----- src/riscv/uarch.h | 1 + src/riscv/udev.c | 38 ++++++++++++++++++++++++++++++++++++- src/riscv/udev.h | 1 + 6 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/common/cpu.h b/src/common/cpu.h index 011e1e6..1a45100 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -22,6 +22,7 @@ enum { CPU_VENDOR_PHYTIUM, // ARCH_RISCV CPU_VENDOR_RISCV, + CPU_VENDOR_SIFIVE, // OTHERS CPU_VENDOR_UNKNOWN, CPU_VENDOR_INVALID diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index ee0ec02..f314e4b 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -5,6 +5,8 @@ #include "../common/global.h" #include "../common/udev.h" +#include "udev.h" +#include "uarch.h" #include "soc.h" struct frequency* get_frequency_info(uint32_t core) { @@ -34,8 +36,10 @@ struct cpuInfo* get_cpu_info(void) { topo->cach = NULL; cpu->topo = topo; + char* cpuinfo_str = get_uarch_from_cpuinfo(); cpu->hv = emalloc(sizeof(struct hypervisor)); cpu->hv->present = false; + cpu->arch = get_uarch_from_cpuinfo_str(cpuinfo_str, cpu); cpu->soc = get_soc(); cpu->freq = get_frequency_info(0); cpu->peak_performance = get_peak_performance(cpu); @@ -46,7 +50,7 @@ struct cpuInfo* get_cpu_info(void) { //TODO: Might be worth refactoring with other archs char* get_str_topology(struct cpuInfo* cpu, struct topology* topo) { uint32_t size = 3+7+1; - char* string = emalloc(sizeof(char)*size); + char* string = emalloc(sizeof(char)*size); snprintf(string, size, "%d cores", topo->total_cores); return string; diff --git a/src/riscv/uarch.c b/src/riscv/uarch.c index a9aa42e..ed68ebf 100644 --- a/src/riscv/uarch.c +++ b/src/riscv/uarch.c @@ -1,18 +1,56 @@ -#include +#include +#include +#include +#include #include "uarch.h" #include "../common/global.h" +typedef uint32_t MICROARCH; + struct uarch { - //MICROARCH uarch; + MICROARCH uarch; char* uarch_str; - int32_t process; // measured in nanometers }; +enum { + UARCH_UNKNOWN, + // SIFIVE + UARCH_U74MC +}; + +#define UARCH_START if (false) {} +#define CHECK_UARCH(arch, cpu, cpuinfo_str, uarch_str, str, uarch, vendor) \ + else if (strcmp(cpuinfo_str, uarch_str) == 0) fill_uarch(arch, cpu, str, uarch, vendor); +#define UARCH_END else { printBug("Unknown microarchitecture detected: uarch='%s'", cpuinfo_str); fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN); } + +void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u, VENDOR vendor) { + arch->uarch = u; + cpu->cpu_vendor = vendor; + arch->uarch_str = emalloc(sizeof(char) * (strlen(str)+1)); + strcpy(arch->uarch_str, str); +} + +struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu) { + struct uarch* arch = emalloc(sizeof(struct uarch)); + if(cpuinfo_str == NULL) { + printWarn("get_uarch_from_cpuinfo: Unable to detect microarchitecture, cpuinfo_str is NULL"); + fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN); + return arch; + } + + UARCH_START + CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u74-mc", "U74-MC", UARCH_U74MC, CPU_VENDOR_SIFIVE) + UARCH_END + + return arch; +} + char* get_str_uarch(struct cpuInfo* cpu) { - return "Unknown"; + return cpu->arch->uarch_str; } void free_uarch_struct(struct uarch* arch) { - + free(arch->uarch_str); + free(arch); } diff --git a/src/riscv/uarch.h b/src/riscv/uarch.h index 02548f9..4a9aa24 100644 --- a/src/riscv/uarch.h +++ b/src/riscv/uarch.h @@ -8,5 +8,6 @@ struct uarch; char* get_str_uarch(struct cpuInfo* cpu); void free_uarch_struct(struct uarch* arch); +struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu); #endif diff --git a/src/riscv/udev.c b/src/riscv/udev.c index 8724801..a880f7e 100644 --- a/src/riscv/udev.c +++ b/src/riscv/udev.c @@ -4,7 +4,9 @@ #include "../common/global.h" #include "udev.h" -#define _PATH_DEVTREE "/proc/device-tree/compatible" +#define _PATH_CPUINFO "/proc/cpuinfo" +#define _PATH_DEVTREE "/proc/device-tree/compatible" +#define CPUINFO_UARCH_STR "uarch\t\t: " #define DEVTREE_HARDWARE_FIELD 0 char* get_field_from_devtree(int DEVTREE_FIELD) { @@ -45,6 +47,40 @@ char* get_field_from_devtree(int DEVTREE_FIELD) { return hardware; } +char* parse_cpuinfo_field(char* field_str) { + int filelen; + char* buf; + if((buf = read_file(_PATH_CPUINFO, &filelen)) == NULL) { + printWarn("read_file: %s: %s", _PATH_CPUINFO, strerror(errno)); + return NULL; + } + + char* tmp = strstr(buf, field_str); + if(tmp == NULL) { + printWarn("parse_cpuinfo_field: Unable to find field %s", field_str); + return NULL; + } + + tmp += strlen(field_str); + char* end = strstr(tmp, "\n"); + + if(end == NULL) { + printWarn("parse_cpuinfo_field: Unable to find newline after field %s", field_str); + return NULL; + } + + int ret_strlen = (end-tmp); + char* ret = emalloc(sizeof(char) * (ret_strlen+1)); + memset(ret, 0, sizeof(char) * (ret_strlen+1)); + strncpy(ret, tmp, ret_strlen); + + return ret; +} + char* get_hardware_from_devtree(void) { return get_field_from_devtree(DEVTREE_HARDWARE_FIELD); } + +char* get_uarch_from_cpuinfo(void) { + return parse_cpuinfo_field(CPUINFO_UARCH_STR); +} diff --git a/src/riscv/udev.h b/src/riscv/udev.h index 343489f..33e1a19 100644 --- a/src/riscv/udev.h +++ b/src/riscv/udev.h @@ -6,5 +6,6 @@ #define UNKNOWN -1 char* get_hardware_from_devtree(void); +char* get_uarch_from_cpuinfo(void); #endif From 65bad8721e1e7cdc293c9f1bad4a067e5f42e20f Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sat, 8 Apr 2023 11:51:20 +0200 Subject: [PATCH 09/12] [v1.03][RISCV] Add short/long variants for SiFive and StarFive ascii arts and fix StarFive long logo --- src/common/ascii.h | 44 ++++++++++++++++++++++++++++++++++++++++++-- src/common/printer.c | 4 ++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/common/ascii.h b/src/common/ascii.h index 66aebc3..49fb9cc 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -267,6 +267,25 @@ $C1 ## ### ## ##########. ########## ### \ $C1 " #define ASCII_SIFIVE \ +"$C1 ######################## \ +$C1 ############################ \ +$C1 #### #### \ +$C1 #### #### \ +$C1 #### #### \ +$C1 #### ######################### \ +$C1 #### ########################### \ +$C1 #### #### \ +$C1 #### #### \ +$C1############################### #### \ +$C1############################# #### \ +$C1 ###### ###### ###### \ +$C1 ##### ## ##### \ +$C1 ###### ###### \ +$C1 ##### ##### \ +$C1 ###### ###### \ +$C1 ###### " + +#define ASCII_SIFIVE_L \ "$C1 ########################### \ $C1 ############################### \ $C1 #### #### \ @@ -288,6 +307,25 @@ $C1 ########### \ $C1 ### " #define ASCII_STARFIVE \ +"$C1 # \ +$C1 ########## \ +$C1 ######## ######## \ +$C1 ######## #### \ +$C1 ####### #### \ +$C1 #### ####### \ +$C1 #### ##### ####### \ +$C1 ####### ######## .## \ +$C1 ######## ######## \ +$C1 ### ########. ####### \ +$C1 ####### ##### #### \ +$C1 ######## #. #### \ +$C1 # #### ####### \ +$C1 ##### ####### \ +$C1 ######## ######## \ +$C1 ######### \ +$C1 # " + +#define ASCII_STARFIVE_L \ "$C1 ####### \ $C1 ################. \ $C1 ############ ########### \ @@ -415,8 +453,8 @@ asciiL logo_apple = { ASCII_APPLE, 32, 17, false, {C_FG_WHITE}, asciiL logo_allwinner = { ASCII_ALLWINNER, 47, 16, false, {C_FG_CYAN}, {C_FG_B_BLACK, C_FG_B_CYAN } }; asciiL logo_rockchip = { ASCII_ROCKCHIP, 58, 8, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; -asciiL logo_sifive = { ASCII_SIFIVE, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; -asciiL logo_starfive = { ASCII_STARFIVE, 50, 24, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; +asciiL logo_sifive = { ASCII_SIFIVE, 45, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; +asciiL logo_starfive = { ASCII_STARFIVE, 33, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; // Long variants | ----------------------------------------------------------------------------------------------------| asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} }; @@ -424,6 +462,8 @@ asciiL logo_intel_l = { ASCII_INTEL_L, 62, 19, true, {C_BG_CYAN, C_BG_W asciiL logo_intel_l_new = { ASCII_INTEL_L_NEW, 57, 14, true, {C_BG_CYAN, C_BG_WHITE, C_BG_BLUE}, {C_FG_CYAN, C_FG_WHITE} }; asciiL logo_arm_l = { ASCII_ARM_L, 60, 8, true, {C_BG_CYAN}, {C_FG_WHITE, C_FG_CYAN} }; asciiL logo_ibm_l = { ASCII_IBM_L, 62, 13, true, {C_BG_CYAN, C_FG_WHITE}, {C_FG_CYAN, C_FG_WHITE} }; +asciiL logo_starfive_l = { ASCII_STARFIVE_L, 50, 22, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; +asciiL logo_sifive_l = { ASCII_SIFIVE_L, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; asciiL logo_unknown = { NULL, 0, 0, false, {COLOR_NONE}, {COLOR_NONE, COLOR_NONE} }; #endif diff --git a/src/common/printer.c b/src/common/printer.c index 686201c..7e1248a 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -370,9 +370,9 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter } #elif ARCH_RISCV if(art->vendor == SOC_VENDOR_SIFIVE) - art->art = &logo_sifive; + art->art = choose_ascii_art_aux(&logo_sifive_l, &logo_sifive, term, lf); else if(art->vendor == SOC_VENDOR_STARFIVE) - art->art = &logo_starfive; + art->art = choose_ascii_art_aux(&logo_starfive_l, &logo_starfive, term, lf); else if(art->vendor == SOC_VENDOR_ALLWINNER) art->art = &logo_allwinner; else From 9e9828d21052959648e9d4c06e584a7f8918d168 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sat, 8 Apr 2023 12:39:56 +0200 Subject: [PATCH 10/12] [v1.03][RISCV] Improve SiFive logo and add SiFive color scheme --- src/common/args.c | 2 ++ src/common/ascii.h | 80 +++++++++++++++++++++++--------------------- src/common/main.c | 1 + src/common/printer.h | 1 + 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/common/args.c b/src/common/args.c index 22d8ca7..b3d2b10 100644 --- a/src/common/args.c +++ b/src/common/args.c @@ -13,6 +13,7 @@ #define COLOR_STR_IBM "ibm" #define COLOR_STR_ARM "arm" #define COLOR_STR_ROCKCHIP "rockchip" +#define COLOR_STR_SIFIVE "sifive" static const char *SYTLES_STR_LIST[] = { [STYLE_EMPTY] = NULL, @@ -170,6 +171,7 @@ bool parse_color(char* optarg_str, struct color*** cs) { else if(strcmp(optarg_str, COLOR_STR_IBM) == 0) color_to_copy = COLOR_DEFAULT_IBM; else if(strcmp(optarg_str, COLOR_STR_ARM) == 0) color_to_copy = COLOR_DEFAULT_ARM; else if(strcmp(optarg_str, COLOR_STR_ROCKCHIP) == 0) color_to_copy = COLOR_DEFAULT_ROCKCHIP; + else if(strcmp(optarg_str, COLOR_STR_SIFIVE) == 0) color_to_copy = COLOR_DEFAULT_SIFIVE; else { str_to_parse = optarg_str; free_ptr = false; diff --git a/src/common/ascii.h b/src/common/ascii.h index 49fb9cc..2dd9fbc 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -267,44 +267,48 @@ $C1 ## ### ## ##########. ########## ### \ $C1 " #define ASCII_SIFIVE \ -"$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 ####@@@@#######@@@@@@@@@@@@@@@@@@@@@@@@@@@#### \ +$C1 ###@@@@################################@@@@### \ +$C1 ##@@@@##################################@@@@## \ +$C1 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#########@@@@# \ +$C1 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###########@@@@# \ +$C1 ##@@@@@@############@@@@@@############@@@@@@## \ +$C1 ######@@@@@###########@@###########@@@@@###### \ +$C1 #########@@@@@@################@@@@@@######### \ +$C1 #############@@@@@##########@@@@@############# \ +$C1 ################@@@@@@##@@@@@@################ \ +$C1 ####################@@@@@@#################### \ +$C1 ############################################## " #define ASCII_SIFIVE_L \ -"$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 #######@@@@@###########################@@@@######## \ +$C1 ######@@@@@########@@@@@@@@@@@@@@@@@@@@@@@@@####### \ +$C1 #####@@@@@########@@@@@@@@@@@@@@@@@@@@@@@@@@@###### \ +$C1 ####@@@@@################################@@@@@##### \ +$C1 ###@@@@@##################################@@@@@#### \ +$C1 ##@@@@@####################################@@@@@### \ +$C1 ##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#########@@@@### \ +$C1 ##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@############@@@@### \ +$C1 ####@@@@@#############@@@@@@@############@@@@@##### \ +$C1 #######@@@@@@############@############@@@@@@####### \ +$C1 ##########@@@@@@###################@@@@@@########## \ +$C1 ##############@@@@@@###########@@@@@@############## \ +$C1 #################@@@@@@#####@@@@@@################# \ +$C1 ####################@@@@@@@@@@@#################### \ +$C1 ########################@@@######################## \ +$C1 ################################################### " #define ASCII_STARFIVE \ "$C1 # \ @@ -453,7 +457,7 @@ asciiL logo_apple = { ASCII_APPLE, 32, 17, false, {C_FG_WHITE}, asciiL logo_allwinner = { ASCII_ALLWINNER, 47, 16, false, {C_FG_CYAN}, {C_FG_B_BLACK, C_FG_B_CYAN } }; asciiL logo_rockchip = { ASCII_ROCKCHIP, 58, 8, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_YELLOW}, {C_FG_CYAN, C_FG_YELLOW} }; -asciiL logo_sifive = { ASCII_SIFIVE, 45, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; +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} }; // Long variants | ----------------------------------------------------------------------------------------------------| @@ -463,7 +467,7 @@ asciiL logo_intel_l_new = { ASCII_INTEL_L_NEW, 57, 14, true, {C_BG_CYAN, C_BG_W asciiL logo_arm_l = { ASCII_ARM_L, 60, 8, true, {C_BG_CYAN}, {C_FG_WHITE, C_FG_CYAN} }; asciiL logo_ibm_l = { ASCII_IBM_L, 62, 13, true, {C_BG_CYAN, C_FG_WHITE}, {C_FG_CYAN, C_FG_WHITE} }; asciiL logo_starfive_l = { ASCII_STARFIVE_L, 50, 22, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} }; -asciiL logo_sifive_l = { ASCII_SIFIVE_L, 51, 19, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_CYAN} }; +asciiL logo_sifive_l = { ASCII_SIFIVE_L, 53, 21, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_CYAN} }; asciiL logo_unknown = { NULL, 0, 0, false, {COLOR_NONE}, {COLOR_NONE, COLOR_NONE} }; #endif diff --git a/src/common/main.c b/src/common/main.c index 6f2900f..6371e9b 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -44,6 +44,7 @@ void print_help(char *argv[]) { printf(" * \"amd\": Use AMD default color scheme \n"); printf(" * \"ibm\", Use IBM default color scheme \n"); printf(" * \"arm\": Use ARM default color scheme \n"); + printf(" * \"sifive\": Use SiFive default color scheme \n"); printf(" * custom: If the argument of --color does not match any of the previous strings, a custom scheme can be specified.\n"); printf(" 5 colors must be given in RGB with the format: R,G,B:R,G,B:...\n"); printf(" The first 3 colors are the CPU art color and the next 2 colors are the text colors\n"); diff --git a/src/common/printer.h b/src/common/printer.h index 21dd906..26a1fa3 100644 --- a/src/common/printer.h +++ b/src/common/printer.h @@ -24,6 +24,7 @@ typedef int STYLE; #define COLOR_DEFAULT_IBM "092,119,172:092,119,172:000,000,000:240,240,240:092,119,172" #define COLOR_DEFAULT_ARM "000,145,189:000,145,189:000,000,000:240,240,240:000,145,189" #define COLOR_DEFAULT_ROCKCHIP "114,159,207:229,195,000:000,000,000:240,240,240:114,159,207" +#define COLOR_DEFAULT_SIFIVE "255,255,255:000,000,000:000,000,000:255,255,255:000,000,000" #ifdef ARCH_X86 void print_levels(struct cpuInfo* cpu); From 4405a262ca80647b6a045c26d51d3e5dea8aefbb Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Wed, 12 Apr 2023 16:23:23 +0200 Subject: [PATCH 11/12] [v1.03][RISCV] Add some more uarchs --- src/common/cpu.h | 1 + src/common/printer.c | 2 +- src/riscv/riscv.c | 2 +- src/riscv/riscv.h | 2 +- src/riscv/uarch.c | 26 ++++++++++++++++++++++++-- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/common/cpu.h b/src/common/cpu.h index 1a45100..0db2fbf 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -23,6 +23,7 @@ enum { // ARCH_RISCV CPU_VENDOR_RISCV, CPU_VENDOR_SIFIVE, + CPU_VENDOR_THEAD, // OTHERS CPU_VENDOR_UNKNOWN, CPU_VENDOR_INVALID diff --git a/src/common/printer.c b/src/common/printer.c index 7e1248a..c778626 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -934,7 +934,7 @@ bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struc char* uarch = get_str_uarch(cpu); char* manufacturing_process = get_str_process(cpu->soc); char* soc_name = get_soc_name(cpu->soc); - char* features = get_str_features(cpu); + char* extensions = get_str_extensions(cpu); char* max_frequency = get_str_freq(cpu->freq); char* n_cores = get_str_topology(cpu, cpu->topo); diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index f314e4b..3a3a78b 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -56,7 +56,7 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo) { return string; } -char* get_str_features(struct cpuInfo* cpu) { +char* get_str_extensions(struct cpuInfo* cpu) { return NULL; } diff --git a/src/riscv/riscv.h b/src/riscv/riscv.h index e644077..b9729fb 100644 --- a/src/riscv/riscv.h +++ b/src/riscv/riscv.h @@ -5,7 +5,7 @@ struct cpuInfo* get_cpu_info(void); char* get_str_topology(struct cpuInfo* cpu, struct topology* topo); -char* get_str_features(struct cpuInfo* cpu); +char* get_str_extensions(struct cpuInfo* cpu); void print_debug(struct cpuInfo* cpu); #endif diff --git a/src/riscv/uarch.c b/src/riscv/uarch.c index ed68ebf..0821993 100644 --- a/src/riscv/uarch.c +++ b/src/riscv/uarch.c @@ -16,7 +16,11 @@ struct uarch { enum { UARCH_UNKNOWN, // SIFIVE - UARCH_U74MC + UARCH_U54, + UARCH_U74, + // THEAD + UARCH_C906, + UARCH_C910 }; #define UARCH_START if (false) {} @@ -31,6 +35,9 @@ void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u, strcpy(arch->uarch_str, str); } +// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml +// SiFive: https://www.sifive.com/risc-v-core-ip +// T-Head: https://www.t-head.cn/product/c906 struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu) { struct uarch* arch = emalloc(sizeof(struct uarch)); if(cpuinfo_str == NULL) { @@ -39,8 +46,23 @@ struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu) return arch; } + // U74/U74-MC: + // SiFive says that U74-MC is "Multicore: four U74 cores and one S76 core" while + // U74 is "High performance Linux-capable processor". It's like U74-MC is somehow a small SoC containing + // the U74 and the S76? Then U74-MC is not a microarchitecture per se... UARCH_START - CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u74-mc", "U74-MC", UARCH_U74MC, CPU_VENDOR_SIFIVE) + CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,bullet0", "U74", UARCH_U74, CPU_VENDOR_SIFIVE) // bullet0 is present in U740, which has U74 + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,e5", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,e7", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,e71", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,rocket0", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u5", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u54", "U54", UARCH_U54, CPU_VENDOR_SIFIVE) + // CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u7", "XXXXXX", UARCH_U74, CPU_VENDOR_SIFIVE) + CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u74", "U74", UARCH_U74, CPU_VENDOR_SIFIVE) + CHECK_UARCH(arch, cpu, cpuinfo_str, "sifive,u74-mc", "U74", UARCH_U74, CPU_VENDOR_SIFIVE) + CHECK_UARCH(arch, cpu, cpuinfo_str, "thead,c906", "T-Head C906", UARCH_C906, CPU_VENDOR_THEAD) + CHECK_UARCH(arch, cpu, cpuinfo_str, "thead,c910", "T-Head C910", UARCH_C910, CPU_VENDOR_THEAD) UARCH_END return arch; From 05744f4e40b3f6bb487703af5d80baeee782bf97 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Wed, 12 Apr 2023 18:55:56 +0200 Subject: [PATCH 12/12] [v1.03][RISCV] Add support for RISCV extensions --- src/common/cpu.h | 16 ++++++- src/common/printer.c | 105 ++++++++++++++++++++++++++++++++++++++++++- src/riscv/riscv.c | 40 +++++++++++++++++ src/riscv/riscv.h | 26 +++++++++++ src/riscv/udev.c | 6 +++ src/riscv/udev.h | 1 + 6 files changed, 190 insertions(+), 4 deletions(-) diff --git a/src/common/cpu.h b/src/common/cpu.h index 0db2fbf..449fbe0 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -120,16 +120,28 @@ struct features { #endif }; +struct extensions { + char* str; + uint32_t mask; +}; + struct cpuInfo { - VENDOR cpu_vendor; + VENDOR cpu_vendor; struct uarch* arch; struct hypervisor* hv; struct frequency* freq; struct cache* cach; struct topology* topo; - struct features* feat; int64_t peak_performance; + // Similar but not exactly equal + // to struct features +#ifdef ARCH_RISCV + struct extensions* ext; +#else + struct features* feat; +#endif + #if defined(ARCH_X86) || defined(ARCH_PPC) // CPU name from model char* cpu_name; diff --git a/src/common/printer.c b/src/common/printer.c index c778626..9216fb7 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -66,6 +66,8 @@ enum { ATTRIBUTE_ALTIVEC, #elif ARCH_ARM ATTRIBUTE_FEATURES, +#elif ARCH_RISCV + ATTRIBUTE_EXTENSIONS, #endif ATTRIBUTE_L1i, ATTRIBUTE_L1d, @@ -99,6 +101,8 @@ static const char* ATTRIBUTE_FIELDS [] = { "Altivec: ", #elif defined(ARCH_ARM) "Features: ", +#elif defined(ARCH_RISCV) + "Extensions: ", #endif "L1i Size:", "L1d Size:", @@ -132,6 +136,8 @@ static const char* ATTRIBUTE_FIELDS_SHORT [] = { "Altivec: ", #elif defined(ARCH_ARM) "Features: ", +#elif defined(ARCH_RISCV) + "Extensions: ", #endif "L1i Size:", "L1d Size:", @@ -442,7 +448,7 @@ uint32_t longest_field_length(struct ascii* art, int la) { return max; } -#if defined(ARCH_X86) || defined(ARCH_PPC) || defined(ARCH_RISCV) +#if defined(ARCH_X86) || defined(ARCH_PPC) void print_ascii_generic(struct ascii* art, uint32_t la, int32_t termw, const char** attribute_fields, bool hybrid_architecture) { struct ascii_logo* logo = art->art; int attr_to_print = 0; @@ -925,6 +931,98 @@ bool print_cpufetch_arm(struct cpuInfo* cpu, STYLE s, struct color** cs, struct #endif #ifdef ARCH_RISCV +// https://stackoverflow.com/questions/109023/count-the-number-of-set-bits-in-a-32-bit-integer +int number_of_bits(uint32_t i) { + i = i - ((i >> 1) & 0x55555555); // add pairs of bits + i = (i & 0x33333333) + ((i >> 2) & 0x33333333); // quads + i = (i + (i >> 4)) & 0x0F0F0F0F; // groups of 8 + + return (i * 0x01010101) >> 24; // horizontal sum of bytes +} + +void print_ascii_riscv(struct ascii* art, uint32_t la, int32_t termw, const char** attribute_fields, uint32_t extensions_mask) { + struct ascii_logo* logo = art->art; + int attr_to_print = 0; + int attr_type; + char* attr_value; + int32_t beg_space; + int32_t space_right; + int32_t ext_list_size = sizeof(extension_list)/sizeof(extension_list[0]); + int32_t ext_num = 0; + int32_t ext_to_print = 0; + int32_t num_extensions = number_of_bits(extensions_mask); + int32_t space_up = ((int)logo->height - (int)(art->n_attributes_set + num_extensions))/2; + int32_t space_down = (int)logo->height - (int)(art->n_attributes_set + num_extensions) - (int)space_up; + uint32_t logo_pos = 0; + int32_t iters = max(logo->height, art->n_attributes_set); + + struct line_buffer* lbuf = emalloc(sizeof(struct line_buffer)); + lbuf->buf = emalloc(sizeof(char) * LINE_BUFFER_SIZE); + lbuf->pos = 0; + lbuf->chars = 0; + + printf("\n"); + for(int32_t n=0; n < iters; n++) { + // 1. Print logo + if(space_up > 0 || (space_up + n >= 0 && space_up + n < (int)logo->height)) { + for(uint32_t i=0; i < logo->width; i++) { + if(logo->art[logo_pos] == '$') { + if(logo->replace_blocks) logo_pos += 3; + else parse_print_color(art, lbuf, &logo_pos); + } + if(logo->replace_blocks && logo->art[logo_pos] != ' ') { + if(logo->art[logo_pos] == '#') printOut(lbuf, 1, "%s%c%s", logo->color_ascii[0], ' ', art->reset); + else if(logo->art[logo_pos] == '@') printOut(lbuf, 1, "%s%c%s", logo->color_ascii[1], ' ', art->reset); + else if(logo->art[logo_pos] == '%') printOut(lbuf, 1, "%s%c%s", logo->color_ascii[2], ' ', art->reset); + else printOut(lbuf, 1, "%c", logo->art[logo_pos]); + } + else + printOut(lbuf, 1, "%c", logo->art[logo_pos]); + + logo_pos++; + } + printOut(lbuf, 0, "%s", art->reset); + } + else { + // If logo should not be printed, fill with spaces + printOut(lbuf, logo->width, "%*c", logo->width, ' '); + } + + // 2. Print text + if(space_up < 0 || (n > space_up-1 && n < (int)logo->height - space_down)) { + attr_type = art->attributes[attr_to_print]->type; + attr_value = art->attributes[attr_to_print]->value; + + // Print extension + if(attr_to_print > 0 && art->attributes[attr_to_print-1]->type == ATTRIBUTE_EXTENSIONS && ext_num != num_extensions) { + // Search for the extension to print + while(ext_to_print < ext_list_size && !((extensions_mask >> extension_list[ext_to_print].id) & 1U)) ext_to_print++; + if(ext_to_print == ext_list_size) { + printBug("print_ascii_riscv: Unable to find the extension to print"); + } + + printOut(lbuf, 3 + strlen(extension_list[ext_to_print].str), "%s - %s%s", logo->color_text[0], extension_list[ext_to_print].str, art->reset); + ext_num++; + ext_to_print++; + } + else { + attr_to_print++; + beg_space = 0; + space_right = 2 + 1 + (la - strlen(attribute_fields[attr_type])); + + printOut(lbuf, beg_space + strlen(attribute_fields[attr_type]) + space_right + strlen(attr_value), + "%*s%s%s%s%*s%s%s%s", beg_space, "", logo->color_text[0], attribute_fields[attr_type], art->reset, space_right, "", logo->color_text[1], attr_value, art->reset); + } + } + printOutLine(lbuf, art, termw); + printf("\n"); + } + printf("\n"); + + free(lbuf->buf); + free(lbuf); +} + bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struct terminal* term) { struct ascii* art = set_ascii(get_soc_vendor(cpu->soc), s); if(art == NULL) @@ -950,6 +1048,9 @@ bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struc setAttribute(art,ATTRIBUTE_UARCH,uarch); setAttribute(art,ATTRIBUTE_NCORES, n_cores); setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); + if(extensions != NULL) { + setAttribute(art,ATTRIBUTE_EXTENSIONS,extensions); + } /*setAttribute(art,ATTRIBUTE_L1i,l1i); setAttribute(art,ATTRIBUTE_L1d,l1d); setAttribute(art,ATTRIBUTE_L2,l2); @@ -971,7 +1072,7 @@ bool print_cpufetch_riscv(struct cpuInfo* cpu, STYLE s, struct color** cs, struc longest_attribute = longest_attribute_length(art, attribute_fields); } - print_ascii_generic(art, longest_attribute, term->w, attribute_fields, false); + print_ascii_riscv(art, longest_attribute, term->w, attribute_fields, cpu->ext->mask); return true; } diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c index 3a3a78b..67e40b7 100644 --- a/src/riscv/riscv.c +++ b/src/riscv/riscv.c @@ -28,6 +28,40 @@ int64_t get_peak_performance(struct cpuInfo* cpu) { return flops; } +struct extensions* get_extensions_from_str(char* str) { + struct extensions* ext = emalloc(sizeof(struct extensions)); + ext->mask = 0; + ext->str = NULL; + + if(str == NULL) { + return ext; + } + + int len = sizeof(char) * (strlen(str)+1); + ext->str = emalloc(sizeof(char) * len); + memset(ext->str, 0, len); + strncpy(ext->str, str, sizeof(char) * len); + + // Code inspired in Linux kernel: + // https://elixir.bootlin.com/linux/v6.2.10/source/arch/riscv/kernel/cpufeature.c + char* isa = str; + if (!strncmp(isa, "rv32", 4)) + isa += 4; + else if (!strncmp(isa, "rv64", 4)) + isa += 4; + else { + printBug("get_extensions_from_str: ISA string must start with rv64 or rv32"); + return ext; + } + + for(char* e = isa; *e != '\0'; e++) { + int n = *e - 'a'; + ext->mask |= 1UL << n; + } + + return ext; +} + struct cpuInfo* get_cpu_info(void) { struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); //init_cpu_info(cpu); @@ -37,8 +71,11 @@ struct cpuInfo* get_cpu_info(void) { cpu->topo = topo; char* cpuinfo_str = get_uarch_from_cpuinfo(); + char* ext_str = get_extensions_from_cpuinfo(); cpu->hv = emalloc(sizeof(struct hypervisor)); cpu->hv->present = false; + cpu->ext = get_extensions_from_str(ext_str); + if(cpu->ext->str != NULL && cpu->ext->mask == 0) return NULL; cpu->arch = get_uarch_from_cpuinfo_str(cpuinfo_str, cpu); cpu->soc = get_soc(); cpu->freq = get_frequency_info(0); @@ -57,6 +94,9 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo) { } char* get_str_extensions(struct cpuInfo* cpu) { + if(cpu->ext != NULL) { + return cpu->ext->str; + } return NULL; } diff --git a/src/riscv/riscv.h b/src/riscv/riscv.h index b9729fb..fcbdff1 100644 --- a/src/riscv/riscv.h +++ b/src/riscv/riscv.h @@ -3,6 +3,32 @@ #include "../common/cpu.h" +struct extension { + int id; + char* str; +}; + +// https://en.wikichip.org/wiki/risc-v/standard_extensions +// Included all except for G +static const struct extension extension_list[] = { + { 'i' - 'a', "(I) Integer Instruction Set" }, + { 'm' - 'a', "(M) Integer Multiplication and Division" }, + { 'a' - 'a', "(A) Atomic Instructions" }, + { 'f' - 'a', "(F) Single-Precision Floating-Point" }, + { 'd' - 'a', "(D) Double-Precision Floating-Point" }, + { 'q' - 'a', "(Q) Quad-Precision Floating-Point" }, + { 'l' - 'a', "(L) Decimal Floating-Point" }, + { 'c' - 'a', "(C) Compressed Instructions" }, + { 'b' - 'a', "(B) Double-Precision Floating-Point" }, + { 'j' - 'a', "(J) Dynamically Translated Languages" }, + { 't' - 'a', "(T) Transactional Memory" }, + { 'p' - 'a', "(P) Packed-SIMD Instructions" }, + { 'v' - 'a', "(V) Vector Operations" }, + { 'n' - 'a', "(N) User-Level Interrupts" }, + { 'h' - 'a', "(H) Hypervisor" }, + { 's' - 'a', "(S) Supervisor-level Instructions" } +}; + struct cpuInfo* get_cpu_info(void); char* get_str_topology(struct cpuInfo* cpu, struct topology* topo); char* get_str_extensions(struct cpuInfo* cpu); diff --git a/src/riscv/udev.c b/src/riscv/udev.c index a880f7e..1769e9e 100644 --- a/src/riscv/udev.c +++ b/src/riscv/udev.c @@ -7,6 +7,7 @@ #define _PATH_CPUINFO "/proc/cpuinfo" #define _PATH_DEVTREE "/proc/device-tree/compatible" #define CPUINFO_UARCH_STR "uarch\t\t: " +#define CPUINFO_EXTENSIONS_STR "isa\t\t: " #define DEVTREE_HARDWARE_FIELD 0 char* get_field_from_devtree(int DEVTREE_FIELD) { @@ -84,3 +85,8 @@ char* get_hardware_from_devtree(void) { char* get_uarch_from_cpuinfo(void) { return parse_cpuinfo_field(CPUINFO_UARCH_STR); } + +char* get_extensions_from_cpuinfo() { + return parse_cpuinfo_field(CPUINFO_EXTENSIONS_STR); +} + diff --git a/src/riscv/udev.h b/src/riscv/udev.h index 33e1a19..48a54db 100644 --- a/src/riscv/udev.h +++ b/src/riscv/udev.h @@ -7,5 +7,6 @@ char* get_hardware_from_devtree(void); char* get_uarch_from_cpuinfo(void); +char* get_extensions_from_cpuinfo(void); #endif