[v1.04][ARM] Preeliminary M3 support

This commit is contained in:
Dr-Noob
2023-12-22 23:23:42 +01:00
parent 2feee25659
commit 6ae51f2b52
5 changed files with 105 additions and 0 deletions

View File

@@ -314,6 +314,41 @@ void fill_cpu_info_avalanche_blizzard(struct cpuInfo* cpu, uint32_t pcores, uint
ava->next_cpu = NULL;
}
void fill_cpu_info_everest_sawtooth(struct cpuInfo* cpu, uint32_t pcores, uint32_t ecores) {
// 1. Fill SAWTOOTH
struct cpuInfo* saw = cpu;
saw->midr = MIDR_APPLE_M3_SAWTOOTH;
saw->arch = get_uarch_from_midr(saw->midr, saw);
saw->cach = get_cache_info(saw);
saw->feat = get_features_info();
saw->topo = malloc(sizeof(struct topology));
saw->topo->cach = saw->cach;
saw->topo->total_cores = pcores;
saw->freq = malloc(sizeof(struct frequency));
saw->freq->base = UNKNOWN_DATA;
saw->freq->max = 2750;
saw->hv = malloc(sizeof(struct hypervisor));
saw->hv->present = false;
saw->next_cpu = malloc(sizeof(struct cpuInfo));
// 2. Fill EVEREST
struct cpuInfo* eve = saw->next_cpu;
eve->midr = MIDR_APPLE_M3_EVEREST;
eve->arch = get_uarch_from_midr(eve->midr, eve);
eve->cach = get_cache_info(eve);
eve->feat = get_features_info();
eve->topo = malloc(sizeof(struct topology));
eve->topo->cach = eve->cach;
eve->topo->total_cores = ecores;
eve->freq = malloc(sizeof(struct frequency));
eve->freq->base = UNKNOWN_DATA;
eve->freq->max = 4050;
eve->hv = malloc(sizeof(struct hypervisor));
eve->hv->present = false;
eve->next_cpu = NULL;
}
struct cpuInfo* get_cpu_info_mach(struct cpuInfo* cpu) {
uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
@@ -381,6 +416,37 @@ struct cpuInfo* get_cpu_info_mach(struct cpuInfo* cpu) {
cpu->soc = get_soc();
cpu->peak_performance = get_peak_performance(cpu);
}
else if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH) {
cpu->num_cpus = 2;
// Now detect the M3 version
uint32_t cpu_subfamily = get_sys_info_by_name("hw.cpusubfamily");
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
// Apple M3
fill_cpu_info_everest_sawtooth(cpu, 4, 4);
}
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS) {
// Apple M3 Pro/Max/Ultra. Detect number of cores
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
if(physicalcpu == 11 || physicalcpu == 12) {
// M3 Pro
fill_cpu_info_everest_sawtooth(cpu, physicalcpu-6, 6);
}
else if(physicalcpu >= 14 && physicalcpu <= 16) {
// M3 Max
fill_cpu_info_everest_sawtooth(cpu, physicalcpu-4, 4);
}
else {
printBug("Found invalid physical cpu number: %d", physicalcpu);
return NULL;
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
return NULL;
}
cpu->soc = get_soc();
cpu->peak_performance = get_peak_performance(cpu);
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
return NULL;

View File

@@ -886,6 +886,30 @@ struct system_on_chip* guess_soc_apple(struct system_on_chip* soc) {
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
else if(cpu_family == CPUFAMILY_ARM_EVEREST_SAWTOOTH) {
// Check M3 version
if(cpu_subfamily == CPUSUBFAMILY_ARM_HG) {
fill_soc(soc, "M3", SOC_APPLE_M3, 3);
}
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HS) {
fill_soc(soc, "M3 Pro", SOC_APPLE_M3_PRO, 3);
}
else if(cpu_subfamily == CPUSUBFAMILY_ARM_HC_HD) {
// Should be M3 Max
uint32_t physicalcpu = get_sys_info_by_name("hw.physicalcpu");
if(physicalcpu >= 14 && physicalcpu <= 16) {
fill_soc(soc, "M3 Ultra", SOC_APPLE_M3_MAX, 3);
}
else {
printBug("Found invalid physical cpu number: %d", physicalcpu);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
else {
printBug("Found invalid cpu_subfamily: 0x%.8X", cpu_subfamily);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;
}
}
else {
printBug("Found invalid cpu_family: 0x%.8X", cpu_family);
soc->soc_vendor = SOC_VENDOR_UNKNOWN;

View File

@@ -309,6 +309,9 @@ enum {
SOC_APPLE_M2_PRO,
SOC_APPLE_M2_MAX,
SOC_APPLE_M2_ULTRA,
SOC_APPLE_M3,
SOC_APPLE_M3_PRO,
SOC_APPLE_M3_MAX,
// ALLWINNER
SOC_ALLWINNER_A10,
SOC_ALLWINNER_A13,

View File

@@ -8,6 +8,9 @@
// APPLE_CPU_PART_M2_BLIZZARD=0x30,M2_AVALANCHE=0x31
#define MIDR_APPLE_M2_BLIZZARD 0x610F0300
#define MIDR_APPLE_M2_AVALANCHE 0x610F0310
// https://github.com/AsahiLinux/m1n1/blob/main/src/chickens.c
#define MIDR_APPLE_M2_SAWTOOTH 0x610F0480
#define MIDR_APPLE_M2_EVEREST 0x610F0490
// M1 / A14
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
@@ -17,6 +20,10 @@
#ifndef CPUFAMILY_ARM_AVALANCHE_BLIZZARD
#define CPUFAMILY_ARM_AVALANCHE_BLIZZARD 0xDA33D83D
#endif
// M3 / A16 / A17
#ifndef CPUFAMILY_ARM_EVEREST_SAWTOOTH
#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x72015832
#endif
// For detecting different M1 types
// NOTE: Could also be achieved detecting different

View File

@@ -105,6 +105,8 @@ enum {
UARCH_FIRESTORM, // Apple M1 processor (big cores).
UARCH_BLIZZARD, // Apple M2 processor (little cores).
UARCH_AVALANCHE, // Apple M2 processor (big cores).
UARCH_SAWTOOTH, // Apple M3 processor (little cores).
UARCH_EVEREST, // Apple M3 processor (big cores).
// CAVIUM
UARCH_THUNDERX, // Cavium ThunderX
UARCH_THUNDERX2, // Cavium ThunderX2 (originally Broadcom Vulkan).
@@ -220,6 +222,7 @@ void fill_uarch(struct uarch* arch, struct cpuInfo* cpu, char* str, MICROARCH u,
* Other sources:
* - https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/asm/cputype.h
* - https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/cputype.h
* - https://github.com/AsahiLinux/m1n1/blob/main/src/chickens.c
*/
struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
struct uarch* arch = emalloc(sizeof(struct uarch));
@@ -327,6 +330,8 @@ struct uarch* get_uarch_from_midr(uint32_t midr, struct cpuInfo* cpu) {
CHECK_UARCH(arch, cpu, 'a', 0x023, NA, NA, "Firestorm", UARCH_FIRESTORM, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'a', 0x030, NA, NA, "Blizzard", UARCH_BLIZZARD, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'a', 0x031, NA, NA, "Avalanche", UARCH_AVALANCHE, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'a', 0x048, NA, NA, "Sawtooth", UARCH_SAWTOOTH, CPU_VENDOR_APPLE)
CHECK_UARCH(arch, cpu, 'a', 0x049, NA, NA, "Everest", UARCH_EVEREST, 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)