|
#include <stdint.h> |
|
|
|
#include <arm/linux/api.h> |
|
#include <cpuinfo/log.h> |
|
|
|
|
|
void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( |
|
uint32_t features, |
|
uint32_t features2, |
|
uint32_t midr, |
|
const struct cpuinfo_arm_chipset chipset[restrict static 1], |
|
struct cpuinfo_arm_isa isa[restrict static 1]) |
|
{ |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_AES) { |
|
isa->aes = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) { |
|
isa->pmull = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) { |
|
isa->sha1 = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) { |
|
isa->sha2 = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) { |
|
isa->crc32 = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) { |
|
isa->atomics = true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { |
|
|
|
cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions"); |
|
} else { |
|
const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP; |
|
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { |
|
case UINT32_C(0x4100D050): |
|
case UINT32_C(0x4100D060): |
|
case UINT32_C(0x4100D0A0): |
|
case UINT32_C(0x4100D0B0): |
|
case UINT32_C(0x4100D0C0): |
|
case UINT32_C(0x4100D0D0): |
|
case UINT32_C(0x4100D0E0): |
|
case UINT32_C(0x4100D400): |
|
case UINT32_C(0x4100D490): |
|
case UINT32_C(0x4800D400): |
|
case UINT32_C(0x51008020): |
|
case UINT32_C(0x51008030): |
|
case UINT32_C(0x51008040): |
|
case UINT32_C(0x51008050): |
|
case UINT32_C(0x53000030): |
|
case UINT32_C(0x53000040): |
|
isa->fp16arith = true; |
|
isa->rdm = true; |
|
break; |
|
default: |
|
if ((features & fp16arith_mask) == fp16arith_mask) { |
|
isa->fp16arith = true; |
|
} else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) { |
|
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations"); |
|
} else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) { |
|
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations"); |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { |
|
isa->rdm = true; |
|
} |
|
break; |
|
} |
|
} |
|
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_I8MM) { |
|
isa->i8mm = true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { |
|
case UINT32_C(0x4100D060): |
|
case UINT32_C(0x4100D0B0): |
|
case UINT32_C(0x4100D0C0): |
|
case UINT32_C(0x4100D0D0): |
|
case UINT32_C(0x4100D0E0): |
|
case UINT32_C(0x4100D400): |
|
case UINT32_C(0x4100D490): |
|
case UINT32_C(0x4100D4A0): |
|
case UINT32_C(0x4800D400): |
|
case UINT32_C(0x51008040): |
|
case UINT32_C(0x51008050): |
|
case UINT32_C(0x53000030): |
|
case UINT32_C(0x53000040): |
|
isa->dot = true; |
|
break; |
|
case UINT32_C(0x4100D050): |
|
isa->dot = !!(midr_get_variant(midr) >= 1); |
|
break; |
|
case UINT32_C(0x4100D0A0): |
|
isa->dot = !!(midr_get_variant(midr) >= 2); |
|
break; |
|
default: |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDDP) { |
|
isa->dot = true; |
|
} |
|
break; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { |
|
isa->jscvt = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { |
|
isa->jscvt = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) { |
|
isa->fcma = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_SVE) { |
|
isa->sve = true; |
|
} |
|
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) { |
|
isa->sve2 = true; |
|
} |
|
|
|
|
|
if (features2 & (CPUINFO_ARM_LINUX_FEATURE2_BF16 | CPUINFO_ARM_LINUX_FEATURE2_SVEBF16)) { |
|
isa->bf16 = true; |
|
} |
|
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) { |
|
isa->fhm = true; |
|
} |
|
} |
|
|
|
|