Skip to content

Commit 0ea0754

Browse files
committed
[v1.01] Experimental M1 chip detection using hw.cpusubfamily
1 parent 316c2de commit 0ea0754

File tree

4 files changed

+69
-13
lines changed

4 files changed

+69
-13
lines changed

src/arm/midr.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@
1010
#include <asm/hwcap.h>
1111
#elif defined __APPLE__ || __MACH__
1212
#include "sysctl.h"
13-
// From Linux kernel: arch/arm64/include/asm/cputype.h
14-
#define MIDR_APPLE_M1_ICESTORM 0x610F0220
15-
#define MIDR_APPLE_M1_FIRESTORM 0x610F0230
16-
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
17-
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
18-
#endif
1913
#endif
2014

2115
#include "../common/global.h"
@@ -244,7 +238,7 @@ struct cpuInfo* get_cpu_info_linux(struct cpuInfo* cpu) {
244238
}
245239

246240
#elif defined __APPLE__ || __MACH__
247-
void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu) {
241+
void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu, uint32_t pcores, uint32_t ecores) {
248242
// 1. Fill ICESTORM
249243
struct cpuInfo* ice = cpu;
250244

@@ -254,7 +248,7 @@ void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu) {
254248
ice->feat = get_features_info();
255249
ice->topo = malloc(sizeof(struct topology));
256250
ice->topo->cach = ice->cach;
257-
ice->topo->total_cores = 4;
251+
ice->topo->total_cores = ecores;
258252
ice->freq = malloc(sizeof(struct frequency));
259253
ice->freq->base = UNKNOWN_DATA;
260254
ice->freq->max = 2064;
@@ -270,7 +264,7 @@ void fill_cpu_info_firestorm_icestorm(struct cpuInfo* cpu) {
270264
fire->feat = get_features_info();
271265
fire->topo = malloc(sizeof(struct topology));
272266
fire->topo->cach = fire->cach;
273-
fire->topo->total_cores = 4;
267+
fire->topo->total_cores = pcores;
274268
fire->freq = malloc(sizeof(struct frequency));
275269
fire->freq->base = UNKNOWN_DATA;
276270
fire->freq->max = 3200;
@@ -286,8 +280,26 @@ struct cpuInfo* get_cpu_info_mach(struct cpuInfo* cpu) {
286280
// is a ARM_FIRESTORM_ICESTORM (Apple M1)
287281
if(cpu_family == CPUFAMILY_ARM_FIRESTORM_ICESTORM) {
288282
cpu->num_cpus = 2;
283+
// Now detect the M1 version
284+
uint32_t cpu_subfamily = get_sys_info_by_name("hw.cpusubfamily");
285+
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
286+
// Apple M1
287+
fill_cpu_info_firestorm_icestorm(cpu, 4, 4);
288+
}
289+
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS || cpu_subfamily == CPUSUBFAMILY_ARM_HC_HD) {
290+
// Apple M1 Pro/Max. Detect number of cores
291+
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
292+
if(physicalcpu < 8 || physicalcpu > 10) {
293+
printBug("Found invalid physicalcpu: 0x%.8X", physicalcpu);
294+
return NULL;
295+
}
296+
fill_cpu_info_firestorm_icestorm(cpu, physicalcpu-2, 2);
297+
}
298+
else {
299+
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
300+
return NULL;
301+
}
289302
cpu->soc = get_soc();
290-
fill_cpu_info_firestorm_icestorm(cpu);
291303
cpu->peak_performance = get_peak_performance(cpu);
292304
}
293305
else {

src/arm/soc.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#include "udev.h"
99
#include "../common/global.h"
1010

11+
#if defined(__APPLE__) || defined(__MACH__)
12+
#include "sysctl.h"
13+
#endif
14+
1115
#define min(a,b) (((a)<(b))?(a):(b))
1216
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
1317

@@ -642,6 +646,22 @@ struct system_on_chip* guess_soc_raspbery_pi(struct system_on_chip* soc) {
642646
return soc;
643647
}
644648

649+
#if defined(__APPLE__) || defined(__MACH__)
650+
struct system_on_chip* guess_soc_apple(struct system_on_chip* soc) {
651+
uint32_t cpu_subfamily = get_sys_info_by_name("hw.cpusubfamily");
652+
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
653+
fill_soc(soc, "M1", SOC_APPLE_M1, 5);
654+
}
655+
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS) {
656+
fill_soc(soc, "M1 Pro", SOC_APPLE_M1_PRO, 5);
657+
}
658+
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HC_HD) {
659+
fill_soc(soc, "M1 Max", SOC_APPLE_M1_MAX, 5);
660+
}
661+
return soc;
662+
}
663+
#endif
664+
645665
struct system_on_chip* get_soc() {
646666
struct system_on_chip* soc = emalloc(sizeof(struct system_on_chip));
647667
soc->raw_name = NULL;
@@ -675,7 +695,13 @@ struct system_on_chip* get_soc() {
675695
#endif // ifdef __ANDROID__
676696
}
677697
#elif defined __APPLE__ || __MACH__
678-
fill_soc(soc, "M1", SOC_APPLE_M1, 5);
698+
soc = guess_soc_apple(soc);
699+
if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) {
700+
printWarn("SoC detection failed using cpu_subfamily");
701+
}
702+
else {
703+
return soc;
704+
}
679705
#endif // ifdef __linux__
680706

681707
if(soc->raw_name == NULL) {

src/arm/socs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ enum {
254254
SOC_SNAPD_SM8350,
255255
// APPLE
256256
SOC_APPLE_M1,
257+
SOC_APPLE_M1_PRO,
258+
SOC_APPLE_M1_MAX,
257259
// ALLWINNER
258260
SOC_ALLWINNER_A10,
259261
SOC_ALLWINNER_A13,
@@ -286,9 +288,9 @@ inline static VENDOR get_soc_vendor_from_soc(SOC soc) {
286288
else if(soc >= SOC_EXYNOS_3475 && soc <= SOC_EXYNOS_880) return SOC_VENDOR_EXYNOS;
287289
else if(soc >= SOC_MTK_MT6893 && soc <= SOC_MTK_MT8783) return SOC_VENDOR_MEDIATEK;
288290
else if(soc >= SOC_SNAPD_QSD8650 && soc <= SOC_SNAPD_SM8350) return SOC_VENDOR_SNAPDRAGON;
289-
else if(soc >= SOC_APPLE_M1 && soc <= SOC_APPLE_M1) return SOC_VENDOR_APPLE;
291+
else if(soc >= SOC_APPLE_M1 && soc <= SOC_APPLE_M1_MAX) return SOC_VENDOR_APPLE;
290292
else if(soc >= SOC_ALLWINNER_A10 && soc <= SOC_ALLWINNER_R328) return SOC_VENDOR_ALLWINNER;
291-
return SOC_VENDOR_UNKNOWN;
293+
return SOC_VENDOR_UNKNOWN;
292294
}
293295

294296
#endif

src/arm/sysctl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
#ifndef __SYSCTL__
22
#define __SYSCTL__
33

4+
// From Linux kernel: arch/arm64/include/asm/cputype.h
5+
#define MIDR_APPLE_M1_ICESTORM 0x610F0220
6+
#define MIDR_APPLE_M1_FIRESTORM 0x610F0230
7+
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
8+
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
9+
#endif
10+
#ifndef CPUSUBFAMILY_ARM_HG
11+
#define CPUSUBFAMILY_ARM_HG 2
12+
#endif
13+
#ifndef CPUSUBFAMILY_ARM_HS
14+
#define CPUSUBFAMILY_ARM_HS 4
15+
#endif
16+
#ifndef CPUSUBFAMILY_ARM_HC_HD
17+
#define CPUSUBFAMILY_ARM_HC_HD 5
18+
#endif
19+
420
uint32_t get_sys_info_by_name(char* name);
521

622
#endif

0 commit comments

Comments
 (0)