[v1.03][RISCV] Add preeliminary uarch detection

This commit is contained in:
Dr-Noob
2023-04-07 16:19:43 +02:00
parent 69dd47bab0
commit 13e86d7f14
6 changed files with 88 additions and 7 deletions

View File

@@ -22,6 +22,7 @@ enum {
CPU_VENDOR_PHYTIUM, CPU_VENDOR_PHYTIUM,
// ARCH_RISCV // ARCH_RISCV
CPU_VENDOR_RISCV, CPU_VENDOR_RISCV,
CPU_VENDOR_SIFIVE,
// OTHERS // OTHERS
CPU_VENDOR_UNKNOWN, CPU_VENDOR_UNKNOWN,
CPU_VENDOR_INVALID CPU_VENDOR_INVALID

View File

@@ -5,6 +5,8 @@
#include "../common/global.h" #include "../common/global.h"
#include "../common/udev.h" #include "../common/udev.h"
#include "udev.h"
#include "uarch.h"
#include "soc.h" #include "soc.h"
struct frequency* get_frequency_info(uint32_t core) { struct frequency* get_frequency_info(uint32_t core) {
@@ -34,8 +36,10 @@ 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();
cpu->hv = emalloc(sizeof(struct hypervisor)); cpu->hv = emalloc(sizeof(struct hypervisor));
cpu->hv->present = false; cpu->hv->present = false;
cpu->arch = get_uarch_from_cpuinfo_str(cpuinfo_str, cpu);
cpu->soc = get_soc(); cpu->soc = get_soc();
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);

View File

@@ -1,18 +1,56 @@
#include <stdint.h> #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uarch.h" #include "uarch.h"
#include "../common/global.h" #include "../common/global.h"
typedef uint32_t MICROARCH;
struct uarch { struct uarch {
//MICROARCH uarch; MICROARCH uarch;
char* uarch_str; 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) { char* get_str_uarch(struct cpuInfo* cpu) {
return "Unknown"; return cpu->arch->uarch_str;
} }
void free_uarch_struct(struct uarch* arch) { void free_uarch_struct(struct uarch* arch) {
free(arch->uarch_str);
free(arch);
} }

View File

@@ -8,5 +8,6 @@ struct uarch;
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);
#endif #endif

View File

@@ -4,7 +4,9 @@
#include "../common/global.h" #include "../common/global.h"
#include "udev.h" #include "udev.h"
#define _PATH_CPUINFO "/proc/cpuinfo"
#define _PATH_DEVTREE "/proc/device-tree/compatible" #define _PATH_DEVTREE "/proc/device-tree/compatible"
#define CPUINFO_UARCH_STR "uarch\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) {
@@ -45,6 +47,40 @@ char* get_field_from_devtree(int DEVTREE_FIELD) {
return hardware; 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) { char* get_hardware_from_devtree(void) {
return get_field_from_devtree(DEVTREE_HARDWARE_FIELD); return get_field_from_devtree(DEVTREE_HARDWARE_FIELD);
} }
char* get_uarch_from_cpuinfo(void) {
return parse_cpuinfo_field(CPUINFO_UARCH_STR);
}

View File

@@ -6,5 +6,6 @@
#define UNKNOWN -1 #define UNKNOWN -1
char* get_hardware_from_devtree(void); char* get_hardware_from_devtree(void);
char* get_uarch_from_cpuinfo(void);
#endif #endif