|
#include <stdint.h> |
|
|
|
#include <arm/api.h> |
|
#include <arm/midr.h> |
|
#include <cpuinfo/log.h> |
|
|
|
|
|
void cpuinfo_arm_decode_vendor_uarch( |
|
uint32_t midr, |
|
#if CPUINFO_ARCH_ARM |
|
bool has_vfpv4, |
|
#endif |
|
enum cpuinfo_vendor vendor[restrict static 1], |
|
enum cpuinfo_uarch uarch[restrict static 1]) |
|
{ |
|
switch (midr_get_implementer(midr)) { |
|
case 'A': |
|
*vendor = cpuinfo_vendor_arm; |
|
switch (midr_get_part(midr)) { |
|
#if CPUINFO_ARCH_ARM |
|
case 0xC05: |
|
*uarch = cpuinfo_uarch_cortex_a5; |
|
break; |
|
case 0xC07: |
|
*uarch = cpuinfo_uarch_cortex_a7; |
|
break; |
|
case 0xC08: |
|
*uarch = cpuinfo_uarch_cortex_a8; |
|
break; |
|
case 0xC09: |
|
*uarch = cpuinfo_uarch_cortex_a9; |
|
break; |
|
case 0xC0C: |
|
*uarch = cpuinfo_uarch_cortex_a12; |
|
break; |
|
case 0xC0E: |
|
*uarch = cpuinfo_uarch_cortex_a17; |
|
break; |
|
case 0xC0D: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_cortex_a12; |
|
break; |
|
case 0xC0F: |
|
*uarch = cpuinfo_uarch_cortex_a15; |
|
break; |
|
#endif |
|
case 0xD01: |
|
*uarch = cpuinfo_uarch_cortex_a32; |
|
break; |
|
case 0xD03: |
|
*uarch = cpuinfo_uarch_cortex_a53; |
|
break; |
|
case 0xD04: |
|
*uarch = cpuinfo_uarch_cortex_a35; |
|
break; |
|
case 0xD05: |
|
|
|
*uarch = (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) == 0 ? |
|
cpuinfo_uarch_cortex_a55r0 : cpuinfo_uarch_cortex_a55; |
|
break; |
|
case 0xD06: |
|
*uarch = cpuinfo_uarch_cortex_a65; |
|
break; |
|
case 0xD07: |
|
*uarch = cpuinfo_uarch_cortex_a57; |
|
break; |
|
case 0xD08: |
|
*uarch = cpuinfo_uarch_cortex_a72; |
|
break; |
|
case 0xD09: |
|
*uarch = cpuinfo_uarch_cortex_a73; |
|
break; |
|
case 0xD0A: |
|
*uarch = cpuinfo_uarch_cortex_a75; |
|
break; |
|
case 0xD0B: |
|
*uarch = cpuinfo_uarch_cortex_a76; |
|
break; |
|
case 0xD0C: |
|
*uarch = cpuinfo_uarch_neoverse_n1; |
|
break; |
|
case 0xD0D: |
|
*uarch = cpuinfo_uarch_cortex_a77; |
|
break; |
|
case 0xD0E: |
|
*uarch = cpuinfo_uarch_cortex_a76; |
|
break; |
|
case 0xD40: |
|
*uarch = cpuinfo_uarch_neoverse_v1; |
|
break; |
|
case 0xD41: |
|
*uarch = cpuinfo_uarch_cortex_a78; |
|
break; |
|
case 0xD44: |
|
*uarch = cpuinfo_uarch_cortex_x1; |
|
break; |
|
case 0xD46: |
|
*uarch = cpuinfo_uarch_cortex_a510; |
|
break; |
|
case 0xD47: |
|
*uarch = cpuinfo_uarch_cortex_a710; |
|
break; |
|
#if CPUINFO_ARCH_ARM64 |
|
case 0xD48: |
|
*uarch = cpuinfo_uarch_cortex_x2; |
|
break; |
|
#endif |
|
case 0xD49: |
|
*uarch = cpuinfo_uarch_neoverse_n2; |
|
break; |
|
#if CPUINFO_ARCH_ARM64 |
|
case 0xD4A: |
|
*uarch = cpuinfo_uarch_neoverse_e1; |
|
break; |
|
case 0xD4D: |
|
*uarch = cpuinfo_uarch_cortex_a715; |
|
break; |
|
case 0xD4E: |
|
*uarch = cpuinfo_uarch_cortex_x3; |
|
break; |
|
#endif |
|
default: |
|
switch (midr_get_part(midr) >> 8) { |
|
#if CPUINFO_ARCH_ARM |
|
case 7: |
|
*uarch = cpuinfo_uarch_arm7; |
|
break; |
|
case 9: |
|
*uarch = cpuinfo_uarch_arm9; |
|
break; |
|
case 11: |
|
*uarch = cpuinfo_uarch_arm11; |
|
break; |
|
#endif |
|
default: |
|
cpuinfo_log_warning("unknown ARM CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
} |
|
break; |
|
case 'B': |
|
*vendor = cpuinfo_vendor_broadcom; |
|
switch (midr_get_part(midr)) { |
|
case 0x00F: |
|
*uarch = cpuinfo_uarch_brahma_b15; |
|
break; |
|
case 0x100: |
|
*uarch = cpuinfo_uarch_brahma_b53; |
|
break; |
|
#if CPUINFO_ARCH_ARM64 |
|
case 0x516: |
|
|
|
*vendor = cpuinfo_vendor_cavium; |
|
*uarch = cpuinfo_uarch_thunderx2; |
|
break; |
|
#endif |
|
default: |
|
cpuinfo_log_warning("unknown Broadcom CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
#if CPUINFO_ARCH_ARM64 |
|
case 'C': |
|
*vendor = cpuinfo_vendor_cavium; |
|
switch (midr_get_part(midr)) { |
|
case 0x0A0: |
|
case 0x0A1: |
|
case 0x0A2: |
|
case 0x0A3: |
|
*uarch = cpuinfo_uarch_thunderx; |
|
break; |
|
case 0x0AF: |
|
*uarch = cpuinfo_uarch_thunderx2; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Cavium CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
#endif |
|
case 'H': |
|
*vendor = cpuinfo_vendor_huawei; |
|
switch (midr_get_part(midr)) { |
|
#if CPUINFO_ARCH_ARM64 |
|
case 0xD01: |
|
*uarch = cpuinfo_uarch_taishan_v110; |
|
break; |
|
#endif |
|
case 0xD40: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a76; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Huawei CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
#if CPUINFO_ARCH_ARM |
|
case 'i': |
|
*vendor = cpuinfo_vendor_intel; |
|
switch (midr_get_part(midr) >> 8) { |
|
case 2: |
|
case 4: |
|
case 6: |
|
*uarch = cpuinfo_uarch_xscale; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Intel CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
#endif |
|
case 'N': |
|
*vendor = cpuinfo_vendor_nvidia; |
|
switch (midr_get_part(midr)) { |
|
case 0x000: |
|
*uarch = cpuinfo_uarch_denver; |
|
break; |
|
case 0x003: |
|
*uarch = cpuinfo_uarch_denver2; |
|
break; |
|
case 0x004: |
|
*uarch = cpuinfo_uarch_carmel; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Nvidia CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
case 'P': |
|
*vendor = cpuinfo_vendor_apm; |
|
switch (midr_get_part(midr)) { |
|
case 0x000: |
|
*uarch = cpuinfo_uarch_xgene; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Applied Micro CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
case 'Q': |
|
*vendor = cpuinfo_vendor_qualcomm; |
|
switch (midr_get_part(midr)) { |
|
#if CPUINFO_ARCH_ARM |
|
case 0x00F: |
|
|
|
if (has_vfpv4) { |
|
|
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a5; |
|
} else { |
|
*uarch = cpuinfo_uarch_scorpion; |
|
} |
|
break; |
|
case 0x02D: |
|
*uarch = cpuinfo_uarch_scorpion; |
|
break; |
|
case 0x04D: |
|
|
|
|
|
|
|
|
|
|
|
|
|
case 0x06F: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_krait; |
|
break; |
|
#endif |
|
case 0x201: |
|
case 0x205: |
|
case 0x211: |
|
*uarch = cpuinfo_uarch_kryo; |
|
break; |
|
case 0x800: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a73; |
|
break; |
|
case 0x801: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a53; |
|
break; |
|
case 0x802: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a75; |
|
break; |
|
case 0x803: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a55r0; |
|
break; |
|
case 0x804: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a76; |
|
break; |
|
case 0x805: |
|
*vendor = cpuinfo_vendor_arm; |
|
*uarch = cpuinfo_uarch_cortex_a55; |
|
break; |
|
#if CPUINFO_ARCH_ARM64 |
|
case 0xC00: |
|
*uarch = cpuinfo_uarch_falkor; |
|
break; |
|
case 0xC01: |
|
*uarch = cpuinfo_uarch_saphira; |
|
break; |
|
#endif |
|
default: |
|
cpuinfo_log_warning("unknown Qualcomm CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
case 'S': |
|
*vendor = cpuinfo_vendor_samsung; |
|
switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { |
|
case 0x00100010: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_exynos_m1; |
|
break; |
|
case 0x00400010: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_exynos_m2; |
|
break; |
|
case 0x00100020: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_exynos_m3; |
|
break; |
|
case 0x00100030: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_exynos_m4; |
|
break; |
|
case 0x00100040: |
|
|
|
|
|
|
|
|
|
|
|
*uarch = cpuinfo_uarch_exynos_m5; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Samsung CPU variant 0x%01"PRIx32" part 0x%03"PRIx32" ignored", |
|
midr_get_variant(midr), midr_get_part(midr)); |
|
} |
|
break; |
|
#if CPUINFO_ARCH_ARM |
|
case 'V': |
|
*vendor = cpuinfo_vendor_marvell; |
|
switch (midr_get_part(midr)) { |
|
case 0x581: |
|
case 0x584: |
|
*uarch = cpuinfo_uarch_pj4; |
|
break; |
|
default: |
|
cpuinfo_log_warning("unknown Marvell CPU part 0x%03"PRIx32" ignored", midr_get_part(midr)); |
|
} |
|
break; |
|
#endif |
|
default: |
|
cpuinfo_log_warning("unknown CPU implementer '%c' (0x%02"PRIx32") with CPU part 0x%03"PRIx32" ignored", |
|
(char) midr_get_implementer(midr), midr_get_implementer(midr), midr_get_part(midr)); |
|
} |
|
} |
|
|