diff --git a/src/arm/midr.c b/src/arm/midr.c index 16a2e08..e62fb0d 100644 --- a/src/arm/midr.c +++ b/src/arm/midr.c @@ -10,6 +10,12 @@ #include #elif defined __APPLE__ || __MACH__ #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 #include "../common/global.h" @@ -171,12 +177,18 @@ struct features* get_features_info() { } #endif // ifdef __aarch64__ #elif defined __APPLE__ || __MACH__ + // Must be M1 + feat->AES = true; + feat->CRC32 = true; + feat->SHA1 = true; + feat->SHA2 = true; + feat->NEON = true; #endif 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(); bool success = false; int32_t* freq_array = malloc(sizeof(uint32_t) * ncores); @@ -225,24 +237,62 @@ void get_cpu_info_linux(struct cpuInfo* cpu) { cpu->num_cpus = sockets; cpu->hv = malloc(sizeof(struct hypervisor)); cpu->hv->present = false; - cpu->soc = get_soc(); + cpu->soc = get_soc(); + + return cpu; } -void get_cpu_info_mach(struct cpuInfo* cpu) { - cpu->midr = 0; - cpu->arch = get_uarch_from_midr(cpu->midr, cpu); +void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu) { + // 1. Fill ICESTORM + struct cpuInfo* ice = cpu; - cpu->cach = get_cache_info(cpu); - cpu->feat = get_features_info(); - cpu->topo = get_topology_from_sysctl(); - cpu->freq = malloc(sizeof(struct frequency)); - cpu->freq->base = UNKNOWN_FREQ; - cpu->freq->max = 1000000000; + ice->midr = MIDR_APPLE_M1_ICESTORM; + ice->arch = get_uarch_from_midr(ice->midr, ice); + ice->cach = get_cache_info(ice); + ice->feat = get_features_info(); + ice->topo = malloc(sizeof(struct topology)); + 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; - cpu->hv = malloc(sizeof(struct hypervisor)); - cpu->hv->present = false; - cpu->soc = get_soc(); + // 2. Fill FIRESTORM + struct cpuInfo* fire = ice->next_cpu; + 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(); + 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() { @@ -250,12 +300,10 @@ struct cpuInfo* get_cpu_info() { init_cpu_info(cpu); #ifdef __linux__ - get_cpu_info_linux(cpu); + return get_cpu_info_linux(cpu); #elif defined __APPLE__ || __MACH__ - get_cpu_info_mach(cpu); + return get_cpu_info_mach(cpu); #endif - - return cpu; } char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) { diff --git a/src/arm/sysctl.c b/src/arm/sysctl.c index 94f4a3f..8ee401e 100644 --- a/src/arm/sysctl.c +++ b/src/arm/sysctl.c @@ -7,19 +7,19 @@ #include "../common/global.h" #include "../common/cpu.h" -struct topology* get_topology_from_sysctl() { - struct topology* t = malloc(sizeof(struct topology)); - size_t dummy; +uint32_t get_sys_info_by_name(char* name) { + size_t size = 0; + uint32_t ret = 0; - if(sysctlbyname("hw.physicalcpu_max", &t->total_cores, &dummy, NULL, 0) != 0) { - printWarn("sysctlbyname(\"hw.physicalcpu_max\") failed: %s\n", strerror(errno)); - t->total_cores = 1; + if (sysctlbyname(name, NULL, &size, NULL, 0) != 0) { + printWarn("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); } - else if(t->total_cores <= 0) { - printWarn("sysctlbyname(\"hw.physicalcpu_max\") returned invalid value: %d\n", t->total_cores); - t->total_cores = 1; + else if (size == sizeof(uint32_t)) { + sysctlbyname(name, &ret, &size, NULL, 0); + } + else { + printWarn("sysctl does not support non-integer lookup for (\"%s\")", name); } - return t; + return ret; } - diff --git a/src/arm/sysctl.h b/src/arm/sysctl.h index 8d4bade..1140aec 100644 --- a/src/arm/sysctl.h +++ b/src/arm/sysctl.h @@ -1,6 +1,6 @@ #ifndef __SYSCTL__ #define __SYSCTL__ -struct topology* get_topology_from_sysctl(); +uint32_t get_sys_info_by_name(char* name); #endif diff --git a/src/arm/uarch.c b/src/arm/uarch.c index 5082137..59b043d 100644 --- a/src/arm/uarch.c +++ b/src/arm/uarch.c @@ -34,6 +34,7 @@ enum { ISA_ARMv8_1_A, ISA_ARMv8_2_A, ISA_ARMv8_3_A, + ISA_ARMv8_4_A, }; enum { @@ -93,6 +94,8 @@ enum { UARCH_TEMPEST, // Apple A12 processor (big cores). UARCH_LIGHTNING, // Apple A13 processor (big cores). UARCH_THUNDER, // Apple A13 processor (little cores). + UARCH_ICESTORM, // Apple M1 processor (little cores). + UARCH_FIRESTORM, // Apple M1 processor (big cores). // CAVIUM UARCH_THUNDERX, // Cavium ThunderX UARCH_THUNDERX2, // Cavium ThunderX2 (originally Broadcom Vulkan). @@ -150,6 +153,8 @@ static const ISA isas_uarch[] = { [UARCH_EXYNOS_M3] = ISA_ARMv8_A, [UARCH_EXYNOS_M4] = 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, }; @@ -164,6 +169,7 @@ static char* isas_string[] = { [ISA_ARMv8_1_A] = "ARMv8.1", [ISA_ARMv8_2_A] = "ARMv8.2", [ISA_ARMv8_3_A] = "ARMv8.3", + [ISA_ARMv8_4_A] = "ARMv8.4" }; #define UARCH_START if (false) {} @@ -281,7 +287,10 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) { CHECK_UARCH(arch, cpu, 'S', 0x002, 1, NA, "Exynos M3", UARCH_EXYNOS_M3, CPU_VENDOR_SAMSUNG) // Exynos 9810 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, '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', 0x584, NA, NA, "PJ4B-MP", UARCH_PJ4, CPU_VENDOR_MARVELL) diff --git a/src/common/cpu.h b/src/common/cpu.h index bd61f8c..f422202 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -10,6 +10,7 @@ enum { CPU_VENDOR_AMD, // ARCH_ARM CPU_VENDOR_ARM, + CPU_VENDOR_APPLE, CPU_VENDOR_BROADCOM, CPU_VENDOR_CAVIUM, CPU_VENDOR_NVIDIA,