1476 lines
53 KiB
Diff
1476 lines
53 KiB
Diff
diff --git CMakeLists.txt CMakeLists.txt
|
||
index e594def..cab4d05 100644
|
||
--- CMakeLists.txt
|
||
+++ CMakeLists.txt
|
||
@@ -119,7 +119,8 @@ ENDIF()
|
||
# ---[ cpuinfo library
|
||
SET(CPUINFO_SRCS
|
||
src/init.c
|
||
- src/api.c)
|
||
+ src/api.c
|
||
+ src/cache.c)
|
||
|
||
IF(CPUINFO_SUPPORTED_PLATFORM)
|
||
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$" OR IOS_ARCH MATCHES "^(i386|x86_64)$")
|
||
diff --git LICENSE LICENSE
|
||
index 4910bfe..3f9a4f0 100644
|
||
--- LICENSE
|
||
+++ LICENSE
|
||
@@ -1,3 +1,4 @@
|
||
+Copyright (c) 2019 Google LLC
|
||
Copyright (c) 2017-2018 Facebook Inc.
|
||
Copyright (C) 2012-2017 Georgia Institute of Technology
|
||
Copyright (C) 2010-2012 Marat Dukhan
|
||
diff --git include/cpuinfo.h include/cpuinfo.h
|
||
index 7d5833f..9938d2b 100644
|
||
--- include/cpuinfo.h
|
||
+++ include/cpuinfo.h
|
||
@@ -38,10 +38,18 @@
|
||
#define CPUINFO_ARCH_PNACL 1
|
||
#endif
|
||
|
||
-#if defined(EMSCRIPTEN)
|
||
+#if defined(__asmjs__)
|
||
#define CPUINFO_ARCH_ASMJS 1
|
||
#endif
|
||
|
||
+#if defined(__wasm__)
|
||
+ #if defined(__wasm_simd128__)
|
||
+ #define CPUINFO_ARCH_WASMSIMD 1
|
||
+ #else
|
||
+ #define CPUINFO_ARCH_WASM 1
|
||
+ #endif
|
||
+#endif
|
||
+
|
||
#if CPUINFO_ARCH_X86 && defined(_MSC_VER)
|
||
#define CPUINFO_ABI __cdecl
|
||
#elif CPUINFO_ARCH_X86 && defined(__GNUC__)
|
||
@@ -80,6 +88,14 @@
|
||
#define CPUINFO_ARCH_ASMJS 0
|
||
#endif
|
||
|
||
+#ifndef CPUINFO_ARCH_WASM
|
||
+ #define CPUINFO_ARCH_WASM 0
|
||
+#endif
|
||
+
|
||
+#ifndef CPUINFO_ARCH_WASMSIMD
|
||
+ #define CPUINFO_ARCH_WASMSIMD 0
|
||
+#endif
|
||
+
|
||
#define CPUINFO_CACHE_UNIFIED 0x00000001
|
||
#define CPUINFO_CACHE_INCLUSIVE 0x00000002
|
||
#define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004
|
||
@@ -278,10 +294,14 @@ enum cpuinfo_uarch {
|
||
cpuinfo_uarch_haswell = 0x00100208,
|
||
/** Intel Broadwell microarchitecture. */
|
||
cpuinfo_uarch_broadwell = 0x00100209,
|
||
- /** Intel Sky Lake microarchitecture. */
|
||
+ /** Intel Sky Lake microarchitecture (14 nm, including Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */
|
||
cpuinfo_uarch_sky_lake = 0x0010020A,
|
||
- /** Intel Kaby Lake microarchitecture. */
|
||
- cpuinfo_uarch_kaby_lake = 0x0010020B,
|
||
+ /** DEPRECATED (Intel Kaby Lake microarchitecture). */
|
||
+ cpuinfo_uarch_kaby_lake = 0x0010020A,
|
||
+ /** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */
|
||
+ cpuinfo_uarch_palm_cove = 0x0010020B,
|
||
+ /** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */
|
||
+ cpuinfo_uarch_sunny_cove = 0x0010020C,
|
||
|
||
/** Pentium 4 with Willamette, Northwood, or Foster cores. */
|
||
cpuinfo_uarch_willamette = 0x00100300,
|
||
@@ -289,13 +309,17 @@ enum cpuinfo_uarch {
|
||
cpuinfo_uarch_prescott = 0x00100301,
|
||
|
||
/** Intel Atom on 45 nm process. */
|
||
- cpuinfo_uarch_bonnell = 0x00100400,
|
||
+ cpuinfo_uarch_bonnell = 0x00100400,
|
||
/** Intel Atom on 32 nm process. */
|
||
- cpuinfo_uarch_saltwell = 0x00100401,
|
||
+ cpuinfo_uarch_saltwell = 0x00100401,
|
||
/** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */
|
||
- cpuinfo_uarch_silvermont = 0x00100402,
|
||
+ cpuinfo_uarch_silvermont = 0x00100402,
|
||
/** Intel Airmont microarchitecture (14 nm out-of-order Atom). */
|
||
- cpuinfo_uarch_airmont = 0x00100403,
|
||
+ cpuinfo_uarch_airmont = 0x00100403,
|
||
+ /** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */
|
||
+ cpuinfo_uarch_goldmont = 0x00100404,
|
||
+ /** Intel Goldmont Plus microarchitecture (Gemini Lake). */
|
||
+ cpuinfo_uarch_goldmont_plus = 0x00100405,
|
||
|
||
/** Intel Knights Ferry HPC boards. */
|
||
cpuinfo_uarch_knights_ferry = 0x00100500,
|
||
@@ -335,8 +359,10 @@ enum cpuinfo_uarch {
|
||
cpuinfo_uarch_steamroller = 0x00200107,
|
||
/** AMD Excavator microarchitecture (Carizzo APUs). */
|
||
cpuinfo_uarch_excavator = 0x00200108,
|
||
- /** AMD Zen microarchitecture (Ryzen CPUs). */
|
||
+ /** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */
|
||
cpuinfo_uarch_zen = 0x00200109,
|
||
+ /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */
|
||
+ cpuinfo_uarch_zen2 = 0x0020010A,
|
||
|
||
/** NSC Geode and AMD Geode GX and LX. */
|
||
cpuinfo_uarch_geode = 0x00200200,
|
||
@@ -370,23 +396,34 @@ enum cpuinfo_uarch {
|
||
cpuinfo_uarch_cortex_a17 = 0x00300217,
|
||
|
||
/** ARM Cortex-A32. */
|
||
- cpuinfo_uarch_cortex_a32 = 0x00300332,
|
||
+ cpuinfo_uarch_cortex_a32 = 0x00300332,
|
||
/** ARM Cortex-A35. */
|
||
- cpuinfo_uarch_cortex_a35 = 0x00300335,
|
||
+ cpuinfo_uarch_cortex_a35 = 0x00300335,
|
||
/** ARM Cortex-A53. */
|
||
- cpuinfo_uarch_cortex_a53 = 0x00300353,
|
||
+ cpuinfo_uarch_cortex_a53 = 0x00300353,
|
||
/** ARM Cortex-A55. */
|
||
- cpuinfo_uarch_cortex_a55 = 0x00300355,
|
||
+ cpuinfo_uarch_cortex_a55 = 0x00300355,
|
||
/** ARM Cortex-A57. */
|
||
- cpuinfo_uarch_cortex_a57 = 0x00300357,
|
||
+ cpuinfo_uarch_cortex_a57 = 0x00300357,
|
||
+ /** ARM Cortex-A65. */
|
||
+ cpuinfo_uarch_cortex_a65 = 0x00300365,
|
||
/** ARM Cortex-A72. */
|
||
- cpuinfo_uarch_cortex_a72 = 0x00300372,
|
||
+ cpuinfo_uarch_cortex_a72 = 0x00300372,
|
||
/** ARM Cortex-A73. */
|
||
- cpuinfo_uarch_cortex_a73 = 0x00300373,
|
||
+ cpuinfo_uarch_cortex_a73 = 0x00300373,
|
||
/** ARM Cortex-A75. */
|
||
- cpuinfo_uarch_cortex_a75 = 0x00300375,
|
||
+ cpuinfo_uarch_cortex_a75 = 0x00300375,
|
||
/** ARM Cortex-A76. */
|
||
- cpuinfo_uarch_cortex_a76 = 0x00300376,
|
||
+ cpuinfo_uarch_cortex_a76 = 0x00300376,
|
||
+ /** ARM Cortex-A76AE. */
|
||
+ cpuinfo_uarch_cortex_a76ae = 0x00300378,
|
||
+ /** ARM Cortex-A77. */
|
||
+ cpuinfo_uarch_cortex_a77 = 0x00300377,
|
||
+
|
||
+ /** ARM Neoverse N1. */
|
||
+ cpuinfo_uarch_neoverse_n1 = 0x00300400,
|
||
+ /** ARM Neoverse E1. */
|
||
+ cpuinfo_uarch_neoverse_e1 = 0x00300401,
|
||
|
||
/** Qualcomm Scorpion. */
|
||
cpuinfo_uarch_scorpion = 0x00400100,
|
||
@@ -406,12 +443,22 @@ enum cpuinfo_uarch {
|
||
/** Nvidia Carmel. */
|
||
cpuinfo_uarch_carmel = 0x00500102,
|
||
|
||
- /** Samsung Mongoose M1 (Exynos 8890 big cores). */
|
||
+ /** Samsung Exynos M1 (Exynos 8890 big cores). */
|
||
+ cpuinfo_uarch_exynos_m1 = 0x00600100,
|
||
+ /** Samsung Exynos M2 (Exynos 8895 big cores). */
|
||
+ cpuinfo_uarch_exynos_m2 = 0x00600101,
|
||
+ /** Samsung Exynos M3 (Exynos 9810 big cores). */
|
||
+ cpuinfo_uarch_exynos_m3 = 0x00600102,
|
||
+ /** Samsung Exynos M4 (Exynos 9820 big cores). */
|
||
+ cpuinfo_uarch_exynos_m4 = 0x00600103,
|
||
+ /** Samsung Exynos M5 (Exynos 9830 big cores). */
|
||
+ cpuinfo_uarch_exynos_m5 = 0x00600104,
|
||
+
|
||
+ /* Old names for Exynos. */
|
||
cpuinfo_uarch_mongoose_m1 = 0x00600100,
|
||
- /** Samsung Mongoose M2 (Exynos 8895 big cores). */
|
||
cpuinfo_uarch_mongoose_m2 = 0x00600101,
|
||
- /** Samsung Meerkat M3 (Exynos 9810 big cores). */
|
||
cpuinfo_uarch_meerkat_m3 = 0x00600102,
|
||
+ cpuinfo_uarch_meerkat_m4 = 0x00600103,
|
||
|
||
/** Apple A6 and A6X processors. */
|
||
cpuinfo_uarch_swift = 0x00700100,
|
||
@@ -640,6 +687,8 @@ void CPUINFO_ABI cpuinfo_deinitialize(void);
|
||
bool avx512bitalg;
|
||
bool avx512vpopcntdq;
|
||
bool avx512vnni;
|
||
+ bool avx512bf16;
|
||
+ bool avx512vp2intersect;
|
||
bool avx512_4vnniw;
|
||
bool avx512_4fmaps;
|
||
bool hle;
|
||
@@ -1110,6 +1159,22 @@ static inline bool cpuinfo_has_x86_avx512vnni(void) {
|
||
#endif
|
||
}
|
||
|
||
+static inline bool cpuinfo_has_x86_avx512bf16(void) {
|
||
+ #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||
+ return cpuinfo_isa.avx512bf16;
|
||
+ #else
|
||
+ return false;
|
||
+ #endif
|
||
+}
|
||
+
|
||
+static inline bool cpuinfo_has_x86_avx512vp2intersect(void) {
|
||
+ #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||
+ return cpuinfo_isa.avx512vp2intersect;
|
||
+ #else
|
||
+ return false;
|
||
+ #endif
|
||
+}
|
||
+
|
||
static inline bool cpuinfo_has_x86_avx512_4vnniw(void) {
|
||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||
return cpuinfo_isa.avx512_4vnniw;
|
||
@@ -1682,6 +1747,11 @@ uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void);
|
||
uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void);
|
||
uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void);
|
||
|
||
+/**
|
||
+ * Returns upper bound on cache size.
|
||
+ */
|
||
+uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void);
|
||
+
|
||
const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void);
|
||
const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void);
|
||
|
||
diff --git src/api.c src/api.c
|
||
index 98b5805..83744f5 100644
|
||
--- src/api.c
|
||
+++ src/api.c
|
||
@@ -18,6 +18,7 @@ uint32_t cpuinfo_cores_count = 0;
|
||
uint32_t cpuinfo_clusters_count = 0;
|
||
uint32_t cpuinfo_packages_count = 0;
|
||
uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = { 0 };
|
||
+uint32_t cpuinfo_max_cache_size = 0;
|
||
|
||
|
||
const struct cpuinfo_processor* cpuinfo_get_processors(void) {
|
||
diff --git src/arm/api.h src/arm/api.h
|
||
index 11e588b..69274bc 100644
|
||
--- src/arm/api.h
|
||
+++ src/arm/api.h
|
||
@@ -104,6 +104,9 @@ CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||
struct cpuinfo_cache l1d[restrict static 1],
|
||
struct cpuinfo_cache l2[restrict static 1],
|
||
struct cpuinfo_cache l3[restrict static 1]);
|
||
+
|
||
+CPUINFO_INTERNAL uint32_t cpuinfo_arm_compute_max_cache_size(
|
||
+ const struct cpuinfo_processor processor[restrict static 1]);
|
||
#else /* defined(__cplusplus) */
|
||
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||
enum cpuinfo_uarch uarch,
|
||
diff --git src/arm/cache.c src/arm/cache.c
|
||
index 5ada7d9..ccadeb4 100644
|
||
--- src/arm/cache.c
|
||
+++ src/arm/cache.c
|
||
@@ -1,10 +1,12 @@
|
||
#include <stdint.h>
|
||
|
||
#include <cpuinfo.h>
|
||
+#include <cpuinfo/internal-api.h>
|
||
#include <cpuinfo/log.h>
|
||
#include <arm/api.h>
|
||
#include <arm/midr.h>
|
||
|
||
+
|
||
void cpuinfo_arm_decode_cache(
|
||
enum cpuinfo_uarch uarch,
|
||
uint32_t cluster_cores,
|
||
@@ -109,7 +111,7 @@ void cpuinfo_arm_decode_cache(
|
||
* memory accesses and has been optimized for use with the Cortex-A5 processor.
|
||
* 8.1.7. Exclusive L2 cache
|
||
* The Cortex-A5 processor can be connected to an L2 cache that supports an exclusive cache mode.
|
||
- * This mode must be activated both in the Cortex-A5 processor and in the L2 cache controller.
|
||
+ * This mode must be activated both in the Cortex-A5 processor and in the L2 cache controller.
|
||
*
|
||
* +--------------------+-----------+-----------+----------+-----------+
|
||
* | Processor model | L1D cache | L1I cache | L2 cache | Reference |
|
||
@@ -698,7 +700,7 @@ void cpuinfo_arm_decode_cache(
|
||
* [3] https://en.wikichip.org/wiki/hisilicon/kirin/980
|
||
*/
|
||
if (midr_is_qualcomm_cortex_a55_silver(midr)) {
|
||
- /* Qualcomm-modified Cortex-A55 in Snapdragon 710 / 845 */
|
||
+ /* Qualcomm-modified Cortex-A55 in Snapdragon 670 / 710 / 845 */
|
||
uint32_t l3_size = 1024 * 1024;
|
||
switch (chipset->series) {
|
||
case cpuinfo_arm_chipset_series_qualcomm_snapdragon:
|
||
@@ -827,6 +829,62 @@ void cpuinfo_arm_decode_cache(
|
||
.flags = CPUINFO_CACHE_INCLUSIVE
|
||
};
|
||
break;
|
||
+ case cpuinfo_uarch_cortex_a65:
|
||
+ {
|
||
+ /*
|
||
+ * ARM Cortex‑A65 Core Technical Reference Manual
|
||
+ * A6.1. About the L1 memory system
|
||
+ * The L1 memory system enhances the performance and power efficiency in the Cortex‑A65 core.
|
||
+ * It consists of separate instruction and data caches. You can configure instruction and data caches
|
||
+ * independently during implementation to sizes of 32KB or 64KB.
|
||
+ *
|
||
+ * L1 instruction-side memory system
|
||
+ * The L1 instruction-side memory system provides an instruction stream to the DPU. Its key features are:
|
||
+ * - 64-byte instruction side cache line length.
|
||
+ * - 4-way set associative L1 instruction cache.
|
||
+ *
|
||
+ * L1 data-side memory system
|
||
+ * - 64-byte data side cache line length.
|
||
+ * - 4-way set associative L1 data cache.
|
||
+ *
|
||
+ * A7.1 About the L2 memory system
|
||
+ * The Cortex‑A65 L2 memory system is required to interface the Cortex‑A65 cores to the L3 memory system.
|
||
+ * The L2 memory subsystem consists of:
|
||
+ * - An optional 4-way, set-associative L2 cache with a configurable size of 64KB, 128KB, or 256KB.
|
||
+ * Cache lines have a fixed length of 64 bytes.
|
||
+ *
|
||
+ * The main features of the L2 memory system are:
|
||
+ * - Strictly exclusive with L1 data cache.
|
||
+ * - Pseudo-inclusive with L1 instruction cache.
|
||
+ * - Private per-core unified L2 cache.
|
||
+ */
|
||
+ const uint32_t l1_size = 32 * 1024;
|
||
+ const uint32_t l2_size = 128 * 1024;
|
||
+ const uint32_t l3_size = 512 * 1024;
|
||
+ *l1i = (struct cpuinfo_cache) {
|
||
+ .size = l1_size,
|
||
+ .associativity = 4,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ *l1d = (struct cpuinfo_cache) {
|
||
+ .size = l1_size,
|
||
+ .associativity = 4,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ *l2 = (struct cpuinfo_cache) {
|
||
+ .size = l2_size,
|
||
+ .associativity = 4,
|
||
+ .line_size = 64,
|
||
+ .flags = CPUINFO_CACHE_INCLUSIVE
|
||
+ };
|
||
+ *l3 = (struct cpuinfo_cache) {
|
||
+ .size = l3_size,
|
||
+ /* DynamIQ */
|
||
+ .associativity = 16,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ break;
|
||
+ }
|
||
case cpuinfo_uarch_cortex_a72:
|
||
{
|
||
/*
|
||
@@ -1047,6 +1105,7 @@ void cpuinfo_arm_decode_cache(
|
||
break;
|
||
}
|
||
case cpuinfo_uarch_cortex_a76:
|
||
+ case cpuinfo_uarch_cortex_a76ae:
|
||
{
|
||
/*
|
||
* ARM Cortex-A76 Core Technical Reference Manual
|
||
@@ -1119,6 +1178,57 @@ void cpuinfo_arm_decode_cache(
|
||
};
|
||
break;
|
||
}
|
||
+ case cpuinfo_uarch_cortex_a77:
|
||
+ {
|
||
+ /*
|
||
+ * ARM Cortex-A77 Core Technical Reference Manual
|
||
+ * A6.1. About the L1 memory system
|
||
+ * The L1 memory system consists of separate instruction and data caches. Both have a fixed size of 64KB.
|
||
+ *
|
||
+ * A6.1.1 L1 instruction-side memory system
|
||
+ * The L1 instruction memory system has the following key features:
|
||
+ * - Virtually Indexed, Physically Tagged (VIPT), which behaves as a Physically Indexed,
|
||
+ * Physically Tagged (PIPT) 4-way set-associative L1 data cache.
|
||
+ * - Fixed cache line length of 64 bytes.
|
||
+ *
|
||
+ * A6.1.2 L1 data-side memory system
|
||
+ * The L1 data memory system has the following features:
|
||
+ * - Virtually Indexed, Physically Tagged (VIPT), which behaves as a Physically Indexed,
|
||
+ * Physically Tagged (PIPT) 4-way set-associative L1 data cache.
|
||
+ * - Fixed cache line length of 64 bytes.
|
||
+ * - Pseudo-LRU cache replacement policy.
|
||
+ *
|
||
+ * A7.1 About the L2 memory system
|
||
+ * The L2 memory subsystem consist of:
|
||
+ * - An 8-way set associative L2 cache with a configurable size of 128KB, 256KB or 512KB. Cache lines
|
||
+ * have a fixed length of 64 bytes.
|
||
+ * - Strictly inclusive with L1 data cache. Weakly inclusive with L1 instruction cache.
|
||
+ */
|
||
+ const uint32_t l2_size = 256 * 1024;
|
||
+ const uint32_t l3_size = 1024 * 1024;
|
||
+ *l1i = (struct cpuinfo_cache) {
|
||
+ .size = 64 * 1024,
|
||
+ .associativity = 4,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ *l1d = (struct cpuinfo_cache) {
|
||
+ .size = 64 * 1024,
|
||
+ .associativity = 4,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ *l2 = (struct cpuinfo_cache) {
|
||
+ .size = l2_size,
|
||
+ .associativity = 8,
|
||
+ .line_size = 64,
|
||
+ .flags = CPUINFO_CACHE_INCLUSIVE,
|
||
+ };
|
||
+ *l3 = (struct cpuinfo_cache) {
|
||
+ .size = l3_size,
|
||
+ .associativity = 16,
|
||
+ .line_size = 64,
|
||
+ };
|
||
+ break;
|
||
+ }
|
||
#if CPUINFO_ARCH_ARM && !defined(__ARM_ARCH_8A__)
|
||
case cpuinfo_uarch_scorpion:
|
||
/*
|
||
@@ -1248,8 +1358,8 @@ void cpuinfo_arm_decode_cache(
|
||
.line_size = 64
|
||
};
|
||
break;
|
||
- case cpuinfo_uarch_mongoose_m1:
|
||
- case cpuinfo_uarch_mongoose_m2:
|
||
+ case cpuinfo_uarch_exynos_m1:
|
||
+ case cpuinfo_uarch_exynos_m2:
|
||
/*
|
||
* - "Moving past branch prediction we can see some elements of how the cache is set up for the L1 I$,
|
||
* namely 64 KB split into four sets with 128-byte line sizes for 128 cache lines per set" [1]
|
||
@@ -1283,7 +1393,7 @@ void cpuinfo_arm_decode_cache(
|
||
.line_size = 64
|
||
};
|
||
break;
|
||
- case cpuinfo_uarch_meerkat_m3:
|
||
+ case cpuinfo_uarch_exynos_m3:
|
||
/*
|
||
* +--------------------+-------+-----------+-----------+-----------+----------+------------+
|
||
* | Processor model | Cores | L1D cache | L1I cache | L2 cache | L3 cache | Reference |
|
||
@@ -1294,19 +1404,19 @@ void cpuinfo_arm_decode_cache(
|
||
* [1] https://www.anandtech.com/show/12478/exynos-9810-handson-awkward-first-results
|
||
*/
|
||
*l1i = (struct cpuinfo_cache) {
|
||
- .size = 64 * 1024 /* assume same as in Mongoose cores */,
|
||
- .associativity = 4 /* assume same as in Mongoose cores */,
|
||
- .line_size = 128 /* assume same as in Mongoose cores */
|
||
+ .size = 64 * 1024 /* assume same as in Exynos M1/M2 cores */,
|
||
+ .associativity = 4 /* assume same as in Exynos M1/M2 cores */,
|
||
+ .line_size = 128 /* assume same as in Exynos M1/M2 cores */
|
||
};
|
||
*l1d = (struct cpuinfo_cache) {
|
||
.size = 64 * 1024,
|
||
- .associativity = 8 /* assume same as in Mongoose cores */,
|
||
- .line_size = 64 /* assume same as in Mongoose cores */,
|
||
+ .associativity = 8 /* assume same as in Exynos M1/M2 cores */,
|
||
+ .line_size = 64 /* assume same as in Exynos M1/M2 cores */,
|
||
};
|
||
*l2 = (struct cpuinfo_cache) {
|
||
.size = 512 * 1024,
|
||
- .associativity = 16 /* assume same as in Mongoose cores */,
|
||
- .line_size = 64 /* assume same as in Mongoose cores */,
|
||
+ .associativity = 16 /* assume same as in Exynos M1/M2 cores */,
|
||
+ .line_size = 64 /* assume same as in Exynos M1/M2 cores */,
|
||
};
|
||
*l3 = (struct cpuinfo_cache) {
|
||
.size = 4 * 1024 * 1024,
|
||
@@ -1393,3 +1503,124 @@ void cpuinfo_arm_decode_cache(
|
||
}
|
||
}
|
||
}
|
||
+
|
||
+uint32_t cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor* processor) {
|
||
+ /*
|
||
+ * There is no precise way to detect cache size on ARM/ARM64, and cache size reported by cpuinfo
|
||
+ * may underestimate the actual cache size. Thus, we use microarchitecture-specific maximum.
|
||
+ */
|
||
+ switch (processor->core->uarch) {
|
||
+ case cpuinfo_uarch_xscale:
|
||
+ case cpuinfo_uarch_arm11:
|
||
+ case cpuinfo_uarch_scorpion:
|
||
+ case cpuinfo_uarch_krait:
|
||
+ case cpuinfo_uarch_kryo:
|
||
+ case cpuinfo_uarch_exynos_m1:
|
||
+ case cpuinfo_uarch_exynos_m2:
|
||
+ case cpuinfo_uarch_exynos_m3:
|
||
+ /* cpuinfo-detected cache size always correct */
|
||
+ return cpuinfo_compute_max_cache_size(processor);
|
||
+ case cpuinfo_uarch_cortex_a5:
|
||
+ /* Max observed (NXP Vybrid SoC) */
|
||
+ return 512 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a7:
|
||
+ /*
|
||
+ * Cortex-A7 MPCore Technical Reference Manual:
|
||
+ * 7.1. About the L2 Memory system
|
||
+ * The L2 memory system consists of an:
|
||
+ * - Optional tightly-coupled L2 cache that includes:
|
||
+ * - Configurable L2 cache size of 128KB, 256KB, 512KB, and 1MB.
|
||
+ */
|
||
+ return 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a8:
|
||
+ /*
|
||
+ * Cortex-A8 Technical Reference Manual:
|
||
+ * 8.1. About the L2 memory system
|
||
+ * The key features of the L2 memory system include:
|
||
+ * - configurable cache size of 0KB, 128KB, 256KB, 512KB, and 1MB
|
||
+ */
|
||
+ return 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a9:
|
||
+ /* Max observed (e.g. Exynos 4212) */
|
||
+ return 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a12:
|
||
+ case cpuinfo_uarch_cortex_a17:
|
||
+ /*
|
||
+ * ARM Cortex-A17 MPCore Processor Technical Reference Manual:
|
||
+ * 7.1. About the L2 Memory system
|
||
+ * The key features of the L2 memory system include:
|
||
+ * - An integrated L2 cache:
|
||
+ * - The cache size is implemented as either 256KB, 512KB, 1MB, 2MB, 4MB or 8MB.
|
||
+ */
|
||
+ return 8 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a15:
|
||
+ /*
|
||
+ * ARM Cortex-A15 MPCore Processor Technical Reference Manual:
|
||
+ * 7.1. About the L2 memory system
|
||
+ * The features of the L2 memory system include:
|
||
+ * - Configurable L2 cache size of 512KB, 1MB, 2MB and 4MB.
|
||
+ */
|
||
+ return 4 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a35:
|
||
+ /*
|
||
+ * ARM Cortex‑A35 Processor Technical Reference Manual:
|
||
+ * 7.1 About the L2 memory system
|
||
+ * L2 cache
|
||
+ * - Further features of the L2 cache are:
|
||
+ * - Configurable size of 128KB, 256KB, 512KB, and 1MB.
|
||
+ */
|
||
+ return 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a53:
|
||
+ /*
|
||
+ * ARM Cortex-A53 MPCore Processor Technical Reference Manual:
|
||
+ * 7.1. About the L2 memory system
|
||
+ * The L2 memory system consists of an:
|
||
+ * - Optional tightly-coupled L2 cache that includes:
|
||
+ * - Configurable L2 cache size of 128KB, 256KB, 512KB, 1MB and 2MB.
|
||
+ */
|
||
+ return 2 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a57:
|
||
+ /*
|
||
+ * ARM Cortex-A57 MPCore Processor Technical Reference Manual:
|
||
+ * 7.1 About the L2 memory system
|
||
+ * The features of the L2 memory system include:
|
||
+ * - Configurable L2 cache size of 512KB, 1MB, and 2MB.
|
||
+ */
|
||
+ return 2 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a72:
|
||
+ /*
|
||
+ * ARM Cortex-A72 MPCore Processor Technical Reference Manual:
|
||
+ * 7.1 About the L2 memory system
|
||
+ * The features of the L2 memory system include:
|
||
+ * - Configurable L2 cache size of 512KB, 1MB, 2MB and 4MB.
|
||
+ */
|
||
+ return 4 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a73:
|
||
+ /*
|
||
+ * ARM Cortex‑A73 MPCore Processor Technical Reference Manual
|
||
+ * 7.1 About the L2 memory system
|
||
+ * The L2 memory system consists of:
|
||
+ * - A tightly-integrated L2 cache with:
|
||
+ * - A configurable size of 256KB, 512KB, 1MB, 2MB, 4MB, or 8MB.
|
||
+ */
|
||
+ return 8 * 1024 * 1024;
|
||
+ case cpuinfo_uarch_cortex_a55:
|
||
+ case cpuinfo_uarch_cortex_a75:
|
||
+ case cpuinfo_uarch_cortex_a76:
|
||
+ case cpuinfo_uarch_exynos_m4:
|
||
+ default:
|
||
+ /*
|
||
+ * ARM DynamIQ Shared Unit Technical Reference Manual
|
||
+ * 1.3 Implementation options
|
||
+ * L3_CACHE_SIZE
|
||
+ * - 256KB
|
||
+ * - 512KB
|
||
+ * - 1024KB
|
||
+ * - 1536KB
|
||
+ * - 2048KB
|
||
+ * - 3072KB
|
||
+ * - 4096KB
|
||
+ */
|
||
+ return 4 * 1024 * 1024;
|
||
+ }
|
||
+}
|
||
diff --git src/arm/linux/init.c src/arm/linux/init.c
|
||
index a297f63..f0c432c 100644
|
||
--- src/arm/linux/init.c
|
||
+++ src/arm/linux/init.c
|
||
@@ -678,6 +678,8 @@ void cpuinfo_arm_linux_init(void) {
|
||
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
|
||
cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count;
|
||
|
||
+ cpuinfo_max_cache_size = cpuinfo_arm_compute_max_cache_size(&processors[0]);
|
||
+
|
||
__sync_synchronize();
|
||
|
||
cpuinfo_is_initialized = true;
|
||
diff --git src/arm/linux/midr.c src/arm/linux/midr.c
|
||
index 668fc72..2c3116b 100644
|
||
--- src/arm/linux/midr.c
|
||
+++ src/arm/linux/midr.c
|
||
@@ -220,7 +220,7 @@ static const struct cluster_config cluster_configs[] = {
|
||
.model = UINT16_C(7420),
|
||
.clusters = 2,
|
||
.cluster_cores = {
|
||
- [0] = 4,
|
||
+ [0] = 4,
|
||
[1] = 4,
|
||
},
|
||
.cluster_midr = {
|
||
@@ -229,7 +229,7 @@ static const struct cluster_config cluster_configs[] = {
|
||
},
|
||
},
|
||
{
|
||
- /* Exynos 8890: 4x Mongoose + 4x Cortex-A53 */
|
||
+ /* Exynos 8890: 4x Exynos M1 + 4x Cortex-A53 */
|
||
.cores = 8,
|
||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||
.model = UINT16_C(8890),
|
||
@@ -695,7 +695,7 @@ static void cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
|
||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||
if (processors[i].package_leader_id == i) {
|
||
if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
|
||
- midr = processors[i].midr;
|
||
+ midr = processors[i].midr;
|
||
} else {
|
||
cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, i, midr);
|
||
/* To be consistent, we copy the MIDR entirely, rather than by parts */
|
||
@@ -836,7 +836,7 @@ uint32_t cpuinfo_arm_linux_detect_cluster_midr(
|
||
* - Clusters preceeding the first reported MIDR value are assumed to have the last reported MIDR value.
|
||
* - Clusters following any reported MIDR value to have that MIDR value.
|
||
*/
|
||
-
|
||
+
|
||
if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
|
||
chipset, clusters_count, cluster_leaders, usable_processors, processors, true))
|
||
{
|
||
diff --git src/arm/mach/init.c src/arm/mach/init.c
|
||
index 5b14b49..e64cc18 100644
|
||
--- src/arm/mach/init.c
|
||
+++ src/arm/mach/init.c
|
||
@@ -562,6 +562,8 @@ void cpuinfo_arm_mach_init(void) {
|
||
cpuinfo_clusters_count = num_clusters;
|
||
cpuinfo_packages_count = mach_topology.packages;
|
||
|
||
+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]);
|
||
+
|
||
__sync_synchronize();
|
||
|
||
cpuinfo_is_initialized = true;
|
||
diff --git src/arm/midr.h src/arm/midr.h
|
||
index 6363ed7..d5a28e3 100644
|
||
--- src/arm/midr.h
|
||
+++ src/arm/midr.h
|
||
@@ -33,31 +33,31 @@
|
||
#define CPUINFO_ARM_MIDR_KRYO_SILVER_821 UINT32_C(0x510F2010)
|
||
#define CPUINFO_ARM_MIDR_KRYO_GOLD UINT32_C(0x510F2050)
|
||
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
|
||
-#define CPUINFO_ARM_MIDR_MONGOOSE UINT32_C(0x530F0010)
|
||
+#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
|
||
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
|
||
|
||
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
|
||
- return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
|
||
+ return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
|
||
((implementer << CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET) & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
|
||
}
|
||
|
||
inline static uint32_t midr_set_variant(uint32_t midr, uint32_t variant) {
|
||
- return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) |
|
||
+ return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) |
|
||
((variant << CPUINFO_ARM_MIDR_VARIANT_OFFSET) & CPUINFO_ARM_MIDR_VARIANT_MASK);
|
||
}
|
||
|
||
inline static uint32_t midr_set_architecture(uint32_t midr, uint32_t architecture) {
|
||
- return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) |
|
||
+ return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) |
|
||
((architecture << CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET) & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
|
||
}
|
||
|
||
inline static uint32_t midr_set_part(uint32_t midr, uint32_t part) {
|
||
- return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) |
|
||
+ return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) |
|
||
((part << CPUINFO_ARM_MIDR_PART_OFFSET) & CPUINFO_ARM_MIDR_PART_MASK);
|
||
}
|
||
|
||
inline static uint32_t midr_set_revision(uint32_t midr, uint32_t revision) {
|
||
- return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) |
|
||
+ return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) |
|
||
((revision << CPUINFO_ARM_MIDR_REVISION_OFFSET) & CPUINFO_ARM_MIDR_REVISION_MASK);
|
||
}
|
||
|
||
@@ -171,13 +171,20 @@ inline static bool midr_is_kryo_gold(uint32_t midr) {
|
||
inline static uint32_t midr_score_core(uint32_t midr) {
|
||
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||
switch (midr & core_mask) {
|
||
+ case UINT32_C(0x53000040): /* Exynos M5 */
|
||
+ case UINT32_C(0x53000030): /* Exynos M4 */
|
||
+ /* These cores are in big role w.r.t Cortex-A75 or Cortex-A76 */
|
||
+ return 6;
|
||
case UINT32_C(0x4E000030): /* Denver 2 */
|
||
- case UINT32_C(0x53000010): /* Mongoose */
|
||
- case UINT32_C(0x53000020): /* Meerkat */
|
||
+ case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */
|
||
+ case UINT32_C(0x53000020): /* Exynos M3 */
|
||
+ case UINT32_C(0x51008040): /* Kryo 485 Gold / Gold Prime */
|
||
case UINT32_C(0x51008020): /* Kryo 385 Gold */
|
||
case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */
|
||
case UINT32_C(0x51002050): /* Kryo Gold */
|
||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||
+ case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||
+ case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||
case UINT32_C(0x4100D0A0): /* Cortex-A75 */
|
||
case UINT32_C(0x4100D090): /* Cortex-A73 */
|
||
@@ -191,12 +198,14 @@ inline static uint32_t midr_score_core(uint32_t midr) {
|
||
case UINT32_C(0x4100D070): /* Cortex-A57 */
|
||
/* Cortex-A57 can be in LITTLE role w.r.t. Denver 2, or in big role w.r.t. Cortex-A53 */
|
||
return 4;
|
||
+ case UINT32_C(0x4100D060): /* Cortex-A65 */
|
||
case UINT32_C(0x4100D050): /* Cortex-A55 */
|
||
case UINT32_C(0x4100D030): /* Cortex-A53 */
|
||
/* Cortex-A53 is usually in LITTLE role, but can be in big role w.r.t. Cortex-A35 */
|
||
return 2;
|
||
case UINT32_C(0x4100D040): /* Cortex-A35 */
|
||
case UINT32_C(0x4100C070): /* Cortex-A7 */
|
||
+ case UINT32_C(0x51008050): /* Kryo 485 Silver */
|
||
case UINT32_C(0x51008030): /* Kryo 385 Silver */
|
||
case UINT32_C(0x51008010): /* Kryo 260 / 280 Silver */
|
||
case UINT32_C(0x51002110): /* Kryo Silver (Snapdragon 820) */
|
||
@@ -215,7 +224,7 @@ inline static uint32_t midr_score_core(uint32_t midr) {
|
||
}
|
||
|
||
inline static uint32_t midr_little_core_for_big(uint32_t midr) {
|
||
- const uint32_t core_mask =
|
||
+ const uint32_t core_mask =
|
||
CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||
switch (midr & core_mask) {
|
||
case CPUINFO_ARM_MIDR_CORTEX_A75:
|
||
@@ -223,7 +232,7 @@ inline static uint32_t midr_little_core_for_big(uint32_t midr) {
|
||
case CPUINFO_ARM_MIDR_CORTEX_A73:
|
||
case CPUINFO_ARM_MIDR_CORTEX_A72:
|
||
case CPUINFO_ARM_MIDR_CORTEX_A57:
|
||
- case CPUINFO_ARM_MIDR_MONGOOSE:
|
||
+ case CPUINFO_ARM_MIDR_EXYNOS_M1_M2:
|
||
return CPUINFO_ARM_MIDR_CORTEX_A53;
|
||
case CPUINFO_ARM_MIDR_CORTEX_A17:
|
||
case CPUINFO_ARM_MIDR_CORTEX_A15:
|
||
diff --git src/arm/uarch.c src/arm/uarch.c
|
||
index d7d2c63..a38250a 100644
|
||
--- src/arm/uarch.c
|
||
+++ src/arm/uarch.c
|
||
@@ -60,6 +60,9 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||
case 0xD05:
|
||
*uarch = cpuinfo_uarch_cortex_a55;
|
||
break;
|
||
+ case 0xD06:
|
||
+ *uarch = cpuinfo_uarch_cortex_a65;
|
||
+ break;
|
||
case 0xD07:
|
||
*uarch = cpuinfo_uarch_cortex_a57;
|
||
break;
|
||
@@ -75,6 +78,22 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||
case 0xD0B:
|
||
*uarch = cpuinfo_uarch_cortex_a76;
|
||
break;
|
||
+#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||
+ case 0xD0C:
|
||
+ *uarch = cpuinfo_uarch_neoverse_n1;
|
||
+ break;
|
||
+#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
|
||
+ case 0xD0D:
|
||
+ *uarch = cpuinfo_uarch_cortex_a77;
|
||
+ break;
|
||
+ case 0xD0E:
|
||
+ *uarch = cpuinfo_uarch_cortex_a76ae;
|
||
+ break;
|
||
+#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||
+ case 0xD4A:
|
||
+ *uarch = cpuinfo_uarch_neoverse_e1;
|
||
+ break;
|
||
+#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
|
||
default:
|
||
switch (midr_get_part(midr) >> 8) {
|
||
#if CPUINFO_ARCH_ARM
|
||
@@ -242,10 +261,14 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||
*vendor = cpuinfo_vendor_arm;
|
||
*uarch = cpuinfo_uarch_cortex_a55;
|
||
break;
|
||
- case 0x804:
|
||
+ case 0x804: /* High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76 */
|
||
*vendor = cpuinfo_vendor_arm;
|
||
*uarch = cpuinfo_uarch_cortex_a76;
|
||
break;
|
||
+ case 0x805: /* Low-performance Kryo 485 "Silver" -> Cortex-A55 */
|
||
+ *vendor = cpuinfo_vendor_arm;
|
||
+ *uarch = cpuinfo_uarch_cortex_a55;
|
||
+ break;
|
||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||
case 0xC00:
|
||
*uarch = cpuinfo_uarch_falkor;
|
||
@@ -263,27 +286,43 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||
switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||
case 0x00100010:
|
||
/*
|
||
- * Exynos 8890 MIDR = 0x531F0011, assume Mongoose M1 has:
|
||
+ * Exynos 8890 MIDR = 0x531F0011, assume Exynos M1 has:
|
||
* - CPU variant 0x1
|
||
* - CPU part 0x001
|
||
*/
|
||
- *uarch = cpuinfo_uarch_mongoose_m1;
|
||
+ *uarch = cpuinfo_uarch_exynos_m1;
|
||
break;
|
||
case 0x00400010:
|
||
/*
|
||
- * Exynos 8895 MIDR = 0x534F0010, assume Mongoose M2 has:
|
||
+ * Exynos 8895 MIDR = 0x534F0010, assume Exynos M2 has:
|
||
* - CPU variant 0x4
|
||
* - CPU part 0x001
|
||
*/
|
||
- *uarch = cpuinfo_uarch_mongoose_m2;
|
||
+ *uarch = cpuinfo_uarch_exynos_m2;
|
||
break;
|
||
case 0x00100020:
|
||
/*
|
||
- * Exynos 9810 MIDR = 0x531F0020, assume Meerkat M3 has:
|
||
+ * Exynos 9810 MIDR = 0x531F0020, assume Exynos M3 has:
|
||
* - CPU variant 0x1
|
||
* - CPU part 0x002
|
||
*/
|
||
- *uarch = cpuinfo_uarch_meerkat_m3;
|
||
+ *uarch = cpuinfo_uarch_exynos_m3;
|
||
+ break;
|
||
+ case 0x00100030:
|
||
+ /*
|
||
+ * Exynos 9820 MIDR = 0x531F0030, assume Exynos M4 has:
|
||
+ * - CPU variant 0x1
|
||
+ * - CPU part 0x003
|
||
+ */
|
||
+ *uarch = cpuinfo_uarch_exynos_m4;
|
||
+ break;
|
||
+ case 0x00100040:
|
||
+ /*
|
||
+ * Exynos 9820 MIDR = 0x531F0040, assume Exynos M5 has:
|
||
+ * - CPU variant 0x1
|
||
+ * - CPU part 0x004
|
||
+ */
|
||
+ *uarch = cpuinfo_uarch_exynos_m5;
|
||
break;
|
||
default:
|
||
cpuinfo_log_warning("unknown Samsung CPU variant 0x%01"PRIx32" part 0x%03"PRIx32" ignored",
|
||
diff --git src/cache.c src/cache.c
|
||
new file mode 100644
|
||
index 0000000..b976b87
|
||
--- /dev/null
|
||
+++ src/cache.c
|
||
@@ -0,0 +1,18 @@
|
||
+#include <stddef.h>
|
||
+
|
||
+#include <cpuinfo.h>
|
||
+#include <cpuinfo/internal-api.h>
|
||
+
|
||
+
|
||
+uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor) {
|
||
+ if (processor->cache.l4 != NULL) {
|
||
+ return processor->cache.l4->size;
|
||
+ } else if (processor->cache.l3 != NULL) {
|
||
+ return processor->cache.l3->size;
|
||
+ } else if (processor->cache.l2 != NULL) {
|
||
+ return processor->cache.l2->size;
|
||
+ } else if (processor->cache.l1d != NULL) {
|
||
+ return processor->cache.l1d->size;
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
diff --git src/cpuinfo/internal-api.h src/cpuinfo/internal-api.h
|
||
index 6045750..717b810 100644
|
||
--- src/cpuinfo/internal-api.h
|
||
+++ src/cpuinfo/internal-api.h
|
||
@@ -31,6 +31,7 @@ extern CPUINFO_INTERNAL uint32_t cpuinfo_cores_count;
|
||
extern CPUINFO_INTERNAL uint32_t cpuinfo_clusters_count;
|
||
extern CPUINFO_INTERNAL uint32_t cpuinfo_packages_count;
|
||
extern CPUINFO_INTERNAL uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max];
|
||
+extern CPUINFO_INTERNAL uint32_t cpuinfo_max_cache_size;
|
||
|
||
CPUINFO_PRIVATE void cpuinfo_x86_mach_init(void);
|
||
CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void);
|
||
@@ -40,4 +41,6 @@ CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void);
|
||
CPUINFO_PRIVATE void cpuinfo_arm_mach_init(void);
|
||
CPUINFO_PRIVATE void cpuinfo_arm_linux_init(void);
|
||
|
||
+CPUINFO_PRIVATE uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor);
|
||
+
|
||
typedef void (*cpuinfo_processor_callback)(uint32_t);
|
||
diff --git src/x86/isa.c src/x86/isa.c
|
||
index bca1ecd..d27dbca 100644
|
||
--- src/x86/isa.c
|
||
+++ src/x86/isa.c
|
||
@@ -42,8 +42,10 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
{
|
||
struct cpuinfo_x86_isa isa = { 0 };
|
||
|
||
- const struct cpuid_regs structured_feature_info =
|
||
+ const struct cpuid_regs structured_feature_info0 =
|
||
(max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs) { 0, 0, 0, 0};
|
||
+ const struct cpuid_regs structured_feature_info1 =
|
||
+ (max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs) { 0, 0, 0, 0};
|
||
|
||
const uint32_t processor_capacity_info_index = UINT32_C(0x80000008);
|
||
const struct cpuid_regs processor_capacity_info =
|
||
@@ -144,9 +146,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* CLFLUSHOPT instruction:
|
||
- * - Intel: ebx[bit 23] in structured feature info.
|
||
+ * - Intel: ebx[bit 23] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.clflushopt = !!(structured_feature_info.ebx & UINT32_C(0x00800000));
|
||
+ isa.clflushopt = !!(structured_feature_info0.ebx & UINT32_C(0x00800000));
|
||
|
||
/*
|
||
* MWAIT/MONITOR instructions:
|
||
@@ -273,9 +275,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* PREFETCHWT1 instruction:
|
||
- * - Intel: ecx[bit 0] of structured feature info. Reserved bit on AMD.
|
||
+ * - Intel: ecx[bit 0] of structured feature info (ecx = 0). Reserved bit on AMD.
|
||
*/
|
||
- isa.prefetchwt1 = !!(structured_feature_info.ecx & UINT32_C(0x00000001));
|
||
+ isa.prefetchwt1 = !!(structured_feature_info0.ecx & UINT32_C(0x00000001));
|
||
|
||
#if CPUINFO_ARCH_X86
|
||
/*
|
||
@@ -386,111 +388,123 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* AVX2 instructions:
|
||
- * - Intel: ebx[bit 5] in structured feature info.
|
||
+ * - Intel: ebx[bit 5] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx2 = avx_regs && !!(structured_feature_info.ebx & UINT32_C(0x00000020));
|
||
+ isa.avx2 = avx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00000020));
|
||
|
||
/*
|
||
* AVX512F instructions:
|
||
- * - Intel: ebx[bit 16] in structured feature info.
|
||
+ * - Intel: ebx[bit 16] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512f = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00010000));
|
||
+ isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
|
||
|
||
/*
|
||
* AVX512PF instructions:
|
||
- * - Intel: ebx[bit 26] in structured feature info.
|
||
+ * - Intel: ebx[bit 26] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512pf = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x04000000));
|
||
+ isa.avx512pf = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x04000000));
|
||
|
||
/*
|
||
* AVX512ER instructions:
|
||
- * - Intel: ebx[bit 27] in structured feature info.
|
||
+ * - Intel: ebx[bit 27] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512er = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x08000000));
|
||
+ isa.avx512er = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x08000000));
|
||
|
||
/*
|
||
* AVX512CD instructions:
|
||
- * - Intel: ebx[bit 28] in structured feature info.
|
||
+ * - Intel: ebx[bit 28] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512cd = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x10000000));
|
||
+ isa.avx512cd = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x10000000));
|
||
|
||
/*
|
||
* AVX512DQ instructions:
|
||
- * - Intel: ebx[bit 17] in structured feature info.
|
||
+ * - Intel: ebx[bit 17] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512dq = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00020000));
|
||
+ isa.avx512dq = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00020000));
|
||
|
||
/*
|
||
* AVX512BW instructions:
|
||
- * - Intel: ebx[bit 30] in structured feature info.
|
||
+ * - Intel: ebx[bit 30] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512bw = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x40000000));
|
||
+ isa.avx512bw = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x40000000));
|
||
|
||
/*
|
||
* AVX512VL instructions:
|
||
- * - Intel: ebx[bit 31] in structured feature info.
|
||
+ * - Intel: ebx[bit 31] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512vl = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x80000000));
|
||
+ isa.avx512vl = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x80000000));
|
||
|
||
/*
|
||
* AVX512IFMA instructions:
|
||
- * - Intel: ebx[bit 21] in structured feature info.
|
||
+ * - Intel: ebx[bit 21] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512ifma = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00200000));
|
||
+ isa.avx512ifma = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00200000));
|
||
|
||
/*
|
||
* AVX512VBMI instructions:
|
||
- * - Intel: ecx[bit 1] in structured feature info.
|
||
+ * - Intel: ecx[bit 1] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512vbmi = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000002));
|
||
+ isa.avx512vbmi = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000002));
|
||
|
||
/*
|
||
* AVX512VBMI2 instructions:
|
||
- * - Intel: ecx[bit 6] in structured feature info.
|
||
+ * - Intel: ecx[bit 6] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512vbmi2 = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000040));
|
||
+ isa.avx512vbmi2 = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000040));
|
||
|
||
/*
|
||
* AVX512BITALG instructions:
|
||
- * - Intel: ecx[bit 12] in structured feature info.
|
||
+ * - Intel: ecx[bit 12] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512bitalg = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00001000));
|
||
+ isa.avx512bitalg = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00001000));
|
||
|
||
/*
|
||
* AVX512VPOPCNTDQ instructions:
|
||
- * - Intel: ecx[bit 14] in structured feature info.
|
||
+ * - Intel: ecx[bit 14] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512vpopcntdq = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00004000));
|
||
+ isa.avx512vpopcntdq = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00004000));
|
||
|
||
/*
|
||
* AVX512VNNI instructions:
|
||
- * - Intel: ecx[bit 11] in structured feature info.
|
||
+ * - Intel: ecx[bit 11] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512vnni = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000800));
|
||
+ isa.avx512vnni = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000800));
|
||
|
||
/*
|
||
* AVX512_4VNNIW instructions:
|
||
- * - Intel: edx[bit 2] in structured feature info.
|
||
+ * - Intel: edx[bit 2] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512_4vnniw = avx512_regs && !!(structured_feature_info.edx & UINT32_C(0x00000004));
|
||
+ isa.avx512_4vnniw = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000004));
|
||
|
||
/*
|
||
* AVX512_4FMAPS instructions:
|
||
- * - Intel: edx[bit 3] in structured feature info.
|
||
+ * - Intel: edx[bit 3] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.avx512_4fmaps = avx512_regs && !!(structured_feature_info.edx & UINT32_C(0x00000008));
|
||
+ isa.avx512_4fmaps = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000008));
|
||
+
|
||
+ /*
|
||
+ * AVX512_VP2INTERSECT instructions:
|
||
+ * - Intel: edx[bit 8] in structured feature info (ecx = 0).
|
||
+ */
|
||
+ isa.avx512vp2intersect = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000100));
|
||
+
|
||
+ /*
|
||
+ * AVX512_BF16 instructions:
|
||
+ * - Intel: eax[bit 5] in structured feature info (ecx = 1).
|
||
+ */
|
||
+ isa.avx512bf16 = avx512_regs && !!(structured_feature_info1.eax & UINT32_C(0x00000020));
|
||
|
||
/*
|
||
* HLE instructions:
|
||
- * - Intel: ebx[bit 4] in structured feature info.
|
||
+ * - Intel: ebx[bit 4] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.hle = !!(structured_feature_info.ebx & UINT32_C(0x00000010));
|
||
+ isa.hle = !!(structured_feature_info0.ebx & UINT32_C(0x00000010));
|
||
|
||
/*
|
||
* RTM instructions:
|
||
- * - Intel: ebx[bit 11] in structured feature info.
|
||
+ * - Intel: ebx[bit 11] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.rtm = !!(structured_feature_info.ebx & UINT32_C(0x00000800));
|
||
+ isa.rtm = !!(structured_feature_info0.ebx & UINT32_C(0x00000800));
|
||
|
||
/*
|
||
* XTEST instruction:
|
||
@@ -500,9 +514,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* MPX registers and instructions:
|
||
- * - Intel: ebx[bit 14] in structured feature info.
|
||
+ * - Intel: ebx[bit 14] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.mpx = mpx_regs && !!(structured_feature_info.ebx & UINT32_C(0x00004000));
|
||
+ isa.mpx = mpx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00004000));
|
||
|
||
#if CPUINFO_ARCH_X86
|
||
/*
|
||
@@ -528,9 +542,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* CLWB instruction:
|
||
- * - Intel: ebx[bit 24] in structured feature info.
|
||
+ * - Intel: ebx[bit 24] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.clwb = !!(structured_feature_info.ebx & UINT32_C(0x01000000));
|
||
+ isa.clwb = !!(structured_feature_info0.ebx & UINT32_C(0x01000000));
|
||
|
||
/*
|
||
* MOVBE instruction:
|
||
@@ -549,9 +563,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions.
|
||
- * - Intel: ebx[bit 0] in structured feature info.
|
||
+ * - Intel: ebx[bit 0] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.fs_gs_base = !!(structured_feature_info.ebx & UINT32_C(0x00000001));
|
||
+ isa.fs_gs_base = !!(structured_feature_info0.ebx & UINT32_C(0x00000001));
|
||
|
||
/*
|
||
* LZCNT instruction:
|
||
@@ -573,21 +587,21 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* BMI instructions:
|
||
- * - Intel, AMD: ebx[bit 3] in structured feature info.
|
||
+ * - Intel, AMD: ebx[bit 3] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.bmi = !!(structured_feature_info.ebx & UINT32_C(0x00000008));
|
||
+ isa.bmi = !!(structured_feature_info0.ebx & UINT32_C(0x00000008));
|
||
|
||
/*
|
||
* BMI2 instructions:
|
||
- * - Intel: ebx[bit 8] in structured feature info.
|
||
+ * - Intel: ebx[bit 8] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.bmi2 = !!(structured_feature_info.ebx & UINT32_C(0x00000100));
|
||
+ isa.bmi2 = !!(structured_feature_info0.ebx & UINT32_C(0x00000100));
|
||
|
||
/*
|
||
* ADCX/ADOX instructions:
|
||
- * - Intel: ebx[bit 19] in structured feature info.
|
||
+ * - Intel: ebx[bit 19] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.adx = !!(structured_feature_info.ebx & UINT32_C(0x00080000));
|
||
+ isa.adx = !!(structured_feature_info0.ebx & UINT32_C(0x00080000));
|
||
|
||
/*
|
||
* AES instructions:
|
||
@@ -597,9 +611,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* VAES instructions:
|
||
- * - Intel: ecx[bit 9] in structured feature info.
|
||
+ * - Intel: ecx[bit 9] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.vaes = !!(structured_feature_info.ecx & UINT32_C(0x00000200));
|
||
+ isa.vaes = !!(structured_feature_info0.ecx & UINT32_C(0x00000200));
|
||
|
||
/*
|
||
* PCLMULQDQ instruction:
|
||
@@ -609,15 +623,15 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* VPCLMULQDQ instruction:
|
||
- * - Intel: ecx[bit 10] in structured feature info.
|
||
+ * - Intel: ecx[bit 10] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.vpclmulqdq = !!(structured_feature_info.ecx & UINT32_C(0x00000400));
|
||
+ isa.vpclmulqdq = !!(structured_feature_info0.ecx & UINT32_C(0x00000400));
|
||
|
||
/*
|
||
* GFNI instructions:
|
||
- * - Intel: ecx[bit 8] in structured feature info.
|
||
+ * - Intel: ecx[bit 8] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.gfni = !!(structured_feature_info.ecx & UINT32_C(0x00000100));
|
||
+ isa.gfni = !!(structured_feature_info0.ecx & UINT32_C(0x00000100));
|
||
|
||
/*
|
||
* RDRAND instruction:
|
||
@@ -627,15 +641,15 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* RDSEED instruction:
|
||
- * - Intel: ebx[bit 18] in structured feature info.
|
||
+ * - Intel: ebx[bit 18] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.rdseed = !!(structured_feature_info.ebx & UINT32_C(0x00040000));
|
||
+ isa.rdseed = !!(structured_feature_info0.ebx & UINT32_C(0x00040000));
|
||
|
||
/*
|
||
* SHA instructions:
|
||
- * - Intel: ebx[bit 29] in structured feature info.
|
||
+ * - Intel: ebx[bit 29] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.sha = !!(structured_feature_info.ebx & UINT32_C(0x20000000));
|
||
+ isa.sha = !!(structured_feature_info0.ebx & UINT32_C(0x20000000));
|
||
|
||
if (vendor == cpuinfo_vendor_via) {
|
||
const struct cpuid_regs padlock_meta_info = cpuid(UINT32_C(0xC0000000));
|
||
@@ -700,9 +714,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||
|
||
/*
|
||
* RDPID instruction:
|
||
- * - Intel: ecx[bit 22] in structured feature info.
|
||
+ * - Intel: ecx[bit 22] in structured feature info (ecx = 0).
|
||
*/
|
||
- isa.rdpid = !!(structured_feature_info.ecx & UINT32_C(0x00400000));
|
||
+ isa.rdpid = !!(structured_feature_info0.ecx & UINT32_C(0x00400000));
|
||
|
||
return isa;
|
||
}
|
||
diff --git src/x86/linux/init.c src/x86/linux/init.c
|
||
index b5f74d0..c096336 100644
|
||
--- src/x86/linux/init.c
|
||
+++ src/x86/linux/init.c
|
||
@@ -592,6 +592,8 @@ void cpuinfo_x86_linux_init(void) {
|
||
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]);
|
||
+
|
||
__sync_synchronize();
|
||
|
||
cpuinfo_is_initialized = true;
|
||
diff --git src/x86/mach/init.c src/x86/mach/init.c
|
||
index 7b41ad0..ae2be33 100644
|
||
--- src/x86/mach/init.c
|
||
+++ src/x86/mach/init.c
|
||
@@ -327,6 +327,8 @@ void cpuinfo_x86_mach_init(void) {
|
||
cpuinfo_clusters_count = mach_topology.packages;
|
||
cpuinfo_packages_count = mach_topology.packages;
|
||
|
||
+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]);
|
||
+
|
||
__sync_synchronize();
|
||
|
||
cpuinfo_is_initialized = true;
|
||
diff --git src/x86/uarch.c src/x86/uarch.c
|
||
index 71c899e..ba72d8a 100644
|
||
--- src/x86/uarch.c
|
||
+++ src/x86/uarch.c
|
||
@@ -74,13 +74,19 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||
case 0x4F: // Broadwell-E
|
||
case 0x56: // Broadwell-DE
|
||
return cpuinfo_uarch_broadwell;
|
||
- case 0x4E: // Skylake-U/Y
|
||
- case 0x55: // Skylake Server (SKX)
|
||
- case 0x5E: // Skylake-H/S
|
||
+ case 0x4E: // Sky Lake Client Y/U
|
||
+ case 0x55: // Sky/Cascade/Cooper Lake Server
|
||
+ case 0x5E: // Sky Lake Client DT/H/S
|
||
+ case 0x8E: // Kaby/Whiskey/Amber/Comet Lake Y/U
|
||
+ case 0x9E: // Kaby/Coffee Lake DT/H/S
|
||
return cpuinfo_uarch_sky_lake;
|
||
- case 0x8E: // Kaby Lake U/Y
|
||
- case 0x9E: // Kaby Lake H/S
|
||
- return cpuinfo_uarch_kaby_lake;
|
||
+ case 0x66: // Cannon Lake (Core i3-8121U)
|
||
+ return cpuinfo_uarch_palm_cove;
|
||
+ case 0x6A: // Ice Lake-DE
|
||
+ case 0x6C: // Ice Lake-SP
|
||
+ case 0x7D: // Ice Lake-Y
|
||
+ case 0x7E: // Ice Lake-U
|
||
+ return cpuinfo_uarch_sunny_cove;
|
||
|
||
/* Low-power cores */
|
||
case 0x1C: // Diamondville, Silverthorne, Pineview
|
||
@@ -90,18 +96,20 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||
case 0x35: // Cloverview
|
||
case 0x36: // Cedarview, Centerton
|
||
return cpuinfo_uarch_saltwell;
|
||
- case 0x37:
|
||
- case 0x4A:
|
||
- case 0x4D:
|
||
+ case 0x37: // Bay Trail
|
||
+ case 0x4A: // Merrifield
|
||
+ case 0x4D: // Avoton, Rangeley
|
||
case 0x5A: // Moorefield
|
||
case 0x5D: // SoFIA
|
||
return cpuinfo_uarch_silvermont;
|
||
- case 0x4C: // Braswell
|
||
- case 0x5F: // Denverton
|
||
+ case 0x4C: // Braswell, Cherry Trail
|
||
case 0x75: // Spreadtrum SC9853I-IA
|
||
- case 0x7A: // Goldmont+
|
||
return cpuinfo_uarch_airmont;
|
||
-
|
||
+ case 0x5C: // Apollo Lake
|
||
+ case 0x5F: // Denverton
|
||
+ return cpuinfo_uarch_goldmont;
|
||
+ case 0x7A: // Gemini Lake
|
||
+ return cpuinfo_uarch_goldmont_plus;
|
||
/* Knights-series cores */
|
||
case 0x57:
|
||
return cpuinfo_uarch_knights_landing;
|
||
@@ -190,7 +198,15 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||
return cpuinfo_uarch_jaguar;
|
||
}
|
||
case 0x17:
|
||
- return cpuinfo_uarch_zen;
|
||
+ switch (model_info->model) {
|
||
+ case 0x01: // 14 nm Naples, Whitehaven, Summit Ridge, Snowy Owl
|
||
+ case 0x08: // 12 nm Pinnacle Ridge
|
||
+ case 0x11: // 14 nm Raven Ridge
|
||
+ case 0x18: // 12 nm Picasso
|
||
+ return cpuinfo_uarch_zen;
|
||
+ case 0x71: // Matisse
|
||
+ return cpuinfo_uarch_zen2;
|
||
+ }
|
||
}
|
||
break;
|
||
default:
|
||
diff --git src/x86/windows/init.c src/x86/windows/init.c
|
||
index eb3498a..7a2090e 100644
|
||
--- src/x86/windows/init.c
|
||
+++ src/x86/windows/init.c
|
||
@@ -571,6 +571,8 @@ BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PV
|
||
cpuinfo_clusters_count = packages_count;
|
||
cpuinfo_packages_count = packages_count;
|
||
|
||
+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]);
|
||
+
|
||
MemoryBarrier();
|
||
|
||
cpuinfo_is_initialized = true;
|
||
diff --git tools/cache-info.c tools/cache-info.c
|
||
index ba0706f..05f69ee 100644
|
||
--- tools/cache-info.c
|
||
+++ tools/cache-info.c
|
||
@@ -60,6 +60,8 @@ int main(int argc, char** argv) {
|
||
fprintf(stderr, "failed to initialize CPU information\n");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
+ printf("Max cache size (upper bound): %"PRIu32" bytes\n", cpuinfo_get_max_cache_size());
|
||
+
|
||
if (cpuinfo_get_l1i_caches_count() != 0 && (cpuinfo_get_l1i_cache(0)->flags & CPUINFO_CACHE_UNIFIED) == 0) {
|
||
report_cache(cpuinfo_get_l1i_caches_count(), cpuinfo_get_l1i_cache(0), 1, "instruction");
|
||
}
|
||
diff --git tools/cpu-info.c tools/cpu-info.c
|
||
index caef424..7fa5187 100644
|
||
--- tools/cpu-info.c
|
||
+++ tools/cpu-info.c
|
||
@@ -73,8 +73,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Broadwell";
|
||
case cpuinfo_uarch_sky_lake:
|
||
return "Sky Lake";
|
||
- case cpuinfo_uarch_kaby_lake:
|
||
- return "Kaby Lake";
|
||
+ case cpuinfo_uarch_palm_cove:
|
||
+ return "Palm Cove";
|
||
+ case cpuinfo_uarch_sunny_cove:
|
||
+ return "Sunny Cove";
|
||
case cpuinfo_uarch_willamette:
|
||
return "Willamette";
|
||
case cpuinfo_uarch_prescott:
|
||
@@ -87,6 +89,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Silvermont";
|
||
case cpuinfo_uarch_airmont:
|
||
return "Airmont";
|
||
+ case cpuinfo_uarch_goldmont:
|
||
+ return "Goldmont";
|
||
+ case cpuinfo_uarch_goldmont_plus:
|
||
+ return "Goldmont Plus";
|
||
case cpuinfo_uarch_knights_ferry:
|
||
return "Knights Ferry";
|
||
case cpuinfo_uarch_knights_corner:
|
||
@@ -117,6 +123,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Excavator";
|
||
case cpuinfo_uarch_zen:
|
||
return "Zen";
|
||
+ case cpuinfo_uarch_zen2:
|
||
+ return "Zen 2";
|
||
case cpuinfo_uarch_geode:
|
||
return "Geode";
|
||
case cpuinfo_uarch_bobcat:
|
||
@@ -157,6 +165,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Cortex-A55";
|
||
case cpuinfo_uarch_cortex_a57:
|
||
return "Cortex-A57";
|
||
+ case cpuinfo_uarch_cortex_a65:
|
||
+ return "Cortex-A65";
|
||
case cpuinfo_uarch_cortex_a72:
|
||
return "Cortex-A72";
|
||
case cpuinfo_uarch_cortex_a73:
|
||
@@ -165,6 +175,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Cortex-A75";
|
||
case cpuinfo_uarch_cortex_a76:
|
||
return "Cortex-A76";
|
||
+ case cpuinfo_uarch_cortex_a76ae:
|
||
+ return "Cortex-A76AE";
|
||
+ case cpuinfo_uarch_cortex_a77:
|
||
+ return "Cortex-A77";
|
||
case cpuinfo_uarch_scorpion:
|
||
return "Scorpion";
|
||
case cpuinfo_uarch_krait:
|
||
@@ -181,12 +195,16 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
|
||
return "Denver 2";
|
||
case cpuinfo_uarch_carmel:
|
||
return "Carmel";
|
||
- case cpuinfo_uarch_mongoose_m1:
|
||
- return "Mongoose M1";
|
||
- case cpuinfo_uarch_mongoose_m2:
|
||
- return "Mongoose M2";
|
||
- case cpuinfo_uarch_meerkat_m3:
|
||
- return "Meerkat M3";
|
||
+ case cpuinfo_uarch_exynos_m1:
|
||
+ return "Exynos M1";
|
||
+ case cpuinfo_uarch_exynos_m2:
|
||
+ return "Exynos M2";
|
||
+ case cpuinfo_uarch_exynos_m3:
|
||
+ return "Exynos M3";
|
||
+ case cpuinfo_uarch_exynos_m4:
|
||
+ return "Exynos M4";
|
||
+ case cpuinfo_uarch_exynos_m5:
|
||
+ return "Exynos M5";
|
||
case cpuinfo_uarch_swift:
|
||
return "Swift";
|
||
case cpuinfo_uarch_cyclone:
|
||
@@ -258,13 +276,23 @@ int main(int argc, char** argv) {
|
||
printf(", %s %s\n", vendor_string, uarch_string);
|
||
}
|
||
}
|
||
- printf("Logical processors:\n");
|
||
+ printf("Logical processors");
|
||
+ #if defined(__linux__)
|
||
+ printf(" (System ID)");
|
||
+ #endif
|
||
+ printf(":\n");
|
||
for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) {
|
||
const struct cpuinfo_processor* processor = cpuinfo_get_processor(i);
|
||
+ printf("\t%"PRIu32"", i);
|
||
+
|
||
+ #if defined(__linux__)
|
||
+ printf(" (%"PRId32")", processor->linux_id);
|
||
+ #endif
|
||
+
|
||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||
- printf("\t%"PRIu32": APIC ID 0x%08"PRIx32"\n", i, processor->apic_id);
|
||
+ printf(": APIC ID 0x%08"PRIx32"\n", processor->apic_id);
|
||
#else
|
||
- printf("\t%"PRIu32"\n", i);
|
||
+ printf("\n");
|
||
#endif
|
||
}
|
||
}
|
||
diff --git tools/isa-info.c tools/isa-info.c
|
||
index 594c46a..98ef919 100644
|
||
--- tools/isa-info.c
|
||
+++ tools/isa-info.c
|
||
@@ -67,6 +67,8 @@ int main(int argc, char** argv) {
|
||
printf("\tAVX512BITALG: %s\n", cpuinfo_has_x86_avx512bitalg() ? "yes" : "no");
|
||
printf("\tAVX512VPOPCNTDQ: %s\n", cpuinfo_has_x86_avx512vpopcntdq() ? "yes" : "no");
|
||
printf("\tAVX512VNNI: %s\n", cpuinfo_has_x86_avx512vnni() ? "yes" : "no");
|
||
+ printf("\tAVX512BF16: %s\n", cpuinfo_has_x86_avx512bf16() ? "yes" : "no");
|
||
+ printf("\tAVX512VP2INTERSECT: %s\n", cpuinfo_has_x86_avx512vp2intersect() ? "yes" : "no");
|
||
printf("\tAVX512_4VNNIW: %s\n", cpuinfo_has_x86_avx512_4vnniw() ? "yes" : "no");
|
||
printf("\tAVX512_4FMAPS: %s\n", cpuinfo_has_x86_avx512_4fmaps() ? "yes" : "no");
|
||
|