From eb966b37a07143bc88ace7108742b3fe4a388770 Mon Sep 17 00:00:00 2001 From: Prashanth Swaminathan Date: Tue, 23 Apr 2024 11:59:28 -0700 Subject: [PATCH 01/25] Use cluster_cpus_list to detect clusters for ARM On newer kernels (6.x+) a separate topology node exists to express the list of cpus associated with each cluster. The cluster topology node explicitly refers to cores that share some resources (e.g. cache) as opposed to 'core_siblings', which only indicate they are on the same physical package. This distinction is relevant on 6.x, where some devices may have all their cores on a single physical package but cores do not all share the same resources on that package. In these cases, the existing logic incorrectly reports that there is a single cluster (because all cores are siblings), even though not all cores share the same resources. Test: Verified on ARM64 Android device that has multiple clusters, where core_siblings reports all cores are siblings. Test: Added mock hardware tests, verified pass on ARM64 hardware. --- CMakeLists.txt | 5 + scripts/android-arm64-mock.sh | 2 + scripts/android-armv7-mock.sh | 2 + src/arm/linux/init.c | 36 +- test/mock/pixel-8.cc | 851 ++++++++++++++++++++++ test/mock/pixel-8.h | 1294 +++++++++++++++++++++++++++++++++ tools/cpu-info.c | 33 + 7 files changed, 2222 insertions(+), 1 deletion(-) create mode 100644 test/mock/pixel-8.cc create mode 100644 test/mock/pixel-8.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 99047e58..1b7faa64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -737,6 +737,11 @@ IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_MOCK_TESTS) TARGET_LINK_LIBRARIES(pixel-2-xl-test PRIVATE cpuinfo_mock gtest) ADD_TEST(NAME pixel-2-xl-test COMMAND pixel-2-xl-test) + ADD_EXECUTABLE(pixel-8-test test/mock/pixel-8.cc) + TARGET_INCLUDE_DIRECTORIES(pixel-8-test BEFORE PRIVATE test/mock) + TARGET_LINK_LIBRARIES(pixel-8-test PRIVATE cpuinfo_mock gtest) + ADD_TEST(NAME pixel-8-test COMMAND pixel-8-test) + ADD_EXECUTABLE(xiaomi-mi-5c-test test/mock/xiaomi-mi-5c.cc) TARGET_INCLUDE_DIRECTORIES(xiaomi-mi-5c-test BEFORE PRIVATE test/mock) TARGET_LINK_LIBRARIES(xiaomi-mi-5c-test PRIVATE cpuinfo_mock gtest) diff --git a/scripts/android-arm64-mock.sh b/scripts/android-arm64-mock.sh index a5ad2e2a..6028260a 100755 --- a/scripts/android-arm64-mock.sh +++ b/scripts/android-arm64-mock.sh @@ -36,6 +36,7 @@ adb push build/android/arm64-v8a/pixel-c-test /data/local/tmp/pixel-c-test adb push build/android/arm64-v8a/pixel-xl-test /data/local/tmp/pixel-xl-test adb push build/android/arm64-v8a/pixel-test /data/local/tmp/pixel-test adb push build/android/arm64-v8a/pixel-2-xl-test /data/local/tmp/pixel-2-xl-test +adb push build/android/arm64-v8a/pixel-8-test /data/local/tmp/pixel-8-test adb push build/android/arm64-v8a/xiaomi-mi-5c-test /data/local/tmp/xiaomi-mi-5c-test adb push build/android/arm64-v8a/xiaomi-redmi-note-3-test /data/local/tmp/xiaomi-redmi-note-3-test adb push build/android/arm64-v8a/xiaomi-redmi-note-4-test /data/local/tmp/xiaomi-redmi-note-4-test @@ -75,6 +76,7 @@ adb shell "/data/local/tmp/pixel-c-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-xl-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-2-xl-test --gtest_color=yes" +adb shell "/data/local/tmp/pixel-8-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-mi-5c-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-redmi-note-3-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-redmi-note-4-test --gtest_color=yes" diff --git a/scripts/android-armv7-mock.sh b/scripts/android-armv7-mock.sh index 1bcf23dd..4f89bd71 100755 --- a/scripts/android-armv7-mock.sh +++ b/scripts/android-armv7-mock.sh @@ -70,6 +70,7 @@ adb push build/android/armeabi-v7a/pixel-c-test /data/local/tmp/pixel-c-test adb push build/android/armeabi-v7a/pixel-xl-test /data/local/tmp/pixel-xl-test adb push build/android/armeabi-v7a/pixel-test /data/local/tmp/pixel-test adb push build/android/armeabi-v7a/pixel-2-xl-test /data/local/tmp/pixel-2-xl-test +adb push build/android/armeabi-v7a/pixel-8-test /data/local/tmp/pixel-8-test adb push build/android/armeabi-v7a/xiaomi-mi-5c-test /data/local/tmp/xiaomi-mi-5c-test adb push build/android/armeabi-v7a/xiaomi-redmi-2a-test /data/local/tmp/xiaomi-redmi-2a-test adb push build/android/armeabi-v7a/xiaomi-redmi-note-3-test /data/local/tmp/xiaomi-redmi-note-3-test @@ -145,6 +146,7 @@ adb shell "/data/local/tmp/pixel-c-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-xl-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-test --gtest_color=yes" adb shell "/data/local/tmp/pixel-2-xl-test --gtest_color=yes" +adb shell "/data/local/tmp/pixel-8-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-mi-5c-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-redmi-2a-test --gtest_color=yes" adb shell "/data/local/tmp/xiaomi-redmi-note-3-test --gtest_color=yes" diff --git a/src/arm/linux/init.c b/src/arm/linux/init.c index 988f05aa..6e2024d1 100644 --- a/src/arm/linux/init.c +++ b/src/arm/linux/init.c @@ -333,18 +333,52 @@ void cpuinfo_arm_linux_init(void) { } /* Propagate topology group IDs among siblings */ + bool detected_core_siblings_list_node = false; + bool detected_cluster_cpus_list_node = false; for (uint32_t i = 0; i < arm_linux_processors_count; i++) { if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) { continue; } - if (arm_linux_processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_ID) { + if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_PACKAGE_ID)) { + continue; + } + + /* Use the cluster_cpus_list topology node if available. If not + * found, cache the result to avoid repeatedly attempting to + * read the non-existent paths. + * */ + if (!detected_core_siblings_list_node && !detected_cluster_cpus_list_node) { + if (cpuinfo_linux_detect_cluster_cpus( + arm_linux_processors_count, + i, + (cpuinfo_siblings_callback)cluster_siblings_parser, + arm_linux_processors)) { + detected_cluster_cpus_list_node = true; + continue; + } else { + detected_core_siblings_list_node = true; + } + } + + /* The cached result above will guarantee only one of the blocks + * below will execute, with a bias towards cluster_cpus_list. + **/ + if (detected_core_siblings_list_node) { cpuinfo_linux_detect_core_siblings( arm_linux_processors_count, i, (cpuinfo_siblings_callback)cluster_siblings_parser, arm_linux_processors); } + + if (detected_cluster_cpus_list_node) { + cpuinfo_linux_detect_cluster_cpus( + arm_linux_processors_count, + i, + (cpuinfo_siblings_callback)cluster_siblings_parser, + arm_linux_processors); + } } /* Propagate all cluster IDs */ diff --git a/test/mock/pixel-8.cc b/test/mock/pixel-8.cc new file mode 100644 index 00000000..a0235b41 --- /dev/null +++ b/test/mock/pixel-8.cc @@ -0,0 +1,851 @@ +#include + +#include +#include + +TEST(PROCESSORS, count) { + ASSERT_EQ(9, cpuinfo_get_processors_count()); +} + +TEST(PROCESSORS, non_null) { + ASSERT_TRUE(cpuinfo_get_processors()); +} + +TEST(PROCESSORS, smt_id) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_processor(i)->smt_id); + } +} + +TEST(PROCESSORS, core) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_EQ(cpuinfo_get_core(i), cpuinfo_get_processor(i)->core); + } +} + +TEST(PROCESSORS, cluster) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(cpuinfo_get_cluster(0), cpuinfo_get_processor(i)->cluster); + break; + case 1: + case 2: + case 3: + case 4: + ASSERT_EQ(cpuinfo_get_cluster(1), cpuinfo_get_processor(i)->cluster); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(cpuinfo_get_cluster(2), cpuinfo_get_processor(i)->cluster); + break; + } + } +} + +TEST(PROCESSORS, package) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_EQ(cpuinfo_get_package(0), cpuinfo_get_processor(i)->package); + } +} + +TEST(PROCESSORS, linux_id) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(8, cpuinfo_get_processor(i)->linux_id); + break; + case 1: + case 2: + case 3: + case 4: + ASSERT_EQ(i + 3, cpuinfo_get_processor(i)->linux_id); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(i - 5, cpuinfo_get_processor(i)->linux_id); + break; + } + } +} + +TEST(PROCESSORS, l1i) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_EQ(cpuinfo_get_l1i_cache(i), cpuinfo_get_processor(i)->cache.l1i); + } +} + +TEST(PROCESSORS, l1d) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_EQ(cpuinfo_get_l1d_cache(i), cpuinfo_get_processor(i)->cache.l1d); + } +} + +TEST(PROCESSORS, l2) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(cpuinfo_get_l2_cache(0), cpuinfo_get_processor(i)->cache.l2); + break; + case 1: + case 2: + case 3: + case 4: + ASSERT_EQ(cpuinfo_get_l2_cache(1), cpuinfo_get_processor(i)->cache.l2); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(cpuinfo_get_l2_cache(2), cpuinfo_get_processor(i)->cache.l2); + break; + } + } +} + +TEST(PROCESSORS, l3) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_FALSE(cpuinfo_get_processor(i)->cache.l3); + } +} + +TEST(PROCESSORS, l4) { + for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { + ASSERT_FALSE(cpuinfo_get_processor(i)->cache.l4); + } +} + +TEST(CORES, count) { + ASSERT_EQ(9, cpuinfo_get_cores_count()); +} + +TEST(CORES, non_null) { + ASSERT_TRUE(cpuinfo_get_cores()); +} + +TEST(CORES, processor_start) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + ASSERT_EQ(i, cpuinfo_get_core(i)->processor_start); + } +} + +TEST(CORES, processor_count) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + ASSERT_EQ(1, cpuinfo_get_core(i)->processor_count); + } +} + +TEST(CORES, core_id) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + ASSERT_EQ(i, cpuinfo_get_core(i)->core_id); + } +} + +TEST(CORES, cluster) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(cpuinfo_get_cluster(0), cpuinfo_get_core(i)->cluster); + break; + case 1: + case 2: + case 3: + case 4: + ASSERT_EQ(cpuinfo_get_cluster(1), cpuinfo_get_core(i)->cluster); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(cpuinfo_get_cluster(2), cpuinfo_get_core(i)->cluster); + break; + } + } +} + +TEST(CORES, package) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + ASSERT_EQ(cpuinfo_get_package(0), cpuinfo_get_core(i)->package); + } +} + +TEST(CORES, vendor) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + ASSERT_EQ(cpuinfo_vendor_arm, cpuinfo_get_core(i)->vendor); + } +} + +TEST(CORES, uarch) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(cpuinfo_uarch_cortex_x3, cpuinfo_get_core(i)->uarch); + break; + case 1: + case 2: + case 3: + ASSERT_EQ(cpuinfo_uarch_cortex_a715, cpuinfo_get_core(i)->uarch); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(cpuinfo_uarch_cortex_a510, cpuinfo_get_core(i)->uarch); + break; + } + } +} + +TEST(CORES, midr) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(UINT32_C(0x411fd4e0), cpuinfo_get_core(i)->midr); + break; + case 1: + case 2: + case 3: + case 4: + ASSERT_EQ(UINT32_C(0x411fd4d0), cpuinfo_get_core(i)->midr); + break; + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(UINT32_C(0x411fd461), cpuinfo_get_core(i)->midr); + break; + } + } +} + +TEST(CORES, DISABLED_frequency) { + for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + ASSERT_EQ(UINT64_C(2457600000), cpuinfo_get_core(i)->frequency); + break; + case 4: + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(UINT64_C(1900800000), cpuinfo_get_core(i)->frequency); + break; + } + } +} + +TEST(CLUSTERS, count) { + ASSERT_EQ(3, cpuinfo_get_clusters_count()); +} + +TEST(CLUSTERS, non_null) { + ASSERT_TRUE(cpuinfo_get_clusters()); +} + +TEST(CLUSTERS, processor_start) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(0, cpuinfo_get_cluster(i)->processor_start); + break; + case 1: + ASSERT_EQ(1, cpuinfo_get_cluster(i)->processor_start); + break; + case 2: + ASSERT_EQ(5, cpuinfo_get_cluster(i)->processor_start); + break; + } + } +} + +TEST(CLUSTERS, processor_count) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(1, cpuinfo_get_cluster(i)->processor_count); + break; + case 1: + ASSERT_EQ(4, cpuinfo_get_cluster(i)->processor_count); + break; + case 2: + ASSERT_EQ(4, cpuinfo_get_cluster(i)->processor_count); + break; + } + } +} + +TEST(CLUSTERS, core_start) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(0, cpuinfo_get_cluster(i)->core_start); + break; + case 1: + ASSERT_EQ(1, cpuinfo_get_cluster(i)->core_start); + break; + case 2: + ASSERT_EQ(5, cpuinfo_get_cluster(i)->core_start); + break; + } + } +} + +TEST(CLUSTERS, core_count) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(1, cpuinfo_get_cluster(i)->core_count); + break; + case 1: + ASSERT_EQ(4, cpuinfo_get_cluster(i)->core_count); + break; + case 2: + ASSERT_EQ(4, cpuinfo_get_cluster(i)->core_count); + break; + } + } +} + +TEST(CLUSTERS, cluster_id) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + ASSERT_EQ(i, cpuinfo_get_cluster(i)->cluster_id); + } +} + +TEST(CLUSTERS, package) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + ASSERT_EQ(cpuinfo_get_package(0), cpuinfo_get_cluster(i)->package); + } +} + +TEST(CLUSTERS, vendor) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + ASSERT_EQ(cpuinfo_vendor_arm, cpuinfo_get_cluster(i)->vendor); + } +} + +TEST(CLUSTERS, uarch) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(cpuinfo_uarch_cortex_x3, cpuinfo_get_cluster(i)->uarch); + break; + case 1: + ASSERT_EQ(cpuinfo_uarch_cortex_a715, cpuinfo_get_cluster(i)->uarch); + break; + case 2: + ASSERT_EQ(cpuinfo_uarch_cortex_a510, cpuinfo_get_cluster(i)->uarch); + break; + } + } +} + +TEST(CLUSTERS, midr) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(UINT32_C(0x411fd4e0), cpuinfo_get_cluster(i)->midr); + break; + case 1: + ASSERT_EQ(UINT32_C(0x411fd4d0), cpuinfo_get_cluster(i)->midr); + break; + case 2: + ASSERT_EQ(UINT32_C(0x411fd461), cpuinfo_get_cluster(i)->midr); + break; + } + } +} + +TEST(CLUSTERS, DISABLED_frequency) { + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + ASSERT_EQ(UINT64_C(1197000), cpuinfo_get_cluster(i)->frequency); + break; + } + } +} + +TEST(PACKAGES, count) { + ASSERT_EQ(1, cpuinfo_get_packages_count()); +} + +TEST(PACKAGES, name) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ( + "Unknown", + std::string( + cpuinfo_get_package(i)->name, + strnlen(cpuinfo_get_package(i)->name, CPUINFO_PACKAGE_NAME_MAX))); + } +} + +TEST(PACKAGES, processor_start) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_package(i)->processor_start); + } +} + +TEST(PACKAGES, processor_count) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(9, cpuinfo_get_package(i)->processor_count); + } +} + +TEST(PACKAGES, core_start) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_package(i)->core_start); + } +} + +TEST(PACKAGES, core_count) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(9, cpuinfo_get_package(i)->core_count); + } +} + +TEST(PACKAGES, cluster_start) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_package(i)->cluster_start); + } +} + +TEST(PACKAGES, cluster_count) { + for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) { + ASSERT_EQ(3, cpuinfo_get_package(i)->cluster_count); + } +} + +TEST(ISA, thumb) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_thumb()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_thumb()); +#endif +} + +TEST(ISA, thumb2) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_thumb2()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_thumb2()); +#endif +} + +TEST(ISA, armv5e) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_v5e()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_v5e()); +#endif +} + +TEST(ISA, armv6) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_v6()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_v6()); +#endif +} + +TEST(ISA, armv6k) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_v6k()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_v6k()); +#endif +} + +TEST(ISA, armv7) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_v7()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_v7()); +#endif +} + +TEST(ISA, armv7mp) { +#if CPUINFO_ARCH_ARM + ASSERT_TRUE(cpuinfo_has_arm_v7mp()); +#elif CPUINFO_ARCH_ARM64 + ASSERT_FALSE(cpuinfo_has_arm_v7mp()); +#endif +} + +TEST(ISA, idiv) { + ASSERT_TRUE(cpuinfo_has_arm_idiv()); +} + +TEST(ISA, vfpv2) { + ASSERT_FALSE(cpuinfo_has_arm_vfpv2()); +} + +TEST(ISA, vfpv3) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv3()); +} + +TEST(ISA, vfpv3_d32) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv3_d32()); +} + +TEST(ISA, vfpv3_fp16) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv3_fp16()); +} + +TEST(ISA, vfpv3_fp16_d32) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv3_fp16_d32()); +} + +TEST(ISA, vfpv4) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv4()); +} + +TEST(ISA, vfpv4_d32) { + ASSERT_TRUE(cpuinfo_has_arm_vfpv4_d32()); +} + +TEST(ISA, wmmx) { + ASSERT_FALSE(cpuinfo_has_arm_wmmx()); +} + +TEST(ISA, wmmx2) { + ASSERT_FALSE(cpuinfo_has_arm_wmmx2()); +} + +TEST(ISA, neon) { + ASSERT_TRUE(cpuinfo_has_arm_neon()); +} + +TEST(ISA, neon_fp16) { + ASSERT_TRUE(cpuinfo_has_arm_neon_fp16()); +} + +TEST(ISA, neon_fma) { + ASSERT_TRUE(cpuinfo_has_arm_neon_fma()); +} + +TEST(ISA, atomics) { + ASSERT_FALSE(cpuinfo_has_arm_atomics()); +} + +TEST(ISA, neon_rdm) { + ASSERT_FALSE(cpuinfo_has_arm_neon_rdm()); +} + +TEST(ISA, fp16_arith) { + ASSERT_FALSE(cpuinfo_has_arm_fp16_arith()); +} + +TEST(ISA, neon_fp16_arith) { + ASSERT_FALSE(cpuinfo_has_arm_neon_fp16_arith()); +} + +TEST(ISA, neon_dot) { + ASSERT_FALSE(cpuinfo_has_arm_neon_dot()); +} + +TEST(ISA, jscvt) { + ASSERT_FALSE(cpuinfo_has_arm_jscvt()); +} + +TEST(ISA, fcma) { + ASSERT_FALSE(cpuinfo_has_arm_fcma()); +} + +TEST(ISA, aes) { + ASSERT_TRUE(cpuinfo_has_arm_aes()); +} + +TEST(ISA, sha1) { + ASSERT_TRUE(cpuinfo_has_arm_sha1()); +} + +TEST(ISA, sha2) { + ASSERT_TRUE(cpuinfo_has_arm_sha2()); +} + +TEST(ISA, pmull) { + ASSERT_TRUE(cpuinfo_has_arm_pmull()); +} + +TEST(ISA, crc32) { + ASSERT_TRUE(cpuinfo_has_arm_crc32()); +} + +TEST(L1I, count) { + ASSERT_EQ(9, cpuinfo_get_l1i_caches_count()); +} + +TEST(L1I, non_null) { + ASSERT_TRUE(cpuinfo_get_l1i_caches()); +} + +TEST(L1I, size) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + ASSERT_EQ(64 * 512, cpuinfo_get_l1i_cache(i)->size); + break; + case 4: + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(32 * 1024, cpuinfo_get_l1i_cache(i)->size); + break; + } + } +} + +TEST(L1I, associativity) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(4, cpuinfo_get_l1i_cache(i)->associativity); + break; + } + } +} + +TEST(L1I, sets) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + ASSERT_EQ( + cpuinfo_get_l1i_cache(i)->size, + cpuinfo_get_l1i_cache(i)->sets * cpuinfo_get_l1i_cache(i)->line_size * + cpuinfo_get_l1i_cache(i)->partitions * cpuinfo_get_l1i_cache(i)->associativity); + } +} + +TEST(L1I, partitions) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + ASSERT_EQ(1, cpuinfo_get_l1i_cache(i)->partitions); + } +} + +TEST(L1I, line_size) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + ASSERT_EQ(64, cpuinfo_get_l1i_cache(i)->line_size); + } +} + +TEST(L1I, flags) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_l1i_cache(i)->flags); + } +} + +TEST(L1I, processors) { + for (uint32_t i = 0; i < cpuinfo_get_l1i_caches_count(); i++) { + ASSERT_EQ(i, cpuinfo_get_l1i_cache(i)->processor_start); + ASSERT_EQ(1, cpuinfo_get_l1i_cache(i)->processor_count); + } +} + +TEST(L1D, count) { + ASSERT_EQ(9, cpuinfo_get_l1d_caches_count()); +} + +TEST(L1D, non_null) { + ASSERT_TRUE(cpuinfo_get_l1d_caches()); +} + +TEST(L1D, size) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + ASSERT_EQ(64 * 512, cpuinfo_get_l1d_cache(i)->size); + break; + case 4: + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(32 * 1024, cpuinfo_get_l1d_cache(i)->size); + break; + } + } +} + +TEST(L1D, associativity) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + ASSERT_EQ(4, cpuinfo_get_l1d_cache(i)->associativity); + break; + } + } +} + +TEST(L1D, sets) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + ASSERT_EQ( + cpuinfo_get_l1d_cache(i)->size, + cpuinfo_get_l1d_cache(i)->sets * cpuinfo_get_l1d_cache(i)->line_size * + cpuinfo_get_l1d_cache(i)->partitions * cpuinfo_get_l1d_cache(i)->associativity); + } +} + +TEST(L1D, partitions) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + ASSERT_EQ(1, cpuinfo_get_l1d_cache(i)->partitions); + } +} + +TEST(L1D, line_size) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + ASSERT_EQ(64, cpuinfo_get_l1d_cache(i)->line_size); + } +} + +TEST(L1D, flags) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + ASSERT_EQ(0, cpuinfo_get_l1d_cache(i)->flags); + } +} + +TEST(L1D, processors) { + for (uint32_t i = 0; i < cpuinfo_get_l1d_caches_count(); i++) { + ASSERT_EQ(i, cpuinfo_get_l1d_cache(i)->processor_start); + ASSERT_EQ(1, cpuinfo_get_l1d_cache(i)->processor_count); + } +} + +TEST(L2, count) { + ASSERT_EQ(3, cpuinfo_get_l2_caches_count()); +} + +TEST(L2, non_null) { + ASSERT_TRUE(cpuinfo_get_l2_caches()); +} + +TEST(L2, size) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(1 * 512 * 512, cpuinfo_get_l2_cache(i)->size); + break; + case 1: + case 2: + ASSERT_EQ(1 * 1024 * 1024, cpuinfo_get_l2_cache(i)->size); + break; + } + } +} + +TEST(L2, associativity) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + ASSERT_EQ(8, cpuinfo_get_l2_cache(i)->associativity); + } +} + +TEST(L2, sets) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + ASSERT_EQ( + cpuinfo_get_l2_cache(i)->size, + cpuinfo_get_l2_cache(i)->sets * cpuinfo_get_l2_cache(i)->line_size * + cpuinfo_get_l2_cache(i)->partitions * cpuinfo_get_l2_cache(i)->associativity); + } +} + +TEST(L2, partitions) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + ASSERT_EQ(1, cpuinfo_get_l2_cache(i)->partitions); + } +} + +TEST(L2, line_size) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + ASSERT_EQ(64, cpuinfo_get_l2_cache(i)->line_size); + } +} + +TEST(L2, flags) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + switch (i) { + case 0: + case 1: + case 2: + ASSERT_EQ(0, cpuinfo_get_l2_cache(i)->flags); + break; + } + } +} + +TEST(L2, processors) { + for (uint32_t i = 0; i < cpuinfo_get_l2_caches_count(); i++) { + switch (i) { + case 0: + ASSERT_EQ(0, cpuinfo_get_l2_cache(i)->processor_start); + ASSERT_EQ(1, cpuinfo_get_l2_cache(i)->processor_count); + break; + case 1: + ASSERT_EQ(1, cpuinfo_get_l2_cache(i)->processor_start); + ASSERT_EQ(4, cpuinfo_get_l2_cache(i)->processor_count); + break; + case 2: + ASSERT_EQ(5, cpuinfo_get_l2_cache(i)->processor_start); + ASSERT_EQ(4, cpuinfo_get_l2_cache(i)->processor_count); + break; + } + } +} + +TEST(L3, none) { + ASSERT_EQ(0, cpuinfo_get_l3_caches_count()); + ASSERT_FALSE(cpuinfo_get_l3_caches()); +} + +TEST(L4, none) { + ASSERT_EQ(0, cpuinfo_get_l4_caches_count()); + ASSERT_FALSE(cpuinfo_get_l4_caches()); +} + +#include + +int main(int argc, char* argv[]) { +#if CPUINFO_ARCH_ARM + cpuinfo_set_hwcap(UINT32_C(0x0037B0D6)); + cpuinfo_set_hwcap2(UINT32_C(0x0000001F)); +#elif CPUINFO_ARCH_ARM64 + cpuinfo_set_hwcap(UINT32_C(0x000000FF)); +#endif + cpuinfo_mock_filesystem(filesystem); +#ifdef __ANDROID__ + cpuinfo_mock_android_properties(properties); +#endif + cpuinfo_initialize(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/mock/pixel-8.h b/test/mock/pixel-8.h new file mode 100644 index 00000000..10ff684e --- /dev/null +++ b/test/mock/pixel-8.h @@ -0,0 +1,1294 @@ +struct cpuinfo_mock_file filesystem[] = { + {.path = "/proc/cpuinfo", + .size = 3717, + .content = + "processor\t: 0\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd46\n" + "CPU revision\t: 1\n" + "\n" + "processor\t: 1\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd46\n" + "CPU revision\t: 1\n" + "\n" + "processor\t: 2\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd46\n" + "CPU revision\t: 1\n" + "\n" + "processor\t: 3\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd46\n" + "CPU revision\t: 1\n" + "\n" + "processor\t: 4\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd4d\n" + "CPU revision\t: 0\n" + "\n" + "processor\t: 5\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd4d\n" + "CPU revision\t: 0\n" + "\n" + "processor\t: 6\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd4d\n" + "CPU revision\t: 0\n" + "\n" + "processor\t: 7\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd4d\n" + "CPU revision\t: 0\n" + "\n" + "processor\t: 8\n" + "BogoMIPS\t: 49.15\n" + "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bti\n" + "CPU implementer\t: 0x41\n" + "CPU architecture: 8\n" + "CPU variant\t: 0x1\n" + "CPU part\t: 0xd4e\n" + "CPU revision\t: 0\n"}, + {.path = "/sys/devices/system/cpu/kernel_max", .size = 3, .content = "31\n"}, + {.path = "/sys/devices/system/cpu/possible", .size = 4, .content = "0-8\n"}, + {.path = "/sys/devices/system/cpu/present", .size = 4, .content = "0-8\n"}, + {.path = "/sys/devices/system/cpu/online", .size = 4, .content = "0-8\n"}, + {.path = "/sys/devices/system/cpu/offline", .size = 1, .content = "\n"}, + {.path = "/sys/devices/system/cpu/modalias", + .size = 251, + .content = + "cpu:type:aarch64:feature:,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009,000A,000B,000C,000D,000E,000F,0010,0011,0012,0013,0014,0015,0016,0017,0018,0019,001A,001B,001C,001D,001E,001F,0020,0021,0022,0023,0024,0025,0026,0027,0028,0029,002C,002D,0031\n"}, + {.path = "/sys/devices/system/cpu/cpuidle/current_driver", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpuidle/current_governor_ro", .size = 4, .content = "teo\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/affected_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", .size = 8, .content = "1704000\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/related_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", + .size = 76, + .content = "324000 610000 820000 955000 1098000 1197000 1328000 1425000 1548000 1704000 \n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", .size = 8, .content = "1197000\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", + .size = 131, + .content = "324000 1026376\n" + "610000 18555\n" + "820000 12889\n" + "955000 3943\n" + "1098000 4202\n" + "1197000 2559\n" + "1328000 4948\n" + "1425000 1421\n" + "1548000 1288\n" + "1704000 9901\n"}, + {.path = "/sys/devices/system/cpu/cpu0/cpufreq/stats/total_trans", .size = 7, .content = "115798\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/core_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/core_siblings_list", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/cluster_cpus", .size = 4, .content = "00f\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/cluster_cpus_list", .size = 4, .content = "0-3\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/physical_package_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/thread_siblings", .size = 4, .content = "001\n"}, + {.path = "/sys/devices/system/cpu/cpu0/topology/thread_siblings_list", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/affected_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq", .size = 8, .content = "1704000\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/related_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_frequencies", + .size = 76, + .content = "324000 610000 820000 955000 1098000 1197000 1328000 1425000 1548000 1704000 \n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/stats/time_in_state", + .size = 131, + .content = "324000 1027068\n" + "610000 18568\n" + "820000 12892\n" + "955000 3945\n" + "1098000 4212\n" + "1197000 2563\n" + "1328000 4950\n" + "1425000 1422\n" + "1548000 1288\n" + "1704000 9910\n"}, + {.path = "/sys/devices/system/cpu/cpu1/cpufreq/stats/total_trans", .size = 7, .content = "115912\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/core_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/core_siblings_list", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/cluster_cpus", .size = 4, .content = "00f\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/cluster_cpus_list", .size = 4, .content = "0-3\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/physical_package_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/thread_siblings", .size = 4, .content = "002\n"}, + {.path = "/sys/devices/system/cpu/cpu1/topology/thread_siblings_list", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/affected_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_max_freq", .size = 8, .content = "1704000\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/related_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_available_frequencies", + .size = 76, + .content = "324000 610000 820000 955000 1098000 1197000 1328000 1425000 1548000 1704000 \n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/scaling_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/stats/time_in_state", + .size = 131, + .content = "324000 1027745\n" + "610000 18580\n" + "820000 12909\n" + "955000 3950\n" + "1098000 4217\n" + "1197000 2570\n" + "1328000 4958\n" + "1425000 1423\n" + "1548000 1290\n" + "1704000 9923\n"}, + {.path = "/sys/devices/system/cpu/cpu2/cpufreq/stats/total_trans", .size = 7, .content = "116054\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/core_id", .size = 2, .content = "2\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/core_siblings_list", .size = 2, .content = "2\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/cluster_cpus", .size = 4, .content = "00f\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/cluster_cpus_list", .size = 4, .content = "0-3\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/physical_package_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/thread_siblings", .size = 4, .content = "004\n"}, + {.path = "/sys/devices/system/cpu/cpu2/topology/thread_siblings_list", .size = 2, .content = "2\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/affected_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_max_freq", .size = 8, .content = "1704000\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/related_cpus", .size = 8, .content = "0 1 2 3\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_available_frequencies", + .size = 76, + .content = "324000 610000 820000 955000 1098000 1197000 1328000 1425000 1548000 1704000 \n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_cur_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/scaling_min_freq", .size = 7, .content = "324000\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/stats/time_in_state", + .size = 131, + .content = "324000 1028434\n" + "610000 18597\n" + "820000 12919\n" + "955000 3952\n" + "1098000 4223\n" + "1197000 2577\n" + "1328000 4960\n" + "1425000 1424\n" + "1548000 1290\n" + "1704000 9931\n"}, + {.path = "/sys/devices/system/cpu/cpu3/cpufreq/stats/total_trans", .size = 7, .content = "116188\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/core_id", .size = 2, .content = "3\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/core_siblings_list", .size = 2, .content = "3\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/cluster_cpus", .size = 4, .content = "00f\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/cluster_cpus_list", .size = 4, .content = "0-3\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/physical_package_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/thread_siblings", .size = 4, .content = "008\n"}, + {.path = "/sys/devices/system/cpu/cpu3/topology/thread_siblings_list", .size = 2, .content = "3\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/affected_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/related_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_available_frequencies", + .size = 115, + .content = + "402000 578000 697000 712000 910000 1065000 1221000 1328000 1418000 1572000 1836000 1945000 2130000 2245000 2367000 \n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq", .size = 8, .content = "2130000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/stats/time_in_state", + .size = 194, + .content = "402000 1023353\n" + "578000 3901\n" + "697000 2240\n" + "712000 282\n" + "910000 8163\n" + "1065000 2924\n" + "1221000 2351\n" + "1328000 1368\n" + "1418000 1272\n" + "1572000 6658\n" + "1836000 12747\n" + "1945000 4128\n" + "2130000 2880\n" + "2245000 1570\n" + "2367000 15230\n"}, + {.path = "/sys/devices/system/cpu/cpu4/cpufreq/stats/total_trans", .size = 6, .content = "62643\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/core_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/core_siblings_list", .size = 2, .content = "4\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/cluster_cpus", .size = 4, .content = "0f0\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/cluster_cpus_list", .size = 4, .content = "4-7\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/physical_package_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/thread_siblings", .size = 4, .content = "010\n"}, + {.path = "/sys/devices/system/cpu/cpu4/topology/thread_siblings_list", .size = 2, .content = "4\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/affected_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/related_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_available_frequencies", + .size = 115, + .content = + "402000 578000 697000 712000 910000 1065000 1221000 1328000 1418000 1572000 1836000 1945000 2130000 2245000 2367000 \n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_cur_freq", .size = 8, .content = "1945000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/scaling_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/stats/time_in_state", + .size = 194, + .content = "402000 1023895\n" + "578000 3911\n" + "697000 2240\n" + "712000 282\n" + "910000 8163\n" + "1065000 2924\n" + "1221000 2355\n" + "1328000 1368\n" + "1418000 1272\n" + "1572000 6684\n" + "1836000 12823\n" + "1945000 4147\n" + "2130000 2894\n" + "2245000 1571\n" + "2367000 15301\n"}, + {.path = "/sys/devices/system/cpu/cpu5/cpufreq/stats/total_trans", .size = 6, .content = "62928\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/core_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/core_siblings_list", .size = 2, .content = "5\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/cluster_cpus", .size = 4, .content = "0f0\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/cluster_cpus_list", .size = 4, .content = "4-7\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/physical_package_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/thread_siblings", .size = 4, .content = "020\n"}, + {.path = "/sys/devices/system/cpu/cpu5/topology/thread_siblings_list", .size = 2, .content = "5\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/affected_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/cpuinfo_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/cpuinfo_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/related_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_available_frequencies", + .size = 115, + .content = + "402000 578000 697000 712000 910000 1065000 1221000 1328000 1418000 1572000 1836000 1945000 2130000 2245000 2367000 \n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_cur_freq", .size = 8, .content = "1945000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/scaling_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/stats/time_in_state", + .size = 194, + .content = "402000 1024410\n" + "578000 3922\n" + "697000 2240\n" + "712000 282\n" + "910000 8163\n" + "1065000 2924\n" + "1221000 2355\n" + "1328000 1368\n" + "1418000 1277\n" + "1572000 6718\n" + "1836000 12892\n" + "1945000 4164\n" + "2130000 2901\n" + "2245000 1571\n" + "2367000 15400\n"}, + {.path = "/sys/devices/system/cpu/cpu6/cpufreq/stats/total_trans", .size = 6, .content = "63222\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/core_id", .size = 2, .content = "2\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/core_siblings_list", .size = 2, .content = "6\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/cluster_cpus", .size = 4, .content = "0f0\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/cluster_cpus_list", .size = 4, .content = "4-7\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/physical_package_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/thread_siblings", .size = 4, .content = "040\n"}, + {.path = "/sys/devices/system/cpu/cpu6/topology/thread_siblings_list", .size = 2, .content = "6\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/affected_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/related_cpus", .size = 8, .content = "4 5 6 7\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_available_frequencies", + .size = 115, + .content = + "402000 578000 697000 712000 910000 1065000 1221000 1328000 1418000 1572000 1836000 1945000 2130000 2245000 2367000 \n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_cur_freq", .size = 8, .content = "2130000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_max_freq", .size = 8, .content = "2367000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/scaling_min_freq", .size = 7, .content = "402000\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/stats/time_in_state", + .size = 194, + .content = "402000 1024939\n" + "578000 3931\n" + "697000 2242\n" + "712000 282\n" + "910000 8170\n" + "1065000 2925\n" + "1221000 2355\n" + "1328000 1368\n" + "1418000 1277\n" + "1572000 6747\n" + "1836000 12967\n" + "1945000 4185\n" + "2130000 2918\n" + "2245000 1571\n" + "2367000 15468\n"}, + {.path = "/sys/devices/system/cpu/cpu7/cpufreq/stats/total_trans", .size = 6, .content = "63514\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/core_id", .size = 2, .content = "3\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/core_siblings_list", .size = 2, .content = "7\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/cluster_cpus", .size = 4, .content = "0f0\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/cluster_cpus_list", .size = 4, .content = "4-7\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/physical_package_id", .size = 2, .content = "1\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/thread_siblings", .size = 4, .content = "080\n"}, + {.path = "/sys/devices/system/cpu/cpu7/topology/thread_siblings_list", .size = 2, .content = "7\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpuidle/driver/name", .size = 10, .content = "psci_idle\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/affected_cpus", .size = 2, .content = "8\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/cpuinfo_max_freq", .size = 8, .content = "2914000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/cpuinfo_min_freq", .size = 7, .content = "500000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/cpuinfo_transition_latency", .size = 8, .content = "5000000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/related_cpus", .size = 2, .content = "8\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_available_frequencies", + .size = 115, + .content = + "500000 880000 1164000 1298000 1557000 1745000 1885000 2049000 2147000 2294000 2363000 2556000 2687000 2850000 2914000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_available_governors", + .size = 57, + .content = "sched_pixel conservative powersave performance schedutil \n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_cur_freq", .size = 7, .content = "500000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_driver", .size = 15, .content = "exynos_cpufreq\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_governor", .size = 12, .content = "sched_pixel\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_max_freq", .size = 8, .content = "2914000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/scaling_min_freq", .size = 7, .content = "500000\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/stats/time_in_state", + .size = 188, + .content = "500000 1530909\n" + "880000 3209\n" + "1164000 1553\n" + "1298000 885\n" + "1557000 2004\n" + "1745000 1410\n" + "1885000 631\n" + "2049000 4090\n" + "2147000 278\n" + "2294000 522\n" + "2363000 228\n" + "2556000 525\n" + "2687000 311\n" + "2850000 940\n" + "2914000 3929\n"}, + {.path = "/sys/devices/system/cpu/cpu8/cpufreq/stats/total_trans", .size = 6, .content = "18185\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/core_id", .size = 2, .content = "0\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/core_siblings_list", .size = 2, .content = "8\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/cluster_cpus", .size = 4, .content = "f00\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/cluster_cpus_list", .size = 2, .content = "8\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/physical_package_id", .size = 2, .content = "2\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/thread_siblings", .size = 4, .content = "100\n"}, + {.path = "/sys/devices/system/cpu/cpu8/topology/thread_siblings_list", .size = 2, .content = "8\n"}, + {NULL}, +}; +#ifdef __ANDROID__ +struct cpuinfo_mock_property properties[] = { + { + .key = "aaudio.hw_burst_min_usec", + .value = "2000", + }, + { + .key = "aaudio.mmap_exclusive_policy", + .value = "2", + }, + { + .key = "aaudio.mmap_policy", + .value = "2", + }, + { + .key = "dalvik.vm.appimageformat", + .value = "lz4", + }, + { + .key = "dalvik.vm.dex2oat-Xms", + .value = "64m", + }, + { + .key = "dalvik.vm.dex2oat-Xmx", + .value = "512m", + }, + { + .key = "dalvik.vm.dexopt.secondary", + .value = "true", + }, + { + .key = "dalvik.vm.heapgrowthlimit", + .value = "256m", + }, + { + .key = "dalvik.vm.heapmaxfree", + .value = "32m", + }, + { + .key = "dalvik.vm.heapminfree", + .value = "8m", + }, + { + .key = "dalvik.vm.heapsize", + .value = "512m", + }, + { + .key = "dalvik.vm.heapstartsize", + .value = "16m", + }, + { + .key = "dalvik.vm.heaptargetutilization", + .value = "0.5", + }, + { + .key = "dalvik.vm.image-dex2oat-Xms", + .value = "64m", + }, + { + .key = "dalvik.vm.image-dex2oat-Xmx", + .value = "64m", + }, + { + .key = "dalvik.vm.isa.arm64.features", + .value = "default", + }, + { + .key = "dalvik.vm.isa.arm64.variant", + .value = "cortex-a55", + }, + { + .key = "dalvik.vm.usejit", + .value = "true", + }, + { + .key = "debug.atrace.tags.enableflags", + .value = "0", + }, + { + .key = "debug.force_rtl", + .value = "false", + }, + { + .key = "dev.bootcomplete", + .value = "1", + }, + { + .key = "drm.service.enabled", + .value = "true", + }, + { + .key = "gsm.current.phone-type", + .value = "1,1", + }, + { + .key = "gsm.network.type", + .value = "IWLAN,IWLAN", + }, + { + .key = "gsm.operator.alpha", + .value = ",", + }, + { + .key = "gsm.operator.iso-country", + .value = "us,", + }, + { + .key = "gsm.operator.isroaming", + .value = "false,false", + }, + { + .key = "gsm.operator.numeric", + .value = ",", + }, + { + .key = "gsm.sim.operator.alpha", + .value = ",", + }, + { + .key = "gsm.sim.operator.iso-country", + .value = ",", + }, + { + .key = "gsm.sim.operator.numeric", + .value = ",", + }, + { + .key = "gsm.sim.state", + .value = "ABSENT,NOT_READY", + }, + { + .key = "gsm.version.baseband", + .value = "g5300i-230927-231102-B-11040898,g5300i-230927-231102-B-11040898", + }, + { + .key = "gsm.version.ril-impl", + .value = "Samsung S.LSI Vendor RIL V2.3 Build 2023-12-12 01:31:33", + }, + { + .key = "hwservicemanager.ready", + .value = "true", + }, + { + .key = "init.svc.adbd", + .value = "running", + }, + { + .key = "init.svc.audioserver", + .value = "running", + }, + { + .key = "init.svc.bootanim", + .value = "stopped", + }, + { + .key = "init.svc.cameraserver", + .value = "running", + }, + { + .key = "init.svc.drm", + .value = "running", + }, + { + .key = "init.svc.gatekeeperd", + .value = "running", + }, + { + .key = "init.svc.gnss_service", + .value = "running", + }, + { + .key = "init.svc.hidl_memory", + .value = "running", + }, + { + .key = "init.svc.hwservicemanager", + .value = "running", + }, + { + .key = "init.svc.init-radio-sh", + .value = "stopped", + }, + { + .key = "init.svc.insmod_sh", + .value = "stopped", + }, + { + .key = "init.svc.installd", + .value = "running", + }, + { + .key = "init.svc.lmkd", + .value = "running", + }, + { + .key = "init.svc.logd", + .value = "running", + }, + { + .key = "init.svc.logd-reinit", + .value = "stopped", + }, + { + .key = "init.svc.media", + .value = "running", + }, + { + .key = "init.svc.mediadrm", + .value = "running", + }, + { + .key = "init.svc.mediaextractor", + .value = "running", + }, + { + .key = "init.svc.mediametrics", + .value = "running", + }, + { + .key = "init.svc.netd", + .value = "running", + }, + { + .key = "init.svc.nfc_hal_service", + .value = "running", + }, + { + .key = "init.svc.ril-daemon", + .value = "running", + }, + { + .key = "init.svc.servicemanager", + .value = "running", + }, + { + .key = "init.svc.storaged", + .value = "running", + }, + { + .key = "init.svc.surfaceflinger", + .value = "running", + }, + { + .key = "init.svc.tombstoned", + .value = "running", + }, + { + .key = "init.svc.ueventd", + .value = "running", + }, + { + .key = "init.svc.update_engine", + .value = "running", + }, + { + .key = "init.svc.update_verifier_nonencrypted", + .value = "stopped", + }, + { + .key = "init.svc.vndservicemanager", + .value = "running", + }, + { + .key = "init.svc.vold", + .value = "running", + }, + { + .key = "init.svc.wificond", + .value = "running", + }, + { + .key = "init.svc.wpa_supplicant", + .value = "running", + }, + { + .key = "init.svc.zygote", + .value = "running", + }, + { + .key = "keyguard.no_require_sim", + .value = "true", + }, + { + .key = "media.mediadrmservice.enable", + .value = "true", + }, + { + .key = "net.bt.name", + .value = "Android", + }, + { + .key = "nfc.initialized", + .value = "true", + }, + { + .key = "partition.system.verified", + .value = "2", + }, + { + .key = "partition.vendor.verified", + .value = "2", + }, + { + .key = "persist.sys.dalvik.vm.lib.2", + .value = "libart.so", + }, + { + .key = "persist.sys.sf.color_saturation", + .value = "1.0", + }, + { + .key = "persist.sys.timezone", + .value = "America/Los_Angeles", + }, + { + .key = "persist.sys.usb.config", + .value = "adb", + }, + { + .key = "pm.dexopt.ab-ota", + .value = "speed-profile", + }, + { + .key = "pm.dexopt.bg-dexopt", + .value = "speed-profile", + }, + { + .key = "pm.dexopt.first-boot", + .value = "verify", + }, + { + .key = "pm.dexopt.inactive", + .value = "verify", + }, + { + .key = "pm.dexopt.install", + .value = "speed-profile", + }, + { + .key = "pm.dexopt.shared", + .value = "speed", + }, + { + .key = "ro.adb.secure", + .value = "1", + }, + { + .key = "ro.allow.mock.location", + .value = "0", + }, + { + .key = "ro.atrace.core.services", + .value = "com.google.android.gms,com.google.android.gms.ui,com.google.android.gms.persistent", + }, + { + .key = "ro.audio.monitorRotation", + .value = "true", + }, + { + .key = "ro.baseband", + .value = "unknown", + }, + { + .key = "ro.board.platform", + .value = "zuma", + }, + { + .key = "ro.boot.avb_version", + .value = "1.2", + }, + { + .key = "ro.boot.bootdevice", + .value = "13200000.ufs", + }, + { + .key = "ro.boot.bootloader", + .value = "ripcurrent-14.1-11012321", + }, + { + .key = "ro.boot.bootreason", + .value = "reboot", + }, + { + .key = "ro.boot.boottime", + .value = + "0BLE:112,1BLL:7,1BLE:73,2BLL:28,2BLE:557,3BLL:314,3BLE:194,SW:10058,KL:13,KD:0,ODT:62,AVB:96,FWL:149", + }, + { + .key = "ro.boot.ddr_info", + .value = "Micron", + }, + { + .key = "ro.boot.ddr_size", + .value = "8GiB", + }, + { + .key = "ro.boot.flash.locked", + .value = "0", + }, + { + .key = "ro.boot.hardware", + .value = "shiba", + }, + { + .key = "ro.boot.hardware.color", + .value = "HAZ", + }, + { + .key = "ro.boot.hardware.revision", + .value = "MP1.0", + }, + { + .key = "ro.boot.hardware.sku", + .value = "G9BQD", + }, + { + .key = "ro.boot.hardware.ufs", + .value = "128GB,Micron", + }, + { + .key = "ro.boot.revision", + .value = "MP1.0", + }, + { + .key = "ro.boot.serialno", + .value = "39061FDJH005AB", + }, + { + .key = "ro.boot.slot_suffix", + .value = "_a", + }, + { + .key = "ro.boot.vbmeta.avb_version", + .value = "1.2", + }, + { + .key = "ro.boot.vbmeta.device_state", + .value = "unlocked", + }, + { + .key = "ro.boot.vbmeta.digest", + .value = "64384054dbd4c6c629c119818f784bf515a4a9996c14f3bb7b314a6267fc7706", + }, + { + .key = "ro.boot.vbmeta.hash_alg", + .value = "sha256", + }, + { + .key = "ro.boot.vbmeta.size", + .value = "16512", + }, + { + .key = "ro.boot.verifiedbootstate", + .value = "orange", + }, + { + .key = "ro.boot.veritymode", + .value = "enforcing", + }, + { + .key = "ro.boot.wificountrycode", + .value = "00", + }, + { + .key = "ro.bootimage.build.date", + .value = "Tue Dec 12 05:18:54 UTC 2023", + }, + { + .key = "ro.bootimage.build.date.utc", + .value = "1702358334", + }, + { + .key = "ro.bootimage.build.fingerprint", + .value = "google/shiba/shiba:14/UQ1A.240105.004/11206848:userdebug/dev-keys", + }, + { + .key = "ro.bootloader", + .value = "ripcurrent-14.1-11012321", + }, + { + .key = "ro.bootmode", + .value = "unknown", + }, + { + .key = "ro.build.ab_update", + .value = "true", + }, + { + .key = "ro.build.characteristics", + .value = "nosdcard", + }, + { + .key = "ro.build.date", + .value = "Tue Dec 12 05:18:54 UTC 2023", + }, + { + .key = "ro.build.date.utc", + .value = "1702358334", + }, + { + .key = "ro.build.description", + .value = "shiba-userdebug 14 UQ1A.240105.004 11206848 dev-keys", + }, + { + .key = "ro.build.display.id", + .value = "shiba-userdebug 14 UQ1A.240105.004 11206848 dev-keys", + }, + { + .key = "ro.build.expect.baseband", + .value = "g5300i-230927-231102-B-11040898", + }, + { + .key = "ro.build.expect.bootloader", + .value = "ripcurrent-14.1-11012321", + }, + { + .key = "ro.build.fingerprint", + .value = "google/shiba/shiba:14/UQ1A.240105.004/11206848:userdebug/dev-keys", + }, + { + .key = "ro.build.flavor", + .value = "shiba-userdebug", + }, + { + .key = "ro.build.host", + .value = "abfarm-release-rbe-32-2004-00107", + }, + { + .key = "ro.build.id", + .value = "UQ1A.240105.004", + }, + { + .key = "ro.build.product", + .value = "shiba", + }, + { + .key = "ro.build.tags", + .value = "dev-keys", + }, + { + .key = "ro.build.type", + .value = "userdebug", + }, + { + .key = "ro.build.user", + .value = "android-build", + }, + { + .key = "ro.build.version.all_codenames", + .value = "REL", + }, + { + .key = "ro.build.version.codename", + .value = "REL", + }, + { + .key = "ro.build.version.incremental", + .value = "11206848", + }, + { + .key = "ro.build.version.preview_sdk", + .value = "0", + }, + { + .key = "ro.build.version.release", + .value = "14", + }, + { + .key = "ro.build.version.sdk", + .value = "34", + }, + { + .key = "ro.build.version.security_patch", + .value = "2024-01-05", + }, + { + .key = "ro.carrier", + .value = "unknown", + }, + { + .key = "ro.com.android.dataroaming", + .value = "false", + }, + { + .key = "ro.com.android.prov_mobiledata", + .value = "false", + }, + { + .key = "ro.com.google.clientidbase", + .value = "android-google", + }, + { + .key = "ro.com.google.ime.theme_id", + .value = "5", + }, + { + .key = "ro.config.alarm_alert", + .value = "Fresh_start.ogg", + }, + { + .key = "ro.config.media_vol_steps", + .value = "25", + }, + { + .key = "ro.config.notification_sound", + .value = "Eureka.ogg", + }, + { + .key = "ro.config.ringtone", + .value = "Your_new_adventure.ogg", + }, + { + .key = "ro.config.vc_call_vol_steps", + .value = "7", + }, + { + .key = "ro.control_privapp_permissions", + .value = "enforce", + }, + { + .key = "ro.crypto.state", + .value = "encrypted", + }, + { + .key = "ro.crypto.type", + .value = "file", + }, + { + .key = "ro.dalvik.vm.native.bridge", + .value = "0", + }, + { + .key = "ro.debuggable", + .value = "1", + }, + { + .key = "ro.error.receiver.system.apps", + .value = "com.google.android.gms", + }, + { + .key = "ro.frp.pst", + .value = "/dev/block/by-name/frp", + }, + { + .key = "ro.hardware", + .value = "shiba", + }, + { + .key = "ro.oem_unlock_supported", + .value = "1", + }, + { + .key = "ro.opa.eligible_device", + .value = "true", + }, + { + .key = "ro.opengles.version", + .value = "196610", + }, + { + .key = "ro.product.board", + .value = "shiba", + }, + { + .key = "ro.product.brand", + .value = "google", + }, + { + .key = "ro.product.cpu.abi", + .value = "arm64-v8a", + }, + { + .key = "ro.product.cpu.abilist", + .value = "arm64-v8a", + }, + { + .key = "ro.product.cpu.abilist64", + .value = "arm64-v8a", + }, + { + .key = "ro.product.device", + .value = "shiba", + }, + { + .key = "ro.product.first_api_level", + .value = "34", + }, + { + .key = "ro.product.locale", + .value = "en-US", + }, + { + .key = "ro.product.manufacturer", + .value = "Google", + }, + { + .key = "ro.product.model", + .value = "Pixel 8", + }, + { + .key = "ro.product.name", + .value = "shiba", + }, + { + .key = "ro.property_service.version", + .value = "2", + }, + { + .key = "ro.revision", + .value = "MP1.0", + }, + { + .key = "ro.secure", + .value = "1", + }, + { + .key = "ro.serialno", + .value = "39061FDJH005AB", + }, + { + .key = "ro.setupwizard.enterprise_mode", + .value = "1", + }, + { + .key = "ro.setupwizard.esim_cid_ignore", + .value = "00000001", + }, + { + .key = "ro.sf.lcd_density", + .value = "420", + }, + { + .key = "ro.storage_manager.enabled", + .value = "false", + }, + { + .key = "ro.telephony.default_network", + .value = "27", + }, + { + .key = "ro.treble.enabled", + .value = "true", + }, + { + .key = "ro.vendor.build.date", + .value = "Tue Dec 12 05:18:54 UTC 2023", + }, + { + .key = "ro.vendor.build.date.utc", + .value = "1702358334", + }, + { + .key = "ro.vendor.build.fingerprint", + .value = "google/shiba/shiba:14/UQ1A.240105.004/11206848:userdebug/dev-keys", + }, + { + .key = "ro.zygote", + .value = "zygote64", + }, + { + .key = "security.perf_harden", + .value = "1", + }, + { + .key = "selinux.restorecon_recursive", + .value = "/data/misc_ce/0", + }, + { + .key = "service.bootanim.exit", + .value = "1", + }, + { + .key = "service.sf.present_timestamp", + .value = "1", + }, + { + .key = "setupwizard.theme", + .value = "glif_v4_light", + }, + { + .key = "sys.boot_completed", + .value = "1", + }, + { + .key = "sys.oem_unlock_allowed", + .value = "1", + }, + { + .key = "sys.rescue_boot_count", + .value = "1", + }, + { + .key = "sys.retaildemo.enabled", + .value = "0", + }, + { + .key = "sys.sysctl.extra_free_kbytes", + .value = "30375", + }, + { + .key = "sys.usb.config", + .value = "adb", + }, + { + .key = "sys.usb.configfs", + .value = "2", + }, + { + .key = "sys.usb.controller", + .value = "11210000.dwc3", + }, + { + .key = "sys.usb.ffs.ready", + .value = "1", + }, + { + .key = "sys.usb.mtp.device_type", + .value = "3", + }, + { + .key = "sys.user.0.ce_available", + .value = "true", + }, + { + .key = "sys.wifitracing.started", + .value = "1", + }, + { + .key = "vold.has_adoptable", + .value = "0", + }, + { + .key = "vold.has_quota", + .value = "1", + }, + {NULL}, +}; +#endif /* __ANDROID__ */ diff --git a/tools/cpu-info.c b/tools/cpu-info.c index a4ace204..b0fec240 100644 --- a/tools/cpu-info.c +++ b/tools/cpu-info.c @@ -336,6 +336,39 @@ int main(int argc, char** argv) { printf(", %s %s\n", vendor_string, uarch_string); } } + printf("Clusters:\n"); + for (uint32_t i = 0; i < cpuinfo_get_clusters_count(); i++) { + const struct cpuinfo_cluster* cluster = cpuinfo_get_cluster(i); + if (cluster->processor_count == 1) { + printf("\t%" PRIu32 ": 1 processor (%" PRIu32 ")", i, cluster->processor_start); + } else { + printf("\t%" PRIu32 ": %" PRIu32 " processors (%" PRIu32 "-%" PRIu32 ")", + i, + cluster->processor_count, + cluster->processor_start, + cluster->processor_start + cluster->processor_count - 1); + } + if (cluster->core_count == 1) { + printf(",\t%" PRIu32 ": 1 core (%" PRIu32 ")", i, cluster->core_start); + } else { + printf(",\t%" PRIu32 ": %" PRIu32 " cores (%" PRIu32 "-%" PRIu32 ")", + i, + cluster->core_count, + cluster->core_start, + cluster->core_start + cluster->core_count - 1); + } + const char* vendor_string = vendor_to_string(cluster->vendor); + const char* uarch_string = uarch_to_string(cluster->uarch); + if (vendor_string == NULL) { + printf(", vendor 0x%08" PRIx32 " uarch 0x%08" PRIx32 "\n", + (uint32_t)cluster->vendor, + (uint32_t)cluster->uarch); + } else if (uarch_string == NULL) { + printf(", %s uarch 0x%08" PRIx32 "\n", vendor_string, (uint32_t)cluster->uarch); + } else { + printf(", %s %s\n", vendor_string, uarch_string); + } + } printf("Logical processors"); #if defined(__linux__) printf(" (System ID)"); From 05332fd802d9109a2a151ec32154b107c1e5caf9 Mon Sep 17 00:00:00 2001 From: cyyever Date: Mon, 3 Jun 2024 00:13:58 +0800 Subject: [PATCH 02/25] add FreeBSD support (#172) --- BUILD.bazel | 17 ++ CMakeLists.txt | 14 +- src/cpuinfo/internal-api.h | 1 + src/freebsd/api.h | 12 ++ src/freebsd/topology.c | 104 ++++++++++ src/init.c | 2 + src/x86/freebsd/init.c | 382 +++++++++++++++++++++++++++++++++++++ 7 files changed, 530 insertions(+), 2 deletions(-) create mode 100644 src/freebsd/api.h create mode 100644 src/freebsd/topology.c create mode 100644 src/x86/freebsd/init.c diff --git a/BUILD.bazel b/BUILD.bazel index 4e3ea999..2c6375fd 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -63,6 +63,10 @@ MACH_SRCS = [ "src/mach/topology.c", ] +FREEBSD_SRCS = [ + "src/freebsd/topology.c", +] + EMSCRIPTEN_SRCS = [ "src/emscripten/init.c", ] @@ -112,6 +116,10 @@ MACH_ARM_SRCS = [ "src/arm/mach/init.c", ] +FREEBSD_X86_SRCS = [ + "src/x86/freebsd/init.c", +] + EMSCRIPTEN_SRCS = [ "src/emscripten/init.c", ] @@ -132,6 +140,7 @@ cc_library( ":macos_x86_64": COMMON_SRCS + X86_SRCS + MACH_SRCS + MACH_X86_SRCS, ":macos_x86_64_legacy": COMMON_SRCS + X86_SRCS + MACH_SRCS + MACH_X86_SRCS, ":macos_arm64": COMMON_SRCS + MACH_SRCS + MACH_ARM_SRCS, + ":freebsd_x86_64": COMMON_SRCS + X86_SRCS + FREEBSD_SRCS + FREEBSD_X86_SRCS, ":windows_x86_64": COMMON_SRCS + X86_SRCS + WINDOWS_X86_SRCS, ":windows_arm64": COMMON_SRCS + ARM_SRCS + WINDOWS_ARM_SRCS, ":android_armv7": COMMON_SRCS + ARM_SRCS + LINUX_SRCS + LINUX_ARM32_SRCS + ANDROID_ARM_SRCS, @@ -175,6 +184,7 @@ cc_library( # Headers must be in textual_hdrs to allow us to set the standard to C99 textual_hdrs = [ "include/cpuinfo.h", + "src/freebsd/api.h", "src/linux/api.h", "src/mach/api.h", "src/cpuinfo/common.h", @@ -463,3 +473,10 @@ config_setting( "cpu": "asmjs", }, ) + +config_setting( + name = "freebsd_x86_64", + values = { + "cpu": "freebsd", + }, +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99047e58..e505e5a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,9 @@ ENDIF() # -- [ Determine target processor SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}") +IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND CPUINFO_TARGET_PROCESSOR STREQUAL "amd64") + SET(CPUINFO_TARGET_PROCESSOR "AMD64") +ENDIF() IF(IS_APPLE_OS AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64.*)$") SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}") ELSEIF(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_VS_PLATFORM_NAME) @@ -105,7 +108,7 @@ IF(NOT CMAKE_SYSTEM_NAME) "Target operating system is not specified. " "cpuinfo will compile, but cpuinfo_initialize() will always fail.") SET(CPUINFO_SUPPORTED_PLATFORM FALSE) -ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android)$") +ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android|FreeBSD)$") IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14" AND NOT IS_APPLE_OS) MESSAGE(WARNING "Target operating system \"${CMAKE_SYSTEM_NAME}\" is not supported in cpuinfo. " @@ -178,6 +181,8 @@ IF(CPUINFO_SUPPORTED_PLATFORM) LIST(APPEND CPUINFO_SRCS src/x86/mach/init.c) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS)$") LIST(APPEND CPUINFO_SRCS src/x86/windows/init.c) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + LIST(APPEND CPUINFO_SRCS src/x86/freebsd/init.c) ENDIF() ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^Windows" AND CPUINFO_TARGET_PROCESSOR MATCHES "^(ARM64|arm64)$") LIST(APPEND CPUINFO_SRCS @@ -234,9 +239,11 @@ IF(CPUINFO_SUPPORTED_PLATFORM) src/linux/processors.c) ELSEIF(IS_APPLE_OS) LIST(APPEND CPUINFO_SRCS src/mach/topology.c) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + LIST(APPEND CPUINFO_SRCS src/freebsd/topology.c) ENDIF() - IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) SET(THREADS_PREFER_PTHREAD_FLAG TRUE) FIND_PACKAGE(Threads REQUIRED) @@ -301,6 +308,9 @@ IF(CPUINFO_SUPPORTED_PLATFORM) TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT}) TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _GNU_SOURCE=1) TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _GNU_SOURCE=1) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + TARGET_LINK_LIBRARIES(cpuinfo PUBLIC ${CMAKE_THREAD_LIBS_INIT}) + TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT}) ENDIF() ELSE() TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=0) diff --git a/src/cpuinfo/internal-api.h b/src/cpuinfo/internal-api.h index d566034e..d84b26a8 100644 --- a/src/cpuinfo/internal-api.h +++ b/src/cpuinfo/internal-api.h @@ -49,6 +49,7 @@ extern CPUINFO_INTERNAL const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_ma CPUINFO_PRIVATE void cpuinfo_x86_mach_init(void); CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void); +CPUINFO_PRIVATE void cpuinfo_x86_freebsd_init(void); #if defined(_WIN32) || defined(__CYGWIN__) #if CPUINFO_ARCH_ARM64 CPUINFO_PRIVATE BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context); diff --git a/src/freebsd/api.h b/src/freebsd/api.h new file mode 100644 index 00000000..d3774370 --- /dev/null +++ b/src/freebsd/api.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct cpuinfo_freebsd_topology { + uint32_t packages; + uint32_t cores; + uint32_t threads; + uint32_t threads_per_core; +}; + +struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void); diff --git a/src/freebsd/topology.c b/src/freebsd/topology.c new file mode 100644 index 00000000..da941e9c --- /dev/null +++ b/src/freebsd/topology.c @@ -0,0 +1,104 @@ +#include +#include +#include + +#include +#include + +#include +#include + +static int sysctl_int(const char* name) { + int value = 0; + size_t value_size = sizeof(value); + if (sysctlbyname(name, &value, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); + } else if (value <= 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value %d %zu", name, value, value_size); + value = 0; + } + return value; +} + +static char* sysctl_str(const char* name) { + size_t value_size = 0; + if (sysctlbyname(name, NULL, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); + } else if (value_size <= 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value size %zu", name, value_size); + } + value_size += 1; + char* value = calloc(value_size, 1); + if (!value) { + cpuinfo_log_error("calloc %zu bytes failed", value_size); + return NULL; + } + if (sysctlbyname(name, value, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); + free(value); + return NULL; + } + return value; +} + +struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { + struct cpuinfo_freebsd_topology topology = { + .packages = 0, + .cores = 0, + .threads_per_core = 0, + .threads = 0, + }; + char* topology_spec = sysctl_str("kern.sched.topology_spec"); + if (!topology_spec) { + return topology; + } + const char* group_tag = ""; + char* p = strstr(topology_spec, group_tag); + while (p) { + const char* cpu_tag = "cpu count=\""; + char* q = strstr(p, cpu_tag); + if (q) { + p = q + strlen(cpu_tag); + topology.packages += atoi(p); + } else { + break; + } + } + if (topology.packages == 0) { + const char* group_tag = " +#include +#include + +#include +#include +#include +#include +#include + +static inline uint32_t max(uint32_t a, uint32_t b) { + return a > b ? a : b; +} + +static inline uint32_t bit_mask(uint32_t bits) { + return (UINT32_C(1) << bits) - UINT32_C(1); +} + +void cpuinfo_x86_freebsd_init(void) { + struct cpuinfo_processor* processors = NULL; + struct cpuinfo_core* cores = NULL; + struct cpuinfo_cluster* clusters = NULL; + struct cpuinfo_package* packages = NULL; + struct cpuinfo_cache* l1i = NULL; + struct cpuinfo_cache* l1d = NULL; + struct cpuinfo_cache* l2 = NULL; + struct cpuinfo_cache* l3 = NULL; + struct cpuinfo_cache* l4 = NULL; + + struct cpuinfo_freebsd_topology freebsd_topology = cpuinfo_freebsd_detect_topology(); + if (freebsd_topology.packages == 0) { + cpuinfo_log_error("failed to detect topology"); + goto cleanup; + } + processors = calloc(freebsd_topology.threads, sizeof(struct cpuinfo_processor)); + if (processors == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 " logical processors", + freebsd_topology.threads * sizeof(struct cpuinfo_processor), + freebsd_topology.threads); + goto cleanup; + } + cores = calloc(freebsd_topology.cores, sizeof(struct cpuinfo_core)); + if (cores == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 " cores", + freebsd_topology.cores * sizeof(struct cpuinfo_core), + freebsd_topology.cores); + goto cleanup; + } + /* On x86 a cluster of cores is the biggest group of cores that shares a + * cache. */ + clusters = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_cluster)); + if (clusters == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 " core clusters", + freebsd_topology.packages * sizeof(struct cpuinfo_cluster), + freebsd_topology.packages); + goto cleanup; + } + packages = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_package)); + if (packages == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 " physical packages", + freebsd_topology.packages * sizeof(struct cpuinfo_package), + freebsd_topology.packages); + goto cleanup; + } + + struct cpuinfo_x86_processor x86_processor; + memset(&x86_processor, 0, sizeof(x86_processor)); + cpuinfo_x86_init_processor(&x86_processor); + char brand_string[48]; + cpuinfo_x86_normalize_brand_string(x86_processor.brand_string, brand_string); + + const uint32_t threads_per_core = freebsd_topology.threads_per_core; + const uint32_t threads_per_package = freebsd_topology.threads / freebsd_topology.packages; + const uint32_t cores_per_package = freebsd_topology.cores / freebsd_topology.packages; + for (uint32_t i = 0; i < freebsd_topology.packages; i++) { + clusters[i] = (struct cpuinfo_cluster){ + .processor_start = i * threads_per_package, + .processor_count = threads_per_package, + .core_start = i * cores_per_package, + .core_count = cores_per_package, + .cluster_id = 0, + .package = packages + i, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + }; + packages[i].processor_start = i * threads_per_package; + packages[i].processor_count = threads_per_package; + packages[i].core_start = i * cores_per_package; + packages[i].core_count = cores_per_package; + packages[i].cluster_start = i; + packages[i].cluster_count = 1; + cpuinfo_x86_format_package_name(x86_processor.vendor, brand_string, packages[i].name); + } + for (uint32_t i = 0; i < freebsd_topology.cores; i++) { + cores[i] = (struct cpuinfo_core){ + .processor_start = i * threads_per_core, + .processor_count = threads_per_core, + .core_id = i % cores_per_package, + .cluster = clusters + i / cores_per_package, + .package = packages + i / cores_per_package, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + }; + } + for (uint32_t i = 0; i < freebsd_topology.threads; i++) { + const uint32_t smt_id = i % threads_per_core; + const uint32_t core_id = i / threads_per_core; + const uint32_t package_id = i / threads_per_package; + + /* Reconstruct APIC IDs from topology components */ + const uint32_t thread_bits_mask = bit_mask(x86_processor.topology.thread_bits_length); + const uint32_t core_bits_mask = bit_mask(x86_processor.topology.core_bits_length); + const uint32_t package_bits_offset = + max(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 apic_id = ((smt_id & thread_bits_mask) << x86_processor.topology.thread_bits_offset) | + ((core_id & core_bits_mask) << x86_processor.topology.core_bits_offset) | + (package_id << package_bits_offset); + cpuinfo_log_debug("reconstructed APIC ID 0x%08" PRIx32 " for thread %" PRIu32, apic_id, i); + + processors[i].smt_id = smt_id; + processors[i].core = cores + i / threads_per_core; + processors[i].cluster = clusters + i / threads_per_package; + processors[i].package = packages + i / threads_per_package; + processors[i].apic_id = apic_id; + } + + uint32_t threads_per_l1 = 0, l1_count = 0; + if (x86_processor.cache.l1i.size != 0 || x86_processor.cache.l1d.size != 0) { + /* Assume that threads on the same core share L1 */ + threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores; + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L1 cache; assume %" PRIu32, + threads_per_l1); + l1_count = freebsd_topology.threads / threads_per_l1; + cpuinfo_log_debug("detected %" PRIu32 " L1 caches", l1_count); + } + + uint32_t threads_per_l2 = 0, l2_count = 0; + if (x86_processor.cache.l2.size != 0) { + if (x86_processor.cache.l3.size != 0) { + /* This is not a last-level cache; assume that threads + * on the same core share L2 */ + threads_per_l2 = freebsd_topology.threads / freebsd_topology.cores; + } else { + /* This is a last-level cache; assume that threads on + * the same package share L2 */ + threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages; + } + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L2 cache; assume %" PRIu32, + threads_per_l2); + l2_count = freebsd_topology.threads / threads_per_l2; + cpuinfo_log_debug("detected %" PRIu32 " L2 caches", l2_count); + } + + uint32_t threads_per_l3 = 0, l3_count = 0; + if (x86_processor.cache.l3.size != 0) { + /* + * Assume that threads on the same package share L3. + * However, is it not necessarily the last-level cache (there + * may be L4 cache as well) + */ + threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages; + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L3 cache; assume %" PRIu32, + threads_per_l3); + l3_count = freebsd_topology.threads / threads_per_l3; + cpuinfo_log_debug("detected %" PRIu32 " L3 caches", l3_count); + } + + uint32_t threads_per_l4 = 0, l4_count = 0; + if (x86_processor.cache.l4.size != 0) { + /* + * Assume that all threads share this L4. + * As of now, L4 cache exists only on notebook x86 CPUs, which + * are single-package, but multi-socket systems could have + * shared L4 (like on IBM POWER8). + */ + threads_per_l4 = freebsd_topology.threads; + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L4 cache; assume %" PRIu32, + threads_per_l4); + l4_count = freebsd_topology.threads / threads_per_l4; + cpuinfo_log_debug("detected %" PRIu32 " L4 caches", l4_count); + } + + if (x86_processor.cache.l1i.size != 0) { + l1i = calloc(l1_count, sizeof(struct cpuinfo_cache)); + if (l1i == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1I caches", + l1_count * sizeof(struct cpuinfo_cache), + l1_count); + return; + } + for (uint32_t c = 0; c < l1_count; c++) { + l1i[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l1i.size, + .associativity = x86_processor.cache.l1i.associativity, + .sets = x86_processor.cache.l1i.sets, + .partitions = x86_processor.cache.l1i.partitions, + .line_size = x86_processor.cache.l1i.line_size, + .flags = x86_processor.cache.l1i.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l1i = &l1i[t / threads_per_l1]; + } + } + + if (x86_processor.cache.l1d.size != 0) { + l1d = calloc(l1_count, sizeof(struct cpuinfo_cache)); + if (l1d == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1D caches", + l1_count * sizeof(struct cpuinfo_cache), + l1_count); + return; + } + for (uint32_t c = 0; c < l1_count; c++) { + l1d[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l1d.size, + .associativity = x86_processor.cache.l1d.associativity, + .sets = x86_processor.cache.l1d.sets, + .partitions = x86_processor.cache.l1d.partitions, + .line_size = x86_processor.cache.l1d.line_size, + .flags = x86_processor.cache.l1d.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l1d = &l1d[t / threads_per_l1]; + } + } + + if (l2_count != 0) { + l2 = calloc(l2_count, sizeof(struct cpuinfo_cache)); + if (l2 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L2 caches", + l2_count * sizeof(struct cpuinfo_cache), + l2_count); + return; + } + for (uint32_t c = 0; c < l2_count; c++) { + l2[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l2.size, + .associativity = x86_processor.cache.l2.associativity, + .sets = x86_processor.cache.l2.sets, + .partitions = x86_processor.cache.l2.partitions, + .line_size = x86_processor.cache.l2.line_size, + .flags = x86_processor.cache.l2.flags, + .processor_start = c * threads_per_l2, + .processor_count = threads_per_l2, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l2 = &l2[t / threads_per_l2]; + } + } + + if (l3_count != 0) { + l3 = calloc(l3_count, sizeof(struct cpuinfo_cache)); + if (l3 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L3 caches", + l3_count * sizeof(struct cpuinfo_cache), + l3_count); + return; + } + for (uint32_t c = 0; c < l3_count; c++) { + l3[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l3.size, + .associativity = x86_processor.cache.l3.associativity, + .sets = x86_processor.cache.l3.sets, + .partitions = x86_processor.cache.l3.partitions, + .line_size = x86_processor.cache.l3.line_size, + .flags = x86_processor.cache.l3.flags, + .processor_start = c * threads_per_l3, + .processor_count = threads_per_l3, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l3 = &l3[t / threads_per_l3]; + } + } + + if (l4_count != 0) { + l4 = calloc(l4_count, sizeof(struct cpuinfo_cache)); + if (l4 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L4 caches", + l4_count * sizeof(struct cpuinfo_cache), + l4_count); + return; + } + for (uint32_t c = 0; c < l4_count; c++) { + l4[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l4.size, + .associativity = x86_processor.cache.l4.associativity, + .sets = x86_processor.cache.l4.sets, + .partitions = x86_processor.cache.l4.partitions, + .line_size = x86_processor.cache.l4.line_size, + .flags = x86_processor.cache.l4.flags, + .processor_start = c * threads_per_l4, + .processor_count = threads_per_l4, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l4 = &l4[t / threads_per_l4]; + } + } + + /* Commit changes */ + cpuinfo_processors = processors; + cpuinfo_cores = cores; + cpuinfo_clusters = clusters; + cpuinfo_packages = packages; + cpuinfo_cache[cpuinfo_cache_level_1i] = l1i; + cpuinfo_cache[cpuinfo_cache_level_1d] = l1d; + cpuinfo_cache[cpuinfo_cache_level_2] = l2; + cpuinfo_cache[cpuinfo_cache_level_3] = l3; + cpuinfo_cache[cpuinfo_cache_level_4] = l4; + + cpuinfo_processors_count = freebsd_topology.threads; + cpuinfo_cores_count = freebsd_topology.cores; + cpuinfo_clusters_count = freebsd_topology.packages; + cpuinfo_packages_count = freebsd_topology.packages; + cpuinfo_cache_count[cpuinfo_cache_level_1i] = l1_count; + cpuinfo_cache_count[cpuinfo_cache_level_1d] = l1_count; + cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count; + cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count; + cpuinfo_cache_count[cpuinfo_cache_level_4] = l4_count; + cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); + + cpuinfo_global_uarch = (struct cpuinfo_uarch_info){ + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + .processor_count = freebsd_topology.threads, + .core_count = freebsd_topology.cores, + }; + + __sync_synchronize(); + + cpuinfo_is_initialized = true; + + processors = NULL; + cores = NULL; + clusters = NULL; + packages = NULL; + l1i = l1d = l2 = l3 = l4 = NULL; + +cleanup: + free(processors); + free(cores); + free(clusters); + free(packages); + free(l1i); + free(l1d); + free(l2); + free(l3); + free(l4); +} From 4c61c5eb69ad347fb9a650b75ce8b89ac9d33192 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Tue, 9 Jul 2024 14:21:52 -0700 Subject: [PATCH 03/25] Add Cortex X4, A720 and A520 --- include/cpuinfo.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 2d74b62f..03f2776a 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -496,13 +496,19 @@ enum cpuinfo_uarch { cpuinfo_uarch_cortex_x2 = 0x00300502, /** ARM Cortex-X3. */ cpuinfo_uarch_cortex_x3 = 0x00300503, + /** ARM Cortex-X4. */ + cpuinfo_uarch_cortex_x4 = 0x00300504, /** ARM Cortex-A510. */ cpuinfo_uarch_cortex_a510 = 0x00300551, + /** ARM Cortex-A520. */ + cpuinfo_uarch_cortex_a520 = 0x00300552, /** ARM Cortex-A710. */ cpuinfo_uarch_cortex_a710 = 0x00300571, /** ARM Cortex-A715. */ cpuinfo_uarch_cortex_a715 = 0x00300572, + /** ARM Cortex-A720. */ + cpuinfo_uarch_cortex_a720 = 0x00300573, /** Qualcomm Scorpion. */ cpuinfo_uarch_scorpion = 0x00400100, From 16bfc1622c6902d6f91d316ec54894910c620325 Mon Sep 17 00:00:00 2001 From: MaajidKhan Date: Wed, 7 Aug 2024 20:33:44 +0530 Subject: [PATCH 04/25] Add a API to check SVE Length support on ARM CPU. (#255) This pull request introduces a new feature to the cpuinfo library that adds an API to return the maximum supported Scalable Vector Extension (SVE) vector length on the given ARM CPU. This enhancement will allow users to query and determine the maximum SVE vector lengths on a given ARM CPU, providing better insights and flexibility for optimizing applications that utilize SVE. **Key Features:** **New API Function:** Introduces a single API function - cpuinfo_get_max_arm_sve_length() that returns the maximum SVE Vector Length supported on the given ARM CPU. The function is designed to be easy to integrate with existing code in other projects like PyTorch (https://github.com/pytorch/pytorch/pull/119571/) and provides a straightforward interface for querying SVE VL. **Here's the sample output on SVE supported instance:** **Query:** ![test_cpp_aug7](https://github.com/user-attachments/assets/0f55fa37-cf54-4fbf-b1bc-a34a27139869) **Output on SVE256 supported Hardware - Graviton3:** ![test_cpp_output](https://github.com/user-attachments/assets/bef72357-dadd-43e9-8983-33248205782f) Signed-off-by: maajidkhann --- include/cpuinfo.h | 10 ++++++++++ src/arm/linux/aarch64-isa.c | 19 +++++++++++++++++++ tools/isa-info.c | 3 +++ 3 files changed, 32 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 03f2776a..2d53ffd0 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1670,6 +1670,7 @@ struct cpuinfo_arm_isa { bool sve; bool sve2; bool i8mm; + uint32_t svelen; #endif bool rdm; bool fp16arith; @@ -2042,6 +2043,15 @@ static inline bool cpuinfo_has_arm_sve2(void) { #endif } +// Function to get the max SVE vector length on ARM CPU's which support SVE. +static inline uint32_t cpuinfo_get_max_arm_sve_length(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.svelen * 8; // bytes * 8 = bit length(vector length) +#else + return 0; +#endif +} + #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions * instead. */ diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index db5349ec..4a013b94 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -3,6 +3,8 @@ #include #include +#include + void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( uint32_t features, uint32_t features2, @@ -151,4 +153,21 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) { isa->fhm = true; } + +#ifndef PR_SVE_GET_VL +#define PR_SVE_GET_VL 51 +#endif + +#ifndef PR_SVE_VL_LEN_MASK +#define PR_SVE_VL_LEN_MASK 0xffff +#endif + + int ret = prctl(PR_SVE_GET_VL); + if (ret < 0) { + cpuinfo_log_error("prctl(PR_SVE_GET_VL) failed"); + isa->svelen = 0; // Assume no SVE support if the call fails + } else { + // Mask out the SVE vector length bits + isa->svelen = ret & PR_SVE_VL_LEN_MASK; + } } diff --git a/tools/isa-info.c b/tools/isa-info.c index 27294615..2c40a5ec 100644 --- a/tools/isa-info.c +++ b/tools/isa-info.c @@ -172,6 +172,9 @@ int main(int argc, char** argv) { printf("\tARM SVE: %s\n", cpuinfo_has_arm_sve() ? "yes" : "no"); printf("\tARM SVE 2: %s\n", cpuinfo_has_arm_sve2() ? "yes" : "no"); + printf("ARM SVE Capabilities:\n"); + printf("\tSVE max length: %d\n", cpuinfo_get_max_arm_sve_length()); + printf("Cryptography extensions:\n"); printf("\tAES: %s\n", cpuinfo_has_arm_aes() ? "yes" : "no"); printf("\tSHA1: %s\n", cpuinfo_has_arm_sha1() ? "yes" : "no"); From 024b37501601d37e97cb9b7f80f0bccf54b4a35d Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 27 Aug 2024 12:38:43 +0200 Subject: [PATCH 05/25] Add detection for `sme` on `aarch64`. --- include/cpuinfo.h | 9 +++++++++ src/arm/linux/aarch64-isa.c | 3 +++ src/arm/linux/api.h | 1 + 3 files changed, 13 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 2d53ffd0..8bb1db4e 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1670,6 +1670,7 @@ struct cpuinfo_arm_isa { bool sve; bool sve2; bool i8mm; + bool sme; uint32_t svelen; #endif bool rdm; @@ -2052,6 +2053,14 @@ static inline uint32_t cpuinfo_get_max_arm_sve_length(void) { #endif } +static inline bool cpuinfo_has_arm_sme(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme; +#else + return false; +#endif +} + #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions * instead. */ diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index 4a013b94..2a88fe29 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -144,6 +144,9 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) { isa->sve2 = true; } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME) { + isa->sme = true; + } // SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 // feature flag was added in Linux kernel before the BF16 feature flag, // so we check for either. diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index 365fea6c..d60f2a25 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -137,6 +137,7 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache { #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) +#define CPUINFO_ARM_LINUX_FEATURE2_SME UINT32_C(0x00800000) #endif #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000) From 209b00cba26583cb8271741aa5f3e267ee7167d0 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Fri, 30 Aug 2024 17:53:58 +0200 Subject: [PATCH 06/25] Add detection for `sme` on `aarch64`. (#257) This is based on the ARM ComputeLibrary implementation [here](https://github.com/ARM-software/ComputeLibrary/blob/f1929dc994d8e5afae5c77ca66446344119a8592/src/common/cpuinfo/CpuIsaInfo.cpp#L75). --- include/cpuinfo.h | 9 +++++++++ src/arm/linux/aarch64-isa.c | 3 +++ src/arm/linux/api.h | 1 + 3 files changed, 13 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 2d53ffd0..8bb1db4e 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1670,6 +1670,7 @@ struct cpuinfo_arm_isa { bool sve; bool sve2; bool i8mm; + bool sme; uint32_t svelen; #endif bool rdm; @@ -2052,6 +2053,14 @@ static inline uint32_t cpuinfo_get_max_arm_sve_length(void) { #endif } +static inline bool cpuinfo_has_arm_sme(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme; +#else + return false; +#endif +} + #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions * instead. */ diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index 4a013b94..2a88fe29 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -144,6 +144,9 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) { isa->sve2 = true; } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME) { + isa->sme = true; + } // SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 // feature flag was added in Linux kernel before the BF16 feature flag, // so we check for either. diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index 365fea6c..d60f2a25 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -137,6 +137,7 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache { #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) +#define CPUINFO_ARM_LINUX_FEATURE2_SME UINT32_C(0x00800000) #endif #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000) From 4611eb986ce5c04b8266241bc0b77ff1925636d8 Mon Sep 17 00:00:00 2001 From: Prashanth Swaminathan <40780424+prashanthswami@users.noreply.github.com> Date: Fri, 30 Aug 2024 08:55:08 -0700 Subject: [PATCH 07/25] Add android-riscv64 build to workflows (#256) The Android NDK supports building for RISC-V as of version r27. Add it to the build workflows here to improve coverage of the RISC-V code. Fixes: #206 --- .github/workflows/build.yml | 4 +-- CMakeLists.txt | 2 +- scripts/android-riscv64-build.sh | 59 ++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100755 scripts/android-riscv64-build.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 311f926b..622650af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,7 +73,7 @@ jobs: cmake-android: strategy: matrix: - script: [android-arm64-build.sh, android-armv7-build.sh, android-x86-build.sh] + script: [android-arm64-build.sh, android-armv7-build.sh, android-riscv64-build.sh, android-x86-build.sh] runs-on: ubuntu-latest timeout-minutes: 40 steps: @@ -86,7 +86,7 @@ jobs: id: setup-ndk uses: nttld/setup-ndk@v1.0.6 with: - ndk-version: r23b + ndk-version: r27 add-to-path: false - name: Configure and build run: scripts/${{ matrix.script }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 4634a223..bd9f77f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,7 +218,7 @@ IF(CPUINFO_SUPPORTED_PLATFORM) ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(riscv(32|64))$") LIST(APPEND CPUINFO_SRCS src/riscv/uarch.c) - IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") LIST(APPEND CPUINFO_SRCS src/riscv/linux/init.c src/riscv/linux/riscv-hw.c diff --git a/scripts/android-riscv64-build.sh b/scripts/android-riscv64-build.sh new file mode 100755 index 00000000..51b578b8 --- /dev/null +++ b/scripts/android-riscv64-build.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -e + +if [ -z "$ANDROID_NDK" ] +then + echo "ANDROID_NDK not set; please set it to the Android NDK directory" + exit 1 +fi + +if [ ! -d "$ANDROID_NDK" ] +then + echo "ANDROID_NDK not a directory; did you install it under ${ANDROID_NDK}?" + exit 1 +fi + +mkdir -p build/android/riscv64 + +CMAKE_ARGS=() + +# CMake-level configuration +CMAKE_ARGS+=("-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake") +CMAKE_ARGS+=("-DCMAKE_BUILD_TYPE=Release") +CMAKE_ARGS+=("-DCMAKE_POSITION_INDEPENDENT_CODE=ON") + +# If Ninja is installed, prefer it to Make +if [ -x "$(command -v ninja)" ] +then + CMAKE_ARGS+=("-GNinja") +fi + +CMAKE_ARGS+=("-DCPUINFO_LIBRARY_TYPE=static") +# CMakeLists for Google Benchmark is broken on Android +CMAKE_ARGS+=("-DCPUINFO_BUILD_BENCHMARKS=OFF") +CMAKE_ARGS+=("-DCPUINFO_BUILD_TOOLS=ON") +CMAKE_ARGS+=("-DCPUINFO_BUILD_UNIT_TESTS=ON") +CMAKE_ARGS+=("-DCPUINFO_BUILD_MOCK_TESTS=ON") + +# Android-specific options +CMAKE_ARGS+=("-DANDROID_NDK=$ANDROID_NDK") +CMAKE_ARGS+=("-DANDROID_ABI=riscv64") +CMAKE_ARGS+=("-DANDROID_PLATFORM=android-35") +CMAKE_ARGS+=("-DANDROID_PIE=ON") +CMAKE_ARGS+=("-DANDROID_STL=c++_static") +CMAKE_ARGS+=("-DANDROID_CPP_FEATURES=exceptions") + +# Use-specified CMake arguments go last to allow overridding defaults +CMAKE_ARGS+=($@) + +cd build/android/riscv64 && cmake ../../.. \ + "${CMAKE_ARGS[@]}" + +# Cross-platform parallel build +if [ "$(uname)" == "Darwin" ] +then + cmake --build . -- "-j$(sysctl -n hw.ncpu)" +else + cmake --build . -- "-j$(nproc)" +fi From fa1c679da8d19e1d87f20175ae1ec10995cd3dd3 Mon Sep 17 00:00:00 2001 From: cyyever Date: Fri, 30 Aug 2024 23:56:51 +0800 Subject: [PATCH 08/25] More robust FreeBSD topology detection (#249) Possibly fix #248 --- README.md | 4 +++- src/freebsd/topology.c | 26 +++++++++++--------------- src/x86/freebsd/init.c | 26 +++++++++++++++++++++----- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 82cadea6..ec05f53b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ cpuinfo is a library to detect essential for performance optimization informatio ## Features - **Cross-platform** availability: - - Linux, Windows, macOS, Android, and iOS operating systems + - Linux, Windows, macOS, Android, iOS and FreeBSD operating systems - x86, x86-64, ARM, and ARM64 architectures - Modern **C/C++ interface** - Thread-safe @@ -258,6 +258,8 @@ LDFLAGS+= $(pkg-config --libs libcpuinfo) - [x] x86 - [x] x86-64 - [x] arm64 +- [x] FreeBSD + - [x] x86-64 ## Methods diff --git a/src/freebsd/topology.c b/src/freebsd/topology.c index da941e9c..675a81f8 100644 --- a/src/freebsd/topology.c +++ b/src/freebsd/topology.c @@ -24,8 +24,10 @@ static char* sysctl_str(const char* name) { size_t value_size = 0; if (sysctlbyname(name, NULL, &value_size, NULL, 0) != 0) { cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); + return NULL; } else if (value_size <= 0) { cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value size %zu", name, value_size); + return NULL; } value_size += 1; char* value = calloc(value_size, 1); @@ -52,29 +54,22 @@ struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { if (!topology_spec) { return topology; } - const char* group_tag = ""; - char* p = strstr(topology_spec, group_tag); - while (p) { - const char* cpu_tag = "cpu count=\""; - char* q = strstr(p, cpu_tag); - if (q) { - p = q + strlen(cpu_tag); - topology.packages += atoi(p); - } else { - break; - } - } - if (topology.packages == 0) { - const char* group_tag = "", " 0) { + break; + } } + if (topology.packages == 0) { - cpuinfo_log_error("failed to parse topology_spec:%s", topology_spec); + cpuinfo_log_error("failed to parse topology_spec: %s", topology_spec); free(topology_spec); goto fail; } @@ -84,6 +79,7 @@ struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { goto fail; } if (topology.cores < topology.packages) { + cpuinfo_log_error("invalid numbers of package and core: %d %d", topology.packages, topology.cores); goto fail; } topology.threads_per_core = sysctl_int("kern.smp.threads_per_core"); diff --git a/src/x86/freebsd/init.c b/src/x86/freebsd/init.c index c6c6d753..797fa24b 100644 --- a/src/x86/freebsd/init.c +++ b/src/x86/freebsd/init.c @@ -135,6 +135,10 @@ void cpuinfo_x86_freebsd_init(void) { if (x86_processor.cache.l1i.size != 0 || x86_processor.cache.l1d.size != 0) { /* Assume that threads on the same core share L1 */ threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores; + if (threads_per_l1 == 0) { + cpuinfo_log_error("failed to detect threads_per_l1"); + goto cleanup; + } cpuinfo_log_warning( "freebsd kernel did not report number of " "threads sharing L1 cache; assume %" PRIu32, @@ -154,6 +158,10 @@ void cpuinfo_x86_freebsd_init(void) { * the same package share L2 */ threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages; } + if (threads_per_l2 == 0) { + cpuinfo_log_error("failed to detect threads_per_l1"); + goto cleanup; + } cpuinfo_log_warning( "freebsd kernel did not report number of " "threads sharing L2 cache; assume %" PRIu32, @@ -170,6 +178,10 @@ void cpuinfo_x86_freebsd_init(void) { * may be L4 cache as well) */ threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages; + if (threads_per_l3 == 0) { + cpuinfo_log_error("failed to detect threads_per_l3"); + goto cleanup; + } cpuinfo_log_warning( "freebsd kernel did not report number of " "threads sharing L3 cache; assume %" PRIu32, @@ -187,6 +199,10 @@ void cpuinfo_x86_freebsd_init(void) { * shared L4 (like on IBM POWER8). */ threads_per_l4 = freebsd_topology.threads; + if (threads_per_l4 == 0) { + cpuinfo_log_error("failed to detect threads_per_l4"); + goto cleanup; + } cpuinfo_log_warning( "freebsd kernel did not report number of " "threads sharing L4 cache; assume %" PRIu32, @@ -203,7 +219,7 @@ void cpuinfo_x86_freebsd_init(void) { "%" PRIu32 " L1I caches", l1_count * sizeof(struct cpuinfo_cache), l1_count); - return; + goto cleanup; } for (uint32_t c = 0; c < l1_count; c++) { l1i[c] = (struct cpuinfo_cache){ @@ -230,7 +246,7 @@ void cpuinfo_x86_freebsd_init(void) { "%" PRIu32 " L1D caches", l1_count * sizeof(struct cpuinfo_cache), l1_count); - return; + goto cleanup; } for (uint32_t c = 0; c < l1_count; c++) { l1d[c] = (struct cpuinfo_cache){ @@ -257,7 +273,7 @@ void cpuinfo_x86_freebsd_init(void) { "%" PRIu32 " L2 caches", l2_count * sizeof(struct cpuinfo_cache), l2_count); - return; + goto cleanup; } for (uint32_t c = 0; c < l2_count; c++) { l2[c] = (struct cpuinfo_cache){ @@ -284,7 +300,7 @@ void cpuinfo_x86_freebsd_init(void) { "%" PRIu32 " L3 caches", l3_count * sizeof(struct cpuinfo_cache), l3_count); - return; + goto cleanup; } for (uint32_t c = 0; c < l3_count; c++) { l3[c] = (struct cpuinfo_cache){ @@ -311,7 +327,7 @@ void cpuinfo_x86_freebsd_init(void) { "%" PRIu32 " L4 caches", l4_count * sizeof(struct cpuinfo_cache), l4_count); - return; + goto cleanup; } for (uint32_t c = 0; c < l4_count; c++) { l4[c] = (struct cpuinfo_cache){ From f0d67c613e1a859fdc41238ed5848545e8e0e102 Mon Sep 17 00:00:00 2001 From: maajidkhann Date: Fri, 6 Sep 2024 17:11:53 +0530 Subject: [PATCH 09/25] Fixes the bug when integrating API on NON-SVE HW. *The current API - cpuinfo_get_max_arm_sve_length() when integarted into PyTorch and tested on Graviton2 (NON SVE hardware), it fails with an error. Signed-off-by: maajidkhann --- src/arm/linux/aarch64-isa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index 2a88fe29..3352db29 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -167,7 +167,7 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( int ret = prctl(PR_SVE_GET_VL); if (ret < 0) { - cpuinfo_log_error("prctl(PR_SVE_GET_VL) failed"); + cpuinfo_log_warning("No SVE support on this machine"); isa->svelen = 0; // Assume no SVE support if the call fails } else { // Mask out the SVE vector length bits From 3fdfe44b286083567127e34a1e3060662fb607e8 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 12:07:50 +0200 Subject: [PATCH 10/25] Add support for `sme2` detection on `aarch64` --- include/cpuinfo.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 8bb1db4e..d6647167 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1671,6 +1671,7 @@ struct cpuinfo_arm_isa { bool sve2; bool i8mm; bool sme; + bool sme2; uint32_t svelen; #endif bool rdm; @@ -2061,6 +2062,14 @@ static inline bool cpuinfo_has_arm_sme(void) { #endif } +static inline bool cpuinfo_has_arm_sme2(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme2; +#else + return false; +#endif +} + #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions * instead. */ From 6a24988c2176e80e2f594cb68a24d86c45b80ea1 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:43:25 +0200 Subject: [PATCH 11/25] Add support for `sme2`. --- src/arm/linux/aarch64-isa.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index 3352db29..c035aff5 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -7,7 +7,7 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( uint32_t features, - uint32_t features2, + uint64_t features2, uint32_t midr, const struct cpuinfo_arm_chipset chipset[restrict static 1], struct cpuinfo_arm_isa isa[restrict static 1]) { @@ -147,6 +147,9 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME) { isa->sme = true; } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME2) { + isa->sme2 = true; + } // SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 // feature flag was added in Linux kernel before the BF16 feature flag, // so we check for either. From f4753b4d2f83c0fe28a87acd9d63529a82627734 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:44:23 +0200 Subject: [PATCH 12/25] Update api.h --- src/arm/linux/api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index d60f2a25..9c001ced 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -138,6 +138,7 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache { #define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000) #define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000) #define CPUINFO_ARM_LINUX_FEATURE2_SME UINT32_C(0x00800000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME2 UINT64_C(0x0000002000000000) #endif #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000) @@ -316,7 +317,7 @@ CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval( CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( uint32_t features, - uint32_t features2, + uint64_t features2, uint32_t midr, const struct cpuinfo_arm_chipset chipset[restrict static 1], struct cpuinfo_arm_isa isa[restrict static 1]); From af1bdfaa394e36c52098cab40b3e9e0832000bdb Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:46:24 +0200 Subject: [PATCH 13/25] Update hwcap.c --- src/arm/linux/hwcap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arm/linux/hwcap.c b/src/arm/linux/hwcap.c index e836548d..55241020 100644 --- a/src/arm/linux/hwcap.c +++ b/src/arm/linux/hwcap.c @@ -31,8 +31,8 @@ void cpuinfo_set_hwcap(uint32_t hwcap) { mock_hwcap = hwcap; } -static uint32_t mock_hwcap2 = 0; -void cpuinfo_set_hwcap2(uint32_t hwcap2) { +static uint64_t mock_hwcap2 = 0; +void cpuinfo_set_hwcap2(uint64_t hwcap2) { mock_hwcap2 = hwcap2; } #endif @@ -40,7 +40,7 @@ void cpuinfo_set_hwcap2(uint32_t hwcap2) { #if CPUINFO_ARCH_ARM typedef unsigned long (*getauxval_function_t)(unsigned long); -bool cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) { +bool cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) { #if CPUINFO_MOCK *hwcap = mock_hwcap; *hwcap2 = mock_hwcap2; From 90d1884f222d7b9405407ecdf932bada253ed449 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:51:46 +0200 Subject: [PATCH 14/25] Update init.c --- src/arm/linux/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arm/linux/init.c b/src/arm/linux/init.c index 6e2024d1..c57cba55 100644 --- a/src/arm/linux/init.c +++ b/src/arm/linux/init.c @@ -246,8 +246,9 @@ void cpuinfo_arm_linux_init(void) { cpuinfo_arm_linux_decode_chipset(proc_cpuinfo_hardware, proc_cpuinfo_revision, valid_processors, 0); #endif + uint32_t isa_features = 0; + uint64_t isa_features2 = 0; #if CPUINFO_ARCH_ARM - uint32_t isa_features = 0, isa_features2 = 0; #ifdef __ANDROID__ /* * On Android before API 20, libc.so does not provide getauxval From 19fe17c6ab76ca24426233914627e4a53ffbbc43 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:53:50 +0200 Subject: [PATCH 15/25] Update init.c --- src/arm/linux/init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/arm/linux/init.c b/src/arm/linux/init.c index c57cba55..1eab69d5 100644 --- a/src/arm/linux/init.c +++ b/src/arm/linux/init.c @@ -246,9 +246,9 @@ void cpuinfo_arm_linux_init(void) { cpuinfo_arm_linux_decode_chipset(proc_cpuinfo_hardware, proc_cpuinfo_revision, valid_processors, 0); #endif +#if CPUINFO_ARCH_ARM uint32_t isa_features = 0; uint64_t isa_features2 = 0; -#if CPUINFO_ARCH_ARM #ifdef __ANDROID__ /* * On Android before API 20, libc.so does not provide getauxval @@ -300,7 +300,8 @@ void cpuinfo_arm_linux_init(void) { &chipset, &cpuinfo_isa); #elif CPUINFO_ARCH_ARM64 - uint32_t isa_features = 0, isa_features2 = 0; + uint32_t isa_features = 0; + uint64_t isa_features2 = 0; /* getauxval is always available on ARM64 Android */ cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2); cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( From ec65d677852f63304a83a7598a44c2f6e99f801b Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 14:55:20 +0200 Subject: [PATCH 16/25] Update hwcap.c --- src/arm/linux/hwcap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arm/linux/hwcap.c b/src/arm/linux/hwcap.c index 55241020..5b537280 100644 --- a/src/arm/linux/hwcap.c +++ b/src/arm/linux/hwcap.c @@ -89,7 +89,7 @@ bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint *hwcap2 = mock_hwcap2; return true; #else - uint32_t hwcaps[2] = {0, 0}; + uint64_t hwcaps[2] = {0, 0}; bool result = false; int file = -1; @@ -113,7 +113,7 @@ bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint hwcaps[0] = (uint32_t)elf_auxv.a_un.a_val; break; case AT_HWCAP2: - hwcaps[1] = (uint32_t)elf_auxv.a_un.a_val; + hwcaps[1] = (uint64_t)elf_auxv.a_un.a_val; break; } } else { @@ -141,13 +141,13 @@ bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint } #endif /* __ANDROID__ */ #elif CPUINFO_ARCH_ARM64 -void cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) { +void cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) { #if CPUINFO_MOCK *hwcap = mock_hwcap; *hwcap2 = mock_hwcap2; #else *hwcap = (uint32_t)getauxval(AT_HWCAP); - *hwcap2 = (uint32_t)getauxval(AT_HWCAP2); + *hwcap2 = (uint64_t)getauxval(AT_HWCAP2); return; #endif } From 1aab550656a49c1d72e1c584913966dabb643881 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 15:00:26 +0200 Subject: [PATCH 17/25] Update api.h --- src/arm/linux/api.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index 9c001ced..c83497c3 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -174,7 +174,7 @@ struct cpuinfo_arm_linux_processor { struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache; #endif uint32_t features; - uint32_t features2; + uint64_t features2; /** * Main ID Register value. */ @@ -297,14 +297,14 @@ CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo( #if CPUINFO_ARCH_ARM CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_getauxval( uint32_t hwcap[restrict static 1], - uint32_t hwcap2[restrict static 1]); + uint64_t hwcap2[restrict static 1]); CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_procfs( uint32_t hwcap[restrict static 1], - uint32_t hwcap2[restrict static 1]); + uint64_t hwcap2[restrict static 1]); CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( uint32_t features, - uint32_t features2, + uint64_t features2, uint32_t midr, uint32_t architecture_version, uint32_t architecture_flags, @@ -313,7 +313,7 @@ CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( #elif CPUINFO_ARCH_ARM64 CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval( uint32_t hwcap[restrict static 1], - uint32_t hwcap2[restrict static 1]); + uint64_t hwcap2[restrict static 1]); CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( uint32_t features, From e588f6afbdfee3a5a5eaf730fadfa66f0e4cdcd7 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 16:20:28 +0200 Subject: [PATCH 18/25] Tabs instead of spaces --- include/cpuinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index d6647167..5031e2d9 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1671,7 +1671,7 @@ struct cpuinfo_arm_isa { bool sve2; bool i8mm; bool sme; - bool sme2; + bool sme2; uint32_t svelen; #endif bool rdm; From c9b4216eff6d81308535f54f417bd29bf7438dcc Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 16:24:19 +0200 Subject: [PATCH 19/25] Update api.h Add feature bits from [here](https://github.com/torvalds/linux/blob/abf2050f51fdca0fd146388f83cddd95a57a008d/arch/arm64/include/uapi/asm/hwcap.h#L99-L104). --- src/arm/linux/api.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/arm/linux/api.h b/src/arm/linux/api.h index c83497c3..14fed7ce 100644 --- a/src/arm/linux/api.h +++ b/src/arm/linux/api.h @@ -139,6 +139,11 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache { #define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000) #define CPUINFO_ARM_LINUX_FEATURE2_SME UINT32_C(0x00800000) #define CPUINFO_ARM_LINUX_FEATURE2_SME2 UINT64_C(0x0000002000000000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME2P1 UINT64_C(0x0000004000000000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME_I16I32 UINT64_C(0x0000008000000000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME_BI32I32 UINT64_C(0x0000010000000000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME_B16B16 UINT64_C(0x0000020000000000) +#define CPUINFO_ARM_LINUX_FEATURE2_SME_F16F16 UINT64_C(0x0000040000000000) #endif #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000) From 4fede9fe84cb6823c9d1eb4da858beabd0e4f42b Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 16:29:40 +0200 Subject: [PATCH 20/25] Update hwcap.c --- src/arm/linux/hwcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arm/linux/hwcap.c b/src/arm/linux/hwcap.c index 5b537280..7f7b4dfd 100644 --- a/src/arm/linux/hwcap.c +++ b/src/arm/linux/hwcap.c @@ -83,7 +83,7 @@ bool cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], u } #ifdef __ANDROID__ -bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) { +bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) { #if CPUINFO_MOCK *hwcap = mock_hwcap; *hwcap2 = mock_hwcap2; From b8c5d8978868e082c1f4b3072689891c78579359 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 16:32:44 +0200 Subject: [PATCH 21/25] Update aarch32-isa.c --- src/arm/linux/aarch32-isa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arm/linux/aarch32-isa.c b/src/arm/linux/aarch32-isa.c index bd5020c7..cd22d1bd 100644 --- a/src/arm/linux/aarch32-isa.c +++ b/src/arm/linux/aarch32-isa.c @@ -24,7 +24,7 @@ void cpuinfo_set_wcid(uint32_t wcid) { void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo( uint32_t features, - uint32_t features2, + uint64_t features2, uint32_t midr, uint32_t architecture_version, uint32_t architecture_flags, From 41c6f099195518097311e97400dbc35c476ee987 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Tue, 24 Sep 2024 18:56:11 +0200 Subject: [PATCH 22/25] Update cpuinfo-mock.h --- include/cpuinfo-mock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cpuinfo-mock.h b/include/cpuinfo-mock.h index 5e129aa6..7bb6d1ee 100644 --- a/include/cpuinfo-mock.h +++ b/include/cpuinfo-mock.h @@ -60,7 +60,7 @@ ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity); void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap); #endif #if CPUINFO_ARCH_ARM -void CPUINFO_ABI cpuinfo_set_hwcap2(uint32_t hwcap2); +void CPUINFO_ABI cpuinfo_set_hwcap2(uint64_t hwcap2); #endif #endif From abec09c93946377df08a901012cb5957dbeac7d1 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Wed, 25 Sep 2024 12:35:03 +0200 Subject: [PATCH 23/25] Update cpuinfo.h --- include/cpuinfo.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 5031e2d9..387611cc 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -1672,6 +1672,11 @@ struct cpuinfo_arm_isa { bool i8mm; bool sme; bool sme2; + bool sme2p1; + bool sme_i16i32; + bool sme_bi32i32; + bool sme_b16b16; + bool sme_f16f16; uint32_t svelen; #endif bool rdm; @@ -2070,6 +2075,46 @@ static inline bool cpuinfo_has_arm_sme2(void) { #endif } +static inline bool cpuinfo_has_arm_sme2p1(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme2p1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_i16i32(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_i16i32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_bi32i32(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_bi32i32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_b16b16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_b16b16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_f16f16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_f16f16; +#else + return false; +#endif +} + #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 /* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions * instead. */ From 6116dc31c50f8cca1edb9e3fe99ef0341ebc6cf9 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Wed, 25 Sep 2024 12:42:21 +0200 Subject: [PATCH 24/25] Update cpuinfo.h From 8f02f6d05164324e39463d16e805caab5bc06d21 Mon Sep 17 00:00:00 2001 From: Pedro Gonnet Date: Wed, 25 Sep 2024 12:45:07 +0200 Subject: [PATCH 25/25] Update aarch64-isa.c --- src/arm/linux/aarch64-isa.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c index c035aff5..bc2186f6 100644 --- a/src/arm/linux/aarch64-isa.c +++ b/src/arm/linux/aarch64-isa.c @@ -150,6 +150,21 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME2) { isa->sme2 = true; } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME2P1) { + isa->sme2p1 = true; + } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_I16I32) { + isa->sme_i16i32 = true; + } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_BI32I32) { + isa->sme_bi32i32 = true; + } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_B16B16) { + isa->sme_b16b16 = true; + } + if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_F16F16) { + isa->sme_f16f16 = true; + } // SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 // feature flag was added in Linux kernel before the BF16 feature flag, // so we check for either.