diff --git CMakeLists.txt CMakeLists.txt index 06aee4d..6e42ab9 100644 --- CMakeLists.txt +++ CMakeLists.txt @@ -1,6 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR) - -INCLUDE(GNUInstallDirs) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5 FATAL_ERROR) # ---[ Project and semantic versioning. PROJECT(cpuinfo C CXX) @@ -18,32 +16,22 @@ OPTION(CPUINFO_BUILD_MOCK_TESTS "Build cpuinfo mock tests" ON) OPTION(CPUINFO_BUILD_BENCHMARKS "Build cpuinfo micro-benchmarks" ON) # ---[ CMake options +INCLUDE(GNUInstallDirs) + IF(CPUINFO_BUILD_UNIT_TESTS OR CPUINFO_BUILD_MOCK_TESTS) ENABLE_TESTING() ENDIF() MACRO(CPUINFO_TARGET_ENABLE_C99 target) - IF(${CMAKE_VERSION} VERSION_LESS "3.1") - IF(NOT MSVC) - TARGET_COMPILE_OPTIONS(${target} PRIVATE -std=c99) - ENDIF() - ELSE() - SET_TARGET_PROPERTIES(${target} PROPERTIES - C_STANDARD 99 - C_EXTENSIONS NO) - ENDIF() + SET_TARGET_PROPERTIES(${target} PROPERTIES + C_STANDARD 99 + C_EXTENSIONS NO) ENDMACRO() MACRO(CPUINFO_TARGET_ENABLE_CXX11 target) - IF(${CMAKE_VERSION} VERSION_LESS "3.1") - IF(NOT MSVC) - TARGET_COMPILE_OPTIONS(${target} PRIVATE -std=c++11) - ENDIF() - ELSE() - SET_TARGET_PROPERTIES(${target} PROPERTIES - CXX_STANDARD 11 - CXX_EXTENSIONS NO) - ENDIF() + SET_TARGET_PROPERTIES(${target} PROPERTIES + CXX_STANDARD 11 + CXX_EXTENSIONS NO) ENDMACRO() MACRO(CPUINFO_TARGET_RUNTIME_LIBRARY target) diff --git include/cpuinfo.h include/cpuinfo.h index e2e6564..cffa299 100644 --- include/cpuinfo.h +++ include/cpuinfo.h @@ -361,6 +361,8 @@ enum cpuinfo_uarch { cpuinfo_uarch_zen = 0x00200109, /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */ cpuinfo_uarch_zen2 = 0x0020010A, + /** AMD Zen 3 microarchitecture. */ + cpuinfo_uarch_zen3 = 0x0020010B, /** NSC Geode and AMD Geode GX and LX. */ cpuinfo_uarch_geode = 0x00200200, @@ -425,6 +427,9 @@ enum cpuinfo_uarch { /** ARM Neoverse E1. */ cpuinfo_uarch_neoverse_e1 = 0x00300401, + /** ARM Cortex-X1. */ + cpuinfo_uarch_cortex_x1 = 0x00300500, + /** Qualcomm Scorpion. */ cpuinfo_uarch_scorpion = 0x00400100, /** Qualcomm Krait. */ @@ -1455,6 +1460,8 @@ static inline bool cpuinfo_has_x86_sha(void) { #endif #if CPUINFO_ARCH_ARM64 bool atomics; + bool sve; + bool sve2; #endif bool rdm; bool fp16arith; @@ -1770,6 +1777,22 @@ static inline bool cpuinfo_has_arm_crc32(void) { #endif } +static inline bool cpuinfo_has_arm_sve(void) { + #if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sve; + #else + return false; + #endif +} + +static inline bool cpuinfo_has_arm_sve2(void) { + #if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sve2; + #else + return false; + #endif +} + const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void); const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void); const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void); diff --git src/arm/linux/aarch32-isa.c src/arm/linux/aarch32-isa.c index 41f9972..df68aa1 100644 --- src/arm/linux/aarch32-isa.c +++ src/arm/linux/aarch32-isa.c @@ -56,24 +56,37 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( /* * NEON FP16 compute extension and VQRDMLAH/VQRDMLSH instructions are not indicated in /proc/cpuinfo. * Use a MIDR-based heuristic to whitelist processors known to support it: - * - Processors with Qualcomm-modified Cortex-A55 cores - * - Processors with Qualcomm-modified Cortex-A75 cores - * - Processors with Qualcomm-modified Cortex-A76 cores - * - Kirin 980 processor + * - Processors with Cortex-A55 cores + * - Processors with Cortex-A65 cores + * - Processors with Cortex-A75 cores + * - Processors with Cortex-A76 cores + * - Processors with Cortex-A77 cores + * - Processors with Exynos M4 cores + * - Processors with Exynos M5 cores + * - Neoverse N1 cores */ - switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { - case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ - case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ - case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ - isa->fp16arith = true; - isa->rdm = true; - break; - default: - if (chipset->series == cpuinfo_arm_chipset_series_hisilicon_kirin && chipset->model == 980) { + if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { + /* Only little cores of Exynos 9810 support FP16 & RDM */ + cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions"); + } else { + switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { + case UINT32_C(0x4100D050): /* Cortex-A55 */ + case UINT32_C(0x4100D060): /* Cortex-A65 */ + case UINT32_C(0x4100D0B0): /* Cortex-A76 */ + case UINT32_C(0x4100D0C0): /* Neoverse N1 */ + case UINT32_C(0x4100D0D0): /* Cortex-A77 */ + case UINT32_C(0x4100D0E0): /* Cortex-A76AE */ + case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */ + case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ + case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ + case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ + case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */ + case UINT32_C(0x53000030): /* Exynos M4 */ + case UINT32_C(0x53000040): /* Exynos M5 */ isa->fp16arith = true; isa->rdm = true; - } - break; + break; + } } /* diff --git src/arm/linux/aarch64-isa.c src/arm/linux/aarch64-isa.c index 619cda5..2000e1a 100644 --- src/arm/linux/aarch64-isa.c +++ src/arm/linux/aarch64-isa.c @@ -6,6 +6,7 @@ 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]) @@ -28,43 +29,56 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) { isa->atomics = true; } - const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP; - if ((features & fp16arith_mask) == fp16arith_mask) { - if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { - /* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */ - cpuinfo_log_warning("FP16 arithmetics disabled: only little cores of Exynos 9810 support FP16 compute"); - } else { - 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"); - } + /* - * Many phones ship with an old kernel configuration that doesn't report - * SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions. + * Some phones ship with an old kernel configuration that doesn't report NEON FP16 compute extension and SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions. * Use a MIDR-based heuristic to whitelist processors known to support it: - * - Processors with Qualcomm-modified Cortex-A55 cores - * - Processors with Qualcomm-modified Cortex-A75 cores - * - Processors with Qualcomm-modified Cortex-A76 cores - * - Kirin 980 processor + * - Processors with Cortex-A55 cores + * - Processors with Cortex-A65 cores + * - Processors with Cortex-A75 cores + * - Processors with Cortex-A76 cores + * - Processors with Cortex-A77 cores + * - Processors with Exynos M4 cores + * - Processors with Exynos M5 cores + * - Neoverse N1 cores */ - switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { - case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ - case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ - case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ - isa->rdm = true; - break; - default: - if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { - isa->rdm = true; - } - if (chipset->series == cpuinfo_arm_chipset_series_hisilicon_kirin && chipset->model == 980) { + if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { + /* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */ + 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): /* Cortex-A55 */ + case UINT32_C(0x4100D060): /* Cortex-A65 */ + case UINT32_C(0x4100D0B0): /* Cortex-A76 */ + case UINT32_C(0x4100D0C0): /* Neoverse N1 */ + case UINT32_C(0x4100D0D0): /* Cortex-A77 */ + case UINT32_C(0x4100D0E0): /* Cortex-A76AE */ + case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */ + case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ + case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ + case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ + case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */ + case UINT32_C(0x53000030): /* Exynos M4 */ + case UINT32_C(0x53000040): /* Exynos M5 */ + isa->fp16arith = true; isa->rdm = true; - } - break; + 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; + } } + /* * Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions. * Use a MIDR-based heuristic to whitelist processors known to support it. @@ -98,13 +112,16 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { isa->jscvt = true; } - if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { - isa->rdm = 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; + } } diff --git src/arm/linux/api.h src/arm/linux/api.h index 2597e49..1c09f82 100644 --- src/arm/linux/api.h +++ src/arm/linux/api.h @@ -111,6 +111,28 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache { #define CPUINFO_ARM_LINUX_FEATURE_ILRCPC UINT32_C(0x04000000) #define CPUINFO_ARM_LINUX_FEATURE_FLAGM UINT32_C(0x08000000) #define CPUINFO_ARM_LINUX_FEATURE_SSBS UINT32_C(0x10000000) + #define CPUINFO_ARM_LINUX_FEATURE_SB UINT32_C(0x20000000) + #define CPUINFO_ARM_LINUX_FEATURE_PACA UINT32_C(0x40000000) + #define CPUINFO_ARM_LINUX_FEATURE_PACG UINT32_C(0x80000000) + + #define CPUINFO_ARM_LINUX_FEATURE2_DCPODP UINT32_C(0x00000001) + #define CPUINFO_ARM_LINUX_FEATURE2_SVE2 UINT32_C(0x00000002) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEAES UINT32_C(0x00000004) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEPMULL UINT32_C(0x00000008) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEBITPERM UINT32_C(0x00000010) + #define CPUINFO_ARM_LINUX_FEATURE2_SVESHA3 UINT32_C(0x00000020) + #define CPUINFO_ARM_LINUX_FEATURE2_SVESM4 UINT32_C(0x00000040) + #define CPUINFO_ARM_LINUX_FEATURE2_FLAGM2 UINT32_C(0x00000080) + #define CPUINFO_ARM_LINUX_FEATURE2_FRINT UINT32_C(0x00000100) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEI8MM UINT32_C(0x00000200) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEF32MM UINT32_C(0x00000400) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEF64MM UINT32_C(0x00000800) + #define CPUINFO_ARM_LINUX_FEATURE2_SVEBF16 UINT32_C(0x00001000) + #define CPUINFO_ARM_LINUX_FEATURE2_I8MM UINT32_C(0x00002000) + #define CPUINFO_ARM_LINUX_FEATURE2_BF16 UINT32_C(0x00004000) + #define CPUINFO_ARM_LINUX_FEATURE2_DGH UINT32_C(0x00008000) + #define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000) + #define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000) #endif #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000) @@ -146,9 +168,7 @@ struct cpuinfo_arm_linux_processor { struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache; #endif uint32_t features; -#if CPUINFO_ARCH_ARM uint32_t features2; -#endif /** * Main ID Register value. */ @@ -282,9 +302,13 @@ CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo( const struct cpuinfo_arm_chipset chipset[restrict static 1], struct cpuinfo_arm_isa isa[restrict static 1]); #elif CPUINFO_ARCH_ARM64 - CPUINFO_INTERNAL uint32_t cpuinfo_arm_linux_hwcap_from_getauxval(void); + CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval( + uint32_t hwcap[restrict static 1], + uint32_t hwcap2[restrict static 1]); + CPUINFO_INTERNAL 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]); diff --git src/arm/linux/hwcap.c src/arm/linux/hwcap.c index 36d0d91..35e9994 100644 --- src/arm/linux/hwcap.c +++ src/arm/linux/hwcap.c @@ -29,12 +29,10 @@ mock_hwcap = hwcap; } - #if CPUINFO_ARCH_ARM - static uint32_t mock_hwcap2 = 0; - void cpuinfo_set_hwcap2(uint32_t hwcap2) { - mock_hwcap2 = hwcap2; - } - #endif + static uint32_t mock_hwcap2 = 0; + void cpuinfo_set_hwcap2(uint32_t hwcap2) { + mock_hwcap2 = hwcap2; + } #endif @@ -145,11 +143,17 @@ } #endif /* __ANDROID__ */ #elif CPUINFO_ARCH_ARM64 - uint32_t cpuinfo_arm_linux_hwcap_from_getauxval(void) { + void cpuinfo_arm_linux_hwcap_from_getauxval( + uint32_t hwcap[restrict static 1], + uint32_t hwcap2[restrict static 1]) + { #if CPUINFO_MOCK - return mock_hwcap; + *hwcap = mock_hwcap; + *hwcap2 = mock_hwcap2; #else - return (uint32_t) getauxval(AT_HWCAP); + *hwcap = (uint32_t) getauxval(AT_HWCAP); + *hwcap2 = (uint32_t) getauxval(AT_HWCAP2); + return ; #endif } #endif diff --git src/arm/linux/init.c src/arm/linux/init.c index 89d957e..23d8439 100644 --- src/arm/linux/init.c +++ src/arm/linux/init.c @@ -277,10 +277,11 @@ void cpuinfo_arm_linux_init(void) { last_midr, last_architecture_version, last_architecture_flags, &chipset, &cpuinfo_isa); #elif CPUINFO_ARCH_ARM64 + uint32_t isa_features = 0, isa_features2 = 0; /* getauxval is always available on ARM64 Android */ - const uint32_t isa_features = cpuinfo_arm_linux_hwcap_from_getauxval(); + cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2); cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( - isa_features, last_midr, &chipset, &cpuinfo_isa); + isa_features, isa_features2, last_midr, &chipset, &cpuinfo_isa); #endif /* Detect min/max frequency and package ID */ diff --git src/arm/mach/init.c src/arm/mach/init.c index d820744..dbea578 100644 --- src/arm/mach/init.c +++ src/arm/mach/init.c @@ -24,7 +24,6 @@ #ifndef CPUFAMILY_ARM_LIGHTNING_THUNDER #define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504D2 #endif - #ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM #define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3 #endif @@ -349,6 +348,7 @@ void cpuinfo_arm_mach_init(void) { case CPUFAMILY_ARM_MONSOON_MISTRAL: case CPUFAMILY_ARM_VORTEX_TEMPEST: case CPUFAMILY_ARM_LIGHTNING_THUNDER: + case CPUFAMILY_ARM_FIRESTORM_ICESTORM: #if CPUINFO_ARCH_ARM64 cpuinfo_isa.atomics = true; #endif @@ -360,8 +360,10 @@ void cpuinfo_arm_mach_init(void) { * ARMv8.2 optional dot-product instructions, so we currently whitelist CPUs * known to support these instruction. */ - if (cpu_family == CPUFAMILY_ARM_LIGHTNING_THUNDER) { - cpuinfo_isa.dot = true; + switch (cpu_family) { + case CPUFAMILY_ARM_LIGHTNING_THUNDER: + case CPUFAMILY_ARM_FIRESTORM_ICESTORM: + cpuinfo_isa.dot = true; } uint32_t num_clusters = 1; diff --git src/arm/midr.h src/arm/midr.h index 2638517..739dc19 100644 --- src/arm/midr.h +++ src/arm/midr.h @@ -171,9 +171,10 @@ inline static bool midr_is_kryo_gold(uint32_t midr) { inline static uint32_t midr_score_core(uint32_t midr) { const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK; switch (midr & core_mask) { - case UINT32_C(0x53000040): /* Exynos M5 */ case UINT32_C(0x53000030): /* Exynos M4 */ - /* These cores are in big role w.r.t Cortex-A75 or Cortex-A76 */ + case UINT32_C(0x53000040): /* Exynos M5 */ + case UINT32_C(0x4100D440): /* Cortex-X1 */ + /* These cores are in big role w.r.t Cortex-A75/-A76/-A77/-A78 */ return 6; case UINT32_C(0x4E000030): /* Denver 2 */ case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */ diff --git src/arm/uarch.c src/arm/uarch.c index 0d7a7d7..8b5362b 100644 --- src/arm/uarch.c +++ src/arm/uarch.c @@ -94,6 +94,9 @@ void cpuinfo_arm_decode_vendor_uarch( case 0xD41: /* Cortex-A78 */ *uarch = cpuinfo_uarch_cortex_a78; break; + case 0xD44: /* Cortex-X1 */ + *uarch = cpuinfo_uarch_cortex_x1; + break; #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) case 0xD4A: *uarch = cpuinfo_uarch_neoverse_e1; diff --git src/init.c src/init.c index f703e8e..d61e7be 100644 --- src/init.c +++ src/init.c @@ -35,8 +35,6 @@ bool CPUINFO_ABI cpuinfo_initialize(void) { #elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 #if defined(__linux__) pthread_once(&init_guard, &cpuinfo_arm_linux_init); - #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE - pthread_once(&init_guard, &cpuinfo_arm_mach_init); #elif defined(__MACH__) && defined(__APPLE__) pthread_once(&init_guard, &cpuinfo_arm_mach_init); #else diff --git src/x86/uarch.c src/x86/uarch.c index ecaa762..3705499 100644 --- src/x86/uarch.c +++ src/x86/uarch.c @@ -209,9 +209,23 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch( return cpuinfo_uarch_zen; case 0x31: // Rome, Castle Peak case 0x60: // Renoir + case 0x68: // Lucienne case 0x71: // Matisse + case 0x90: // Van Gogh + case 0x98: // Mero return cpuinfo_uarch_zen2; } + break; + case 0x19: + switch (model_info->model) { + case 0x01: // Genesis + case 0x21: // Vermeer + case 0x30: // Badami, Trento + case 0x40: // Rembrandt + case 0x50: // Cezanne + return cpuinfo_uarch_zen3; + } + break; } break; case cpuinfo_vendor_hygon: diff --git src/x86/windows/init.c src/x86/windows/init.c index 9a23bd7..274075c 100644 --- src/x86/windows/init.c +++ src/x86/windows/init.c @@ -95,6 +95,15 @@ static void cpuinfo_x86_count_caches( *l4_count_ptr = l4_count; } +static bool cpuinfo_x86_windows_is_wine(void) { + HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); + if (ntdll == NULL) { + return false; + } + + return GetProcAddress(ntdll, "wine_get_version") != NULL; +} + BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context) { struct cpuinfo_processor* processors = NULL; struct cpuinfo_core* cores = NULL; @@ -108,6 +117,7 @@ BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PV PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX processor_infos = NULL; HANDLE heap = GetProcessHeap(); + const bool is_wine = cpuinfo_x86_windows_is_wine(); struct cpuinfo_x86_processor x86_processor; ZeroMemory(&x86_processor, sizeof(x86_processor)); @@ -121,7 +131,8 @@ BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PV x86_processor.topology.thread_bits_offset + x86_processor.topology.thread_bits_length, x86_processor.topology.core_bits_offset + x86_processor.topology.core_bits_length); - const uint32_t max_group_count = (uint32_t) GetMaximumProcessorGroupCount(); + /* WINE doesn't implement GetMaximumProcessorGroupCount and aborts when calling it */ + const uint32_t max_group_count = is_wine ? 1 : (uint32_t) GetMaximumProcessorGroupCount(); cpuinfo_log_debug("detected %"PRIu32" processor groups", max_group_count); uint32_t processors_count = 0; diff --git test/mock/galaxy-s9-us.cc test/mock/galaxy-s9-us.cc index ceea969..91c4868 100644 --- test/mock/galaxy-s9-us.cc +++ test/mock/galaxy-s9-us.cc @@ -817,4 +817,4 @@ int main(int argc, char* argv[]) { cpuinfo_initialize(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} +} \ No newline at end of file diff --git tools/cpu-info.c tools/cpu-info.c index 55d654f..30ec633 100644 --- tools/cpu-info.c +++ tools/cpu-info.c @@ -129,6 +129,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { return "Zen"; case cpuinfo_uarch_zen2: return "Zen 2"; + case cpuinfo_uarch_zen3: + return "Zen 3"; case cpuinfo_uarch_geode: return "Geode"; case cpuinfo_uarch_bobcat: @@ -185,6 +187,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { return "Cortex-A77"; case cpuinfo_uarch_cortex_a78: return "Cortex-A78"; + case cpuinfo_uarch_cortex_x1: + return "Cortex-X1"; case cpuinfo_uarch_scorpion: return "Scorpion"; case cpuinfo_uarch_krait: diff --git tools/isa-info.c tools/isa-info.c index 8365846..92abb57 100644 --- tools/isa-info.c +++ tools/isa-info.c @@ -161,6 +161,10 @@ int main(int argc, char** argv) { printf("\tARM v8.3 JS conversion: %s\n", cpuinfo_has_arm_jscvt() ? "yes" : "no"); printf("\tARM v8.3 complex: %s\n", cpuinfo_has_arm_fcma() ? "yes" : "no"); + printf("SIMD extensions:\n"); + printf("\tARM SVE: %s\n", cpuinfo_has_arm_sve() ? "yes" : "no"); + printf("\tARM SVE 2: %s\n", cpuinfo_has_arm_sve2() ? "yes" : "no"); + printf("Cryptography extensions:\n"); printf("\tAES: %s\n", cpuinfo_has_arm_aes() ? "yes" : "no"); printf("\tSHA1: %s\n", cpuinfo_has_arm_sha1() ? "yes" : "no");