[v0.98][ARM] Detect fire/icestorm CPUs and manually fill most of the fields

This commit is contained in:
Dr-Noob
2021-08-02 15:56:24 +01:00
parent e350f1759f
commit d2dc2046de
5 changed files with 90 additions and 32 deletions

View File

@@ -10,6 +10,12 @@
#include <asm/hwcap.h> #include <asm/hwcap.h>
#elif defined __APPLE__ || __MACH__ #elif defined __APPLE__ || __MACH__
#include "sysctl.h" #include "sysctl.h"
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
// From arch/arm64/include/asm/cputype.h
#define MIDR_APPLE_M1_ICESTORM 0x610F0220
#define MIDR_APPLE_M1_FIRESTORM 0x610F0230
#endif
#endif #endif
#include "../common/global.h" #include "../common/global.h"
@@ -171,12 +177,18 @@ struct features* get_features_info() {
} }
#endif // ifdef __aarch64__ #endif // ifdef __aarch64__
#elif defined __APPLE__ || __MACH__ #elif defined __APPLE__ || __MACH__
// Must be M1
feat->AES = true;
feat->CRC32 = true;
feat->SHA1 = true;
feat->SHA2 = true;
feat->NEON = true;
#endif #endif
return feat; return feat;
} }
void get_cpu_info_linux(struct cpuInfo* cpu) { struct cpuInfo* get_cpu_info_linux(struct cpuInfo* cpu) {
int ncores = get_ncores_from_cpuinfo(); int ncores = get_ncores_from_cpuinfo();
bool success = false; bool success = false;
int32_t* freq_array = malloc(sizeof(uint32_t) * ncores); int32_t* freq_array = malloc(sizeof(uint32_t) * ncores);
@@ -226,23 +238,61 @@ void get_cpu_info_linux(struct cpuInfo* cpu) {
cpu->hv = malloc(sizeof(struct hypervisor)); cpu->hv = malloc(sizeof(struct hypervisor));
cpu->hv->present = false; cpu->hv->present = false;
cpu->soc = get_soc(); cpu->soc = get_soc();
return cpu;
} }
void get_cpu_info_mach(struct cpuInfo* cpu) { void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu) {
cpu->midr = 0; // 1. Fill ICESTORM
cpu->arch = get_uarch_from_midr(cpu->midr, cpu); struct cpuInfo* ice = cpu;
cpu->cach = get_cache_info(cpu); ice->midr = MIDR_APPLE_M1_ICESTORM;
cpu->feat = get_features_info(); ice->arch = get_uarch_from_midr(ice->midr, ice);
cpu->topo = get_topology_from_sysctl(); ice->cach = get_cache_info(ice);
cpu->freq = malloc(sizeof(struct frequency)); ice->feat = get_features_info();
cpu->freq->base = UNKNOWN_FREQ; ice->topo = malloc(sizeof(struct topology));
cpu->freq->max = 1000000000; ice->topo->cach = ice->cach;
ice->topo->total_cores = 4;
ice->freq = malloc(sizeof(struct frequency));
ice->freq->base = UNKNOWN_FREQ;
ice->freq->max = 2064;
ice->hv = malloc(sizeof(struct hypervisor));
ice->hv->present = false;
ice->next_cpu = malloc(sizeof(struct cpuInfo));
cpu->num_cpus = 1; // 2. Fill FIRESTORM
cpu->hv = malloc(sizeof(struct hypervisor)); struct cpuInfo* fire = ice->next_cpu;
cpu->hv->present = false; fire->midr = MIDR_APPLE_M1_FIRESTORM;
fire->arch = get_uarch_from_midr(fire->midr, fire);
fire->cach = get_cache_info(fire);
fire->feat = get_features_info();
fire->topo = malloc(sizeof(struct topology));
fire->topo->cach = fire->cach;
fire->topo->total_cores = 4;
fire->freq = malloc(sizeof(struct frequency));
fire->freq->base = UNKNOWN_FREQ;
fire->freq->max = 3200;
fire->hv = malloc(sizeof(struct hypervisor));
fire->hv->present = false;
fire->next_cpu = NULL;
}
struct cpuInfo* get_cpu_info_mach(struct cpuInfo* cpu) {
uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
// Manually fill the cpuInfo assuming that the CPU
// is a ARM_FIRESTORM_ICESTORM (Apple M1)
if(cpu_family == CPUFAMILY_ARM_FIRESTORM_ICESTORM) {
cpu->num_cpus = 2;
cpu->soc = get_soc(); cpu->soc = get_soc();
fill_cpu_info_firestorm_icestorm(cpu);
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
return NULL;
}
return cpu;
} }
struct cpuInfo* get_cpu_info() { struct cpuInfo* get_cpu_info() {
@@ -250,12 +300,10 @@ struct cpuInfo* get_cpu_info() {
init_cpu_info(cpu); init_cpu_info(cpu);
#ifdef __linux__ #ifdef __linux__
get_cpu_info_linux(cpu); return get_cpu_info_linux(cpu);
#elif defined __APPLE__ || __MACH__ #elif defined __APPLE__ || __MACH__
get_cpu_info_mach(cpu); return get_cpu_info_mach(cpu);
#endif #endif
return cpu;
} }
char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) { char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) {

View File

@@ -7,19 +7,19 @@
#include "../common/global.h" #include "../common/global.h"
#include "../common/cpu.h" #include "../common/cpu.h"
struct topology* get_topology_from_sysctl() { uint32_t get_sys_info_by_name(char* name) {
struct topology* t = malloc(sizeof(struct topology)); size_t size = 0;
size_t dummy; uint32_t ret = 0;
if(sysctlbyname("hw.physicalcpu_max", &t->total_cores, &dummy, NULL, 0) != 0) { if (sysctlbyname(name, NULL, &size, NULL, 0) != 0) {
printWarn("sysctlbyname(\"hw.physicalcpu_max\") failed: %s\n", strerror(errno)); printWarn("sysctlbyname(\"%s\") failed: %s", name, strerror(errno));
t->total_cores = 1;
} }
else if(t->total_cores <= 0) { else if (size == sizeof(uint32_t)) {
printWarn("sysctlbyname(\"hw.physicalcpu_max\") returned invalid value: %d\n", t->total_cores); sysctlbyname(name, &ret, &size, NULL, 0);
t->total_cores = 1; }
else {
printWarn("sysctl does not support non-integer lookup for (\"%s\")", name);
} }
return t; return ret;
} }

View File

@@ -1,6 +1,6 @@
#ifndef __SYSCTL__ #ifndef __SYSCTL__
#define __SYSCTL__ #define __SYSCTL__
struct topology* get_topology_from_sysctl(); uint32_t get_sys_info_by_name(char* name);
#endif #endif

View File

@@ -34,6 +34,7 @@ enum {
ISA_ARMv8_1_A, ISA_ARMv8_1_A,
ISA_ARMv8_2_A, ISA_ARMv8_2_A,
ISA_ARMv8_3_A, ISA_ARMv8_3_A,
ISA_ARMv8_4_A,
}; };
enum { enum {
@@ -93,6 +94,8 @@ enum {
UARCH_TEMPEST, // Apple A12 processor (big cores). UARCH_TEMPEST, // Apple A12 processor (big cores).
UARCH_LIGHTNING, // Apple A13 processor (big cores). UARCH_LIGHTNING, // Apple A13 processor (big cores).
UARCH_THUNDER, // Apple A13 processor (little cores). UARCH_THUNDER, // Apple A13 processor (little cores).
UARCH_ICESTORM, // Apple M1 processor (little cores).
UARCH_FIRESTORM, // Apple M1 processor (big cores).
// CAVIUM // CAVIUM
UARCH_THUNDERX, // Cavium ThunderX UARCH_THUNDERX, // Cavium ThunderX
UARCH_THUNDERX2, // Cavium ThunderX2 (originally Broadcom Vulkan). UARCH_THUNDERX2, // Cavium ThunderX2 (originally Broadcom Vulkan).
@@ -150,6 +153,8 @@ static const ISA isas_uarch[] = {
[UARCH_EXYNOS_M3] = ISA_ARMv8_A, [UARCH_EXYNOS_M3] = ISA_ARMv8_A,
[UARCH_EXYNOS_M4] = ISA_ARMv8_2_A, [UARCH_EXYNOS_M4] = ISA_ARMv8_2_A,
[UARCH_EXYNOS_M5] = ISA_ARMv8_2_A, [UARCH_EXYNOS_M5] = ISA_ARMv8_2_A,
[UARCH_ICESTORM] = ISA_ARMv8_4_A,
[UARCH_FIRESTORM] = ISA_ARMv8_4_A,
[UARCH_PJ4] = ISA_ARMv7_A, [UARCH_PJ4] = ISA_ARMv7_A,
}; };
@@ -164,6 +169,7 @@ static char* isas_string[] = {
[ISA_ARMv8_1_A] = "ARMv8.1", [ISA_ARMv8_1_A] = "ARMv8.1",
[ISA_ARMv8_2_A] = "ARMv8.2", [ISA_ARMv8_2_A] = "ARMv8.2",
[ISA_ARMv8_3_A] = "ARMv8.3", [ISA_ARMv8_3_A] = "ARMv8.3",
[ISA_ARMv8_4_A] = "ARMv8.4"
}; };
#define UARCH_START if (false) {} #define UARCH_START if (false) {}
@@ -282,6 +288,9 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
CHECK_UARCH(arch, cpu, 'S', 0x003, 1, NA, "Exynos M4", UARCH_EXYNOS_M4, CPU_VENDOR_SAMSUNG) // Exynos 9820 CHECK_UARCH(arch, cpu, 'S', 0x003, 1, NA, "Exynos M4", UARCH_EXYNOS_M4, CPU_VENDOR_SAMSUNG) // Exynos 9820
CHECK_UARCH(arch, cpu, 'S', 0x004, 1, NA, "Exynos M5", UARCH_EXYNOS_M5, CPU_VENDOR_SAMSUNG) // Exynos 9820 (this one looks wrong at uarch.c ...) CHECK_UARCH(arch, cpu, 'S', 0x004, 1, NA, "Exynos M5", UARCH_EXYNOS_M5, CPU_VENDOR_SAMSUNG) // Exynos 9820 (this one looks wrong at uarch.c ...)
CHECK_UARCH(arch, cpu, 'a', 0x022, NA, NA, "Icestorm", UARCH_ICESTORM, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'a', 0x023, NA, NA, "Firestorm", UARCH_FIRESTORM, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'V', 0x581, NA, NA, "PJ4", UARCH_PJ4, CPU_VENDOR_MARVELL) CHECK_UARCH(arch, cpu, 'V', 0x581, NA, NA, "PJ4", UARCH_PJ4, CPU_VENDOR_MARVELL)
CHECK_UARCH(arch, cpu, 'V', 0x584, NA, NA, "PJ4B-MP", UARCH_PJ4, CPU_VENDOR_MARVELL) CHECK_UARCH(arch, cpu, 'V', 0x584, NA, NA, "PJ4B-MP", UARCH_PJ4, CPU_VENDOR_MARVELL)

View File

@@ -10,6 +10,7 @@ enum {
CPU_VENDOR_AMD, CPU_VENDOR_AMD,
// ARCH_ARM // ARCH_ARM
CPU_VENDOR_ARM, CPU_VENDOR_ARM,
CPU_VENDOR_APPLE,
CPU_VENDOR_BROADCOM, CPU_VENDOR_BROADCOM,
CPU_VENDOR_CAVIUM, CPU_VENDOR_CAVIUM,
CPU_VENDOR_NVIDIA, CPU_VENDOR_NVIDIA,