mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 07:50:40 +01:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad5c9e6037 | ||
|
|
6ada3ec361 | ||
|
|
91c92bbdf6 | ||
|
|
d0cc04529c | ||
|
|
f826125395 | ||
|
|
2272423163 | ||
|
|
5194976739 | ||
|
|
417d7ce730 |
@@ -445,6 +445,26 @@ $C1 .######### |__________|###### |__________| \
|
|||||||
$C1 ########### ___########### __________ \
|
$C1 ########### ___########### __________ \
|
||||||
$C1.########## |__________| |__________| "
|
$C1.########## |__________| |__________| "
|
||||||
|
|
||||||
|
#define ASCII_SPACEMIT \
|
||||||
|
"$C1 :#: \
|
||||||
|
$C1 :####: \
|
||||||
|
$C1 :#######: \
|
||||||
|
$C1 :#########: \
|
||||||
|
$C1 :#########: \
|
||||||
|
$C1 :#######: \
|
||||||
|
$C1 :####: \
|
||||||
|
$C1 :#: \
|
||||||
|
$C1:##: :#: \
|
||||||
|
$C1:####: :###: \
|
||||||
|
$C1:#######: :####: \
|
||||||
|
$C1:##########: :###: \
|
||||||
|
$C1:###########: :#: \
|
||||||
|
$C1:###########: \
|
||||||
|
$C1 :##########: \
|
||||||
|
$C1 :#######: \
|
||||||
|
$C1 :####: \
|
||||||
|
$C1 :##: "
|
||||||
|
|
||||||
// --------------------- LONG LOGOS ------------------------- //
|
// --------------------- LONG LOGOS ------------------------- //
|
||||||
#define ASCII_AMD_L \
|
#define ASCII_AMD_L \
|
||||||
"$C1 \
|
"$C1 \
|
||||||
@@ -624,6 +644,7 @@ asciiL logo_ampere = { ASCII_AMPERE, 50, 17, false, {C_FG_RED},
|
|||||||
asciiL logo_nxp = { ASCII_NXP, 55, 8, false, {C_FG_YELLOW, C_FG_CYAN, C_FG_GREEN}, {C_FG_CYAN, C_FG_WHITE} };
|
asciiL logo_nxp = { ASCII_NXP, 55, 8, false, {C_FG_YELLOW, C_FG_CYAN, C_FG_GREEN}, {C_FG_CYAN, C_FG_WHITE} };
|
||||||
asciiL logo_amlogic = { ASCII_AMLOGIC, 58, 8, false, {C_FG_BLUE}, {C_FG_BLUE, C_FG_B_WHITE} };
|
asciiL logo_amlogic = { ASCII_AMLOGIC, 58, 8, false, {C_FG_BLUE}, {C_FG_BLUE, C_FG_B_WHITE} };
|
||||||
asciiL logo_marvell = { ASCII_MARVELL, 56, 10, false, {C_FG_B_BLACK}, {C_FG_B_BLACK, C_FG_B_WHITE} };
|
asciiL logo_marvell = { ASCII_MARVELL, 56, 10, false, {C_FG_B_BLACK}, {C_FG_B_BLACK, C_FG_B_WHITE} };
|
||||||
|
asciiL logo_spacemit = { ASCII_SPACEMIT, 26, 18, false, {C_FG_B_GREEN}, {C_FG_B_GREEN, C_FG_B_WHITE} };
|
||||||
|
|
||||||
// Long variants | ----------------------------------------------------------------------------------------------------------------|
|
// Long variants | ----------------------------------------------------------------------------------------------------------------|
|
||||||
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ enum {
|
|||||||
CPU_VENDOR_RISCV,
|
CPU_VENDOR_RISCV,
|
||||||
CPU_VENDOR_SIFIVE,
|
CPU_VENDOR_SIFIVE,
|
||||||
CPU_VENDOR_THEAD,
|
CPU_VENDOR_THEAD,
|
||||||
|
CPU_VENDOR_SPACEMIT,
|
||||||
// OTHERS
|
// OTHERS
|
||||||
CPU_VENDOR_UNKNOWN,
|
CPU_VENDOR_UNKNOWN,
|
||||||
CPU_VENDOR_INVALID
|
CPU_VENDOR_INVALID
|
||||||
|
|||||||
@@ -412,6 +412,8 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
|
|||||||
art->art = &logo_allwinner;
|
art->art = &logo_allwinner;
|
||||||
else if(art->vendor == SOC_VENDOR_SIPEED)
|
else if(art->vendor == SOC_VENDOR_SIPEED)
|
||||||
art->art = &logo_sipeed;
|
art->art = &logo_sipeed;
|
||||||
|
else if(art->vendor == SOC_VENDOR_SPACEMIT)
|
||||||
|
art->art = &logo_spacemit;
|
||||||
else
|
else
|
||||||
art->art = &logo_riscv;
|
art->art = &logo_riscv;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ static char* soc_trademark_string[] = {
|
|||||||
[SOC_VENDOR_SIFIVE] = "SiFive ",
|
[SOC_VENDOR_SIFIVE] = "SiFive ",
|
||||||
[SOC_VENDOR_STARFIVE] = "StarFive ",
|
[SOC_VENDOR_STARFIVE] = "StarFive ",
|
||||||
[SOC_VENDOR_SIPEED] = "Sipeed ",
|
[SOC_VENDOR_SIPEED] = "Sipeed ",
|
||||||
|
[SOC_VENDOR_SPACEMIT] = "SpacemiT ",
|
||||||
// ARM & RISC-V
|
// ARM & RISC-V
|
||||||
[SOC_VENDOR_ALLWINNER] = "Allwinner "
|
[SOC_VENDOR_ALLWINNER] = "Allwinner "
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ enum {
|
|||||||
SOC_VENDOR_SIFIVE,
|
SOC_VENDOR_SIFIVE,
|
||||||
SOC_VENDOR_STARFIVE,
|
SOC_VENDOR_STARFIVE,
|
||||||
SOC_VENDOR_SIPEED,
|
SOC_VENDOR_SIPEED,
|
||||||
|
SOC_VENDOR_SPACEMIT,
|
||||||
// ARM & RISC-V
|
// ARM & RISC-V
|
||||||
SOC_VENDOR_ALLWINNER
|
SOC_VENDOR_ALLWINNER
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ struct extensions* get_extensions_from_str(char* str) {
|
|||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = strlen(str);
|
int len = strlen(str)+1;
|
||||||
ext->str = ecalloc(len+1, sizeof(char));
|
ext->str = emalloc(len * sizeof(char));
|
||||||
strncpy(ext->str, str, sizeof(char) * len);
|
strncpy(ext->str, str, sizeof(char) * len);
|
||||||
|
|
||||||
// Code inspired in Linux kernel (riscv_fill_hwcap):
|
// Code inspired in Linux kernel (riscv_fill_hwcap):
|
||||||
@@ -157,13 +157,12 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
topo->cach = NULL;
|
topo->cach = NULL;
|
||||||
cpu->topo = topo;
|
cpu->topo = topo;
|
||||||
|
|
||||||
char* cpuinfo_str = get_uarch_from_cpuinfo();
|
|
||||||
char* ext_str = get_extensions_from_cpuinfo();
|
char* ext_str = get_extensions_from_cpuinfo();
|
||||||
cpu->hv = emalloc(sizeof(struct hypervisor));
|
cpu->hv = emalloc(sizeof(struct hypervisor));
|
||||||
cpu->hv->present = false;
|
cpu->hv->present = false;
|
||||||
cpu->ext = get_extensions_from_str(ext_str);
|
cpu->ext = get_extensions_from_str(ext_str);
|
||||||
if(cpu->ext->str != NULL && cpu->ext->mask == 0) return NULL;
|
if(cpu->ext->str != NULL && cpu->ext->mask == 0) return NULL;
|
||||||
cpu->arch = get_uarch_from_cpuinfo_str(cpuinfo_str, cpu);
|
cpu->arch = get_uarch(cpu);
|
||||||
cpu->soc = get_soc(cpu);
|
cpu->soc = get_soc(cpu);
|
||||||
cpu->freq = get_frequency_info(0);
|
cpu->freq = get_frequency_info(0);
|
||||||
cpu->peak_performance = get_peak_performance(cpu);
|
cpu->peak_performance = get_peak_performance(cpu);
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ bool match_sipeed(char* soc_name, struct system_on_chip* soc) {
|
|||||||
SOC_END
|
SOC_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool match_spacemit(char* soc_name, struct system_on_chip* soc) {
|
||||||
|
SOC_START
|
||||||
|
SOC_EQ(soc_name, "k1-x", "K1-X", SOC_SPACEMIT_K1X, soc, 22) // https://github.com/Dr-Noob/cpufetch/issues/286 https://www.spacemit.com/en/spacemit-x60-core/
|
||||||
|
SOC_END
|
||||||
|
}
|
||||||
|
|
||||||
struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) {
|
struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) {
|
||||||
char* raw_name = soc->raw_name;
|
char* raw_name = soc->raw_name;
|
||||||
|
|
||||||
@@ -50,6 +56,9 @@ struct system_on_chip* parse_soc_from_string(struct system_on_chip* soc) {
|
|||||||
if(match_sifive(raw_name, soc))
|
if(match_sifive(raw_name, soc))
|
||||||
return soc;
|
return soc;
|
||||||
|
|
||||||
|
if(match_spacemit(raw_name, soc))
|
||||||
|
return soc;
|
||||||
|
|
||||||
match_sipeed(raw_name, soc);
|
match_sipeed(raw_name, soc);
|
||||||
return soc;
|
return soc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ enum {
|
|||||||
SOC_ALLWINNER_D1H,
|
SOC_ALLWINNER_D1H,
|
||||||
// SIPEED
|
// SIPEED
|
||||||
SOC_SIPEED_LICHEEPI4A,
|
SOC_SIPEED_LICHEEPI4A,
|
||||||
|
// SPACEMIT
|
||||||
|
SOC_SPACEMIT_K1X,
|
||||||
// UNKNOWN
|
// UNKNOWN
|
||||||
SOC_MODEL_UNKNOWN
|
SOC_MODEL_UNKNOWN
|
||||||
};
|
};
|
||||||
@@ -22,6 +24,7 @@ inline static VENDOR get_soc_vendor_from_soc(SOC soc) {
|
|||||||
if(soc >= SOC_STARFIVE_VF2 && soc <= SOC_STARFIVE_VF2) return SOC_VENDOR_STARFIVE;
|
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;
|
if(soc >= SOC_ALLWINNER_D1H && soc <= SOC_ALLWINNER_D1H) return SOC_VENDOR_ALLWINNER;
|
||||||
if(soc >= SOC_SIPEED_LICHEEPI4A && soc <= SOC_SIPEED_LICHEEPI4A) return SOC_VENDOR_SIPEED;
|
if(soc >= SOC_SIPEED_LICHEEPI4A && soc <= SOC_SIPEED_LICHEEPI4A) return SOC_VENDOR_SIPEED;
|
||||||
|
if(soc >= SOC_SPACEMIT_K1X && soc <= SOC_SPACEMIT_K1X) return SOC_VENDOR_SPACEMIT;
|
||||||
return SOC_VENDOR_UNKNOWN;
|
return SOC_VENDOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "uarch.h"
|
#include "uarch.h"
|
||||||
|
#include "udev.h"
|
||||||
#include "../common/global.h"
|
#include "../common/global.h"
|
||||||
|
|
||||||
typedef uint32_t MICROARCH;
|
typedef uint32_t MICROARCH;
|
||||||
@@ -12,6 +13,7 @@ struct uarch {
|
|||||||
MICROARCH uarch;
|
MICROARCH uarch;
|
||||||
char* uarch_str;
|
char* uarch_str;
|
||||||
char* cpuinfo_str;
|
char* cpuinfo_str;
|
||||||
|
struct riscv_cpuinfo* ci;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -21,13 +23,20 @@ enum {
|
|||||||
UARCH_U74,
|
UARCH_U74,
|
||||||
// THEAD
|
// THEAD
|
||||||
UARCH_C906,
|
UARCH_C906,
|
||||||
UARCH_C910
|
UARCH_C910,
|
||||||
|
// SPACEMIT
|
||||||
|
UARCH_X60
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UARCH_START if (false) {}
|
#define UARCH_START if (false) {}
|
||||||
#define CHECK_UARCH(arch, cpu, cpuinfo_str, uarch_str, str, uarch, vendor) \
|
#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);
|
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); }
|
#define UARCH_END else { printWarn("Unknown microarchitecture detected: uarch='%s'", cpuinfo_str); fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN); }
|
||||||
|
|
||||||
|
#define ARCHID_START if (false) {}
|
||||||
|
#define CHECK_ARCHID(arch, marchid_val, str, uarch, vendor) \
|
||||||
|
else if (arch->ci->marchid == (unsigned long) marchid_val) fill_uarch(arch, cpu, str, uarch, vendor);
|
||||||
|
#define ARCHID_END else { printWarn("Unknown microarchitecture detected: marchid=0x%.8X", arch->ci->marchid); 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) {
|
void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u, VENDOR vendor) {
|
||||||
arch->uarch = u;
|
arch->uarch = u;
|
||||||
@@ -39,14 +48,8 @@ void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u,
|
|||||||
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
|
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
|
||||||
// SiFive: https://www.sifive.com/risc-v-core-ip
|
// SiFive: https://www.sifive.com/risc-v-core-ip
|
||||||
// T-Head: https://www.t-head.cn/product/c906
|
// T-Head: https://www.t-head.cn/product/c906
|
||||||
struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu) {
|
struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu, struct uarch* arch) {
|
||||||
struct uarch* arch = emalloc(sizeof(struct uarch));
|
|
||||||
arch->cpuinfo_str = cpuinfo_str;
|
arch->cpuinfo_str = cpuinfo_str;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U74/U74-MC:
|
// U74/U74-MC:
|
||||||
// SiFive says that U74-MC is "Multicore: four U74 cores and one S76 core" while
|
// SiFive says that U74-MC is "Multicore: four U74 cores and one S76 core" while
|
||||||
@@ -70,6 +73,41 @@ struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu)
|
|||||||
return arch;
|
return arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use marchid to get the microarchitecture
|
||||||
|
struct uarch* get_uarch_from_riscv_cpuinfo(struct cpuInfo* cpu, struct uarch* arch) {
|
||||||
|
|
||||||
|
ARCHID_START
|
||||||
|
CHECK_ARCHID(arch, 0x8000000058000001, "X60", UARCH_X60, CPU_VENDOR_SPACEMIT) // https://github.com/Dr-Noob/cpufetch/issues/286
|
||||||
|
ARCHID_END
|
||||||
|
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct uarch* get_uarch(struct cpuInfo* cpu) {
|
||||||
|
char* cpuinfo_str = get_uarch_from_cpuinfo();
|
||||||
|
struct uarch* arch = emalloc(sizeof(struct uarch));
|
||||||
|
arch->uarch = UARCH_UNKNOWN;
|
||||||
|
arch->ci = NULL;
|
||||||
|
|
||||||
|
if (cpuinfo_str == NULL) {
|
||||||
|
printWarn("get_uarch_from_cpuinfo: Unable to detect microarchitecture using uarch: cpuinfo_str is NULL");
|
||||||
|
arch->ci = get_riscv_cpuinfo();
|
||||||
|
|
||||||
|
if (arch->ci == NULL || arch->ci->marchid == 0)
|
||||||
|
printWarn("get_riscv_cpuinfo: Unable to get marchid from udev");
|
||||||
|
else
|
||||||
|
arch = get_uarch_from_riscv_cpuinfo(cpu, arch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arch = get_uarch_from_cpuinfo_str(cpuinfo_str, cpu, arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arch->uarch == UARCH_UNKNOWN)
|
||||||
|
fill_uarch(arch, cpu, "Unknown", UARCH_UNKNOWN, CPU_VENDOR_UNKNOWN);
|
||||||
|
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
char* get_str_uarch(struct cpuInfo* cpu) {
|
char* get_str_uarch(struct cpuInfo* cpu) {
|
||||||
return cpu->arch->uarch_str;
|
return cpu->arch->uarch_str;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ struct uarch;
|
|||||||
char* get_arch_cpuinfo_str(struct cpuInfo* cpu);
|
char* get_arch_cpuinfo_str(struct cpuInfo* cpu);
|
||||||
char* get_str_uarch(struct cpuInfo* cpu);
|
char* get_str_uarch(struct cpuInfo* cpu);
|
||||||
void free_uarch_struct(struct uarch* arch);
|
void free_uarch_struct(struct uarch* arch);
|
||||||
struct uarch* get_uarch_from_cpuinfo_str(char* cpuinfo_str, struct cpuInfo* cpu);
|
struct uarch* get_uarch(struct cpuInfo* cpu);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
#define _PATH_DEVTREE "/proc/device-tree/compatible"
|
#define _PATH_DEVTREE "/proc/device-tree/compatible"
|
||||||
#define CPUINFO_UARCH_STR "uarch\t\t: "
|
#define CPUINFO_UARCH_STR "uarch\t\t: "
|
||||||
#define CPUINFO_EXTENSIONS_STR "isa\t\t: "
|
#define CPUINFO_EXTENSIONS_STR "isa\t\t: "
|
||||||
|
#define CPUINFO_RISCV_MVENDORID "mvendorid\t:"
|
||||||
|
#define CPUINFO_RISCV_MARCHID "marchid\t\t:"
|
||||||
|
#define CPUINFO_RISCV_MIMPID "mimpid\t\t:"
|
||||||
#define DEVTREE_HARDWARE_FIELD 0
|
#define DEVTREE_HARDWARE_FIELD 0
|
||||||
|
|
||||||
char* get_field_from_devtree(int DEVTREE_FIELD) {
|
char* get_field_from_devtree(int DEVTREE_FIELD) {
|
||||||
@@ -75,6 +78,52 @@ char* parse_cpuinfo_field(char* field_str) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long parse_cpuinfo_field_uint64(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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* tmp = strstr(buf, field_str);
|
||||||
|
if(tmp == NULL) return 0;
|
||||||
|
tmp += strlen(field_str);
|
||||||
|
|
||||||
|
char* end;
|
||||||
|
errno = 0;
|
||||||
|
unsigned long ret = strtoul(tmp, &end, 16);
|
||||||
|
if (errno != 0) {
|
||||||
|
printWarn("strtoul: %s: %s", strerror(errno), tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates and fills in the riscv_cpuinfo struct (which contains
|
||||||
|
// mvendorid, marchid and mimpid) using cpuinfo to fetch the values.
|
||||||
|
//
|
||||||
|
// Every RISC-V hart (hardware thread) [1] provides a
|
||||||
|
// marchid (Machine Architecture ID register) CSR that encodes its
|
||||||
|
// base microarchitecture [2]. For more information about
|
||||||
|
// marchid and the rest of values, see [3].
|
||||||
|
// [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/QKjUDjz_vKo
|
||||||
|
// [2] https://github.com/riscv/riscv-isa-manual/blob/main/marchid.md
|
||||||
|
// [3] https://five-embeddev.com/riscv-priv-isa-manual/Priv-v1.12/machine.html#machine-architecture-id-register-marchid
|
||||||
|
struct riscv_cpuinfo *get_riscv_cpuinfo(void) {
|
||||||
|
struct riscv_cpuinfo* ci = emalloc(sizeof(struct riscv_cpuinfo));
|
||||||
|
|
||||||
|
ci->mvendorid = parse_cpuinfo_field_uint64(CPUINFO_RISCV_MVENDORID);
|
||||||
|
ci->marchid = parse_cpuinfo_field_uint64(CPUINFO_RISCV_MARCHID);
|
||||||
|
ci->mimpid = parse_cpuinfo_field_uint64(CPUINFO_RISCV_MIMPID);
|
||||||
|
|
||||||
|
if (ci->mvendorid == 0 && ci->mvendorid == 0 && ci->mvendorid == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
char* get_hardware_from_devtree(void) {
|
char* get_hardware_from_devtree(void) {
|
||||||
return get_field_from_devtree(DEVTREE_HARDWARE_FIELD);
|
return get_field_from_devtree(DEVTREE_HARDWARE_FIELD);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,16 @@
|
|||||||
|
|
||||||
#define UNKNOWN -1
|
#define UNKNOWN -1
|
||||||
|
|
||||||
|
// https://elixir.bootlin.com/linux/v6.10.6/source/arch/riscv/include/asm/cpufeature.h#L21
|
||||||
|
struct riscv_cpuinfo {
|
||||||
|
unsigned long mvendorid;
|
||||||
|
unsigned long marchid;
|
||||||
|
unsigned long mimpid;
|
||||||
|
};
|
||||||
|
|
||||||
char* get_hardware_from_devtree(void);
|
char* get_hardware_from_devtree(void);
|
||||||
char* get_uarch_from_cpuinfo(void);
|
char* get_uarch_from_cpuinfo(void);
|
||||||
char* get_extensions_from_cpuinfo(void);
|
char* get_extensions_from_cpuinfo(void);
|
||||||
|
struct riscv_cpuinfo *get_riscv_cpuinfo(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user