aboutsummaryrefslogtreecommitdiff
path: root/src/arm/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/linux')
-rw-r--r--src/arm/linux/aarch32-isa.c9
-rw-r--r--src/arm/linux/aarch64-isa.c18
-rw-r--r--src/arm/linux/chipset.c94
-rw-r--r--src/arm/linux/clusters.c20
-rw-r--r--src/arm/linux/cpuinfo.c8
-rw-r--r--src/arm/linux/init.c2
-rw-r--r--src/arm/linux/midr.c6
7 files changed, 134 insertions, 23 deletions
diff --git a/src/arm/linux/aarch32-isa.c b/src/arm/linux/aarch32-isa.c
index df68aa1..fb95ee9 100644
--- a/src/arm/linux/aarch32-isa.c
+++ b/src/arm/linux/aarch32-isa.c
@@ -64,6 +64,8 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
* - Processors with Exynos M4 cores
* - Processors with Exynos M5 cores
* - Neoverse N1 cores
+ * - Neoverse V1 cores
+ * - Neoverse N2 cores
*/
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
/* Only little cores of Exynos 9810 support FP16 & RDM */
@@ -73,9 +75,11 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
case UINT32_C(0x4100D050): /* Cortex-A55 */
case UINT32_C(0x4100D060): /* Cortex-A65 */
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
- case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
+ case UINT32_C(0x4100D460): /* Cortex-A510 */
+ case UINT32_C(0x4100D470): /* Cortex-A710 */
+ case UINT32_C(0x4100D480): /* Cortex-X2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
@@ -98,6 +102,9 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
+ case UINT32_C(0x4100D460): /* Cortex-A510 */
+ case UINT32_C(0x4100D470): /* Cortex-A710 */
+ case UINT32_C(0x4100D480): /* Cortex-X2 */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
case UINT32_C(0x53000030): /* Exynos-M4 */
diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c
index 2000e1a..44a8f4d 100644
--- a/src/arm/linux/aarch64-isa.c
+++ b/src/arm/linux/aarch64-isa.c
@@ -41,6 +41,8 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
* - Processors with Exynos M4 cores
* - Processors with Exynos M5 cores
* - Neoverse N1 cores
+ * - Neoverse V1 cores
+ * - Neoverse N2 cores
*/
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
/* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */
@@ -54,6 +56,8 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
+ case UINT32_C(0x4100D400): /* Neoverse V1 */
+ case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
@@ -78,6 +82,9 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
break;
}
}
+ if (features2 & CPUINFO_ARM_LINUX_FEATURE2_I8MM) {
+ isa->i8mm = true;
+ }
/*
* Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions.
@@ -89,6 +96,8 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
+ case UINT32_C(0x4100D400): /* Neoverse V1 */
+ case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4100D4A0): /* Neoverse E1 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
@@ -124,4 +133,13 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) {
isa->sve2 = 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.
+ if (features2 & (CPUINFO_ARM_LINUX_FEATURE2_BF16 | CPUINFO_ARM_LINUX_FEATURE2_SVEBF16)) {
+ isa->bf16 = true;
+ }
+ if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) {
+ isa->fhm = true;
+ }
}
+
diff --git a/src/arm/linux/chipset.c b/src/arm/linux/chipset.c
index e36283c..f2a002d 100644
--- a/src/arm/linux/chipset.c
+++ b/src/arm/linux/chipset.c
@@ -1,3 +1,4 @@
+#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -281,6 +282,82 @@ static bool match_sm(
return true;
}
+
+struct special_map_entry {
+ const char* platform;
+ uint16_t model;
+ uint8_t series;
+ char suffix;
+};
+
+static const struct special_map_entry qualcomm_hardware_map_entries[] = {
+ {
+ /* "Kona" -> Qualcomm Kona */
+ .platform = "Kona",
+ .series = cpuinfo_arm_chipset_series_qualcomm_snapdragon,
+ .model = 865,
+ },
+ {
+ /* "Bengal" -> Qualcomm Bengal */
+ .platform = "Bengal",
+ .series = cpuinfo_arm_chipset_series_qualcomm_snapdragon,
+ .model = 662,
+ },
+ {
+ /* "Bengalp" -> Qualcomm Bengalp */
+ .platform = "Bengalp",
+ .series = cpuinfo_arm_chipset_series_qualcomm_snapdragon,
+ .model = 662,
+ },
+ {
+ /* "Lito" -> Qualcomm Lito */
+ .platform = "Lito",
+ .series = cpuinfo_arm_chipset_series_qualcomm_snapdragon,
+ .model = 765,
+ .suffix = 'G'
+ },
+ {
+ /* "Lagoon" -> Qualcomm Lagoon */
+ .platform = "Lagoon",
+ .series = cpuinfo_arm_chipset_series_qualcomm_snapdragon,
+ .model = 0,
+ },
+};
+
+
+int strcicmp(char const *a, char const *b)
+{
+ for (;; a++, b++) {
+ int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
+ if (d != 0 || !*a)
+ return d;
+ }
+}
+
+static bool match_qualcomm_special(
+ const char* start, const char* end,
+ struct cpuinfo_arm_chipset chipset[restrict static 1])
+{
+ for (size_t i = 0; i < CPUINFO_COUNT_OF(qualcomm_hardware_map_entries); i++) {
+ int length = end - start;
+ if (strcicmp(qualcomm_hardware_map_entries[i].platform, start) == 0 &&
+ qualcomm_hardware_map_entries[i].platform[length] == 0)
+ {
+ *chipset = (struct cpuinfo_arm_chipset) {
+ .vendor = chipset_series_vendor[qualcomm_hardware_map_entries[i].series],
+ .series = (enum cpuinfo_arm_chipset_series) qualcomm_hardware_map_entries[i].series,
+ .model = qualcomm_hardware_map_entries[i].model,
+ .suffix = {
+ [0] = qualcomm_hardware_map_entries[i].suffix,
+ },
+ };
+ return true;
+ }
+ }
+ return false;
+
+}
+
/**
* Tries to match /Samsung Exynos\d{4}$/ signature (case-insensitive) for Samsung Exynos chipsets.
* If match successful, extracts model information into \p chipset argument.
@@ -1351,7 +1428,7 @@ static bool match_and_parse_sunxi(
return false;
}
- /* Compare sunXi platform id and number of cores to tabluted values to decode chipset name */
+ /* Compare sunXi platform id and number of cores to tabulated values to decode chipset name */
uint32_t model = 0;
char suffix = 0;
for (size_t i = 0; i < CPUINFO_COUNT_OF(sunxi_map_entries); i++) {
@@ -1752,13 +1829,6 @@ static bool is_tegra(const char* start, const char* end) {
return (length == 5 || start[5] == '3');
}
-struct special_map_entry {
- const char* platform;
- uint16_t model;
- uint8_t series;
- char suffix;
-};
-
static const struct special_map_entry special_hardware_map_entries[] = {
#if CPUINFO_ARCH_ARM
{
@@ -2317,6 +2387,14 @@ struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_ha
(int) hardware_length, hardware);
return chipset;
}
+
+ if (match_qualcomm_special(pos, hardware_end, &chipset)) {
+ cpuinfo_log_debug(
+ "matched Qualcomm signature in /proc/cpuinfo Hardware string \"%.*s\"",
+ (int) hardware_length, hardware);
+ return chipset;
+ }
+
}
word_start = false;
break;
diff --git a/src/arm/linux/clusters.c b/src/arm/linux/clusters.c
index c7a4045..430773d 100644
--- a/src/arm/linux/clusters.c
+++ b/src/arm/linux/clusters.c
@@ -48,7 +48,7 @@ static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
* @param usable_processors - number of processors in the @p processors array with CPUINFO_LINUX_FLAG_VALID flags.
* @param max_processors - number of elements in the @p processors array.
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
- * frequency, MIDR infromation, and core cluster (package siblings list) information.
+ * frequency, MIDR information, and core cluster (package siblings list) information.
*
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
@@ -292,9 +292,9 @@ bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
* - Processors assigned to these clusters stay assigned to the same clusters
* - No new processors are added to these clusters
* - Processors without pre-assigned cluster are clustered in one sequential scan:
- * - If known details (min/max frequency, MIDR components) of a processor are compatible with a preceeding
- * processor, without pre-assigned cluster, the processor is assigned to the cluster of the preceeding processor.
- * - If known details (min/max frequency, MIDR components) of a processor are not compatible with a preceeding
+ * - If known details (min/max frequency, MIDR components) of a processor are compatible with a preceding
+ * processor, without pre-assigned cluster, the processor is assigned to the cluster of the preceding processor.
+ * - If known details (min/max frequency, MIDR components) of a processor are not compatible with a preceding
* processor, the processor is assigned to a newly created cluster.
*
* The function must be called after parsing OS-provided information on core clusters, and usually is called only
@@ -309,7 +309,7 @@ bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
*
* @param max_processors - number of elements in the @p processors array.
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
- * frequency, MIDR infromation, and core cluster (package siblings list) information.
+ * frequency, MIDR information, and core cluster (package siblings list) information.
*
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
@@ -331,7 +331,7 @@ void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
if (cluster_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (cluster_min_frequency != processors[i].min_frequency) {
cpuinfo_log_info(
- "minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceeding cluster (%"PRIu32" KHz); "
+ "minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceding cluster (%"PRIu32" KHz); "
"processor %"PRIu32" starts to a new cluster",
i, processors[i].min_frequency, cluster_min_frequency, i);
goto new_cluster;
@@ -346,7 +346,7 @@ void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
if (cluster_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (cluster_max_frequency != processors[i].max_frequency) {
cpuinfo_log_debug(
- "maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceeding cluster (%"PRIu32" KHz); "
+ "maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceding cluster (%"PRIu32" KHz); "
"processor %"PRIu32" starts a new cluster",
i, processors[i].max_frequency, cluster_max_frequency, i);
goto new_cluster;
@@ -361,7 +361,7 @@ void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
if ((cluster_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK)) {
cpuinfo_log_debug(
- "CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of preceeding cluster (0x%02"PRIx32"); "
+ "CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of preceding cluster (0x%02"PRIx32"); "
"processor %"PRIu32" starts to a new cluster",
i, midr_get_implementer(processors[i].midr), midr_get_implementer(cluster_midr), i);
goto new_cluster;
@@ -417,11 +417,11 @@ void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
}
}
- /* All checks passed, attach processor to the preceeding cluster */
+ /* All checks passed, attach processor to the preceding cluster */
cluster_processors++;
processors[i].package_leader_id = cluster_start;
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
- cpuinfo_log_debug("assigned processor %"PRIu32" to preceeding cluster of processor %"PRIu32, i, cluster_start);
+ cpuinfo_log_debug("assigned processor %"PRIu32" to preceding cluster of processor %"PRIu32, i, cluster_start);
continue;
new_cluster:
diff --git a/src/arm/linux/cpuinfo.c b/src/arm/linux/cpuinfo.c
index 90e1631..817da12 100644
--- a/src/arm/linux/cpuinfo.c
+++ b/src/arm/linux/cpuinfo.c
@@ -177,6 +177,10 @@ static void parse_features(
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FCMA;
#endif
+ } else if (memcmp(feature_start, "i8mm", feature_length) == 0) {
+ #if CPUINFO_ARCH_ARM64
+ processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_I8MM;
+ #endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "half", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_HALF;
@@ -283,6 +287,10 @@ static void parse_features(
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM;
#endif
+ } else if (memcmp(feature_start, "asimdfhm", feature_length) == 0) {
+ #if CPUINFO_ARCH_ARM64
+ processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM;
+ #endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "fastmult", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FASTMULT;
diff --git a/src/arm/linux/init.c b/src/arm/linux/init.c
index 23d8439..d3da5a9 100644
--- a/src/arm/linux/init.c
+++ b/src/arm/linux/init.c
@@ -510,7 +510,7 @@ void cpuinfo_arm_linux_init(void) {
uint32_t l2_count = 0, l3_count = 0, big_l3_size = 0, cluster_id = UINT32_MAX;
/* Indication whether L3 (if it exists) is shared between all cores */
bool shared_l3 = true;
- /* Populate cache infromation structures in l1i, l1d */
+ /* Populate cache information structures in l1i, l1d */
for (uint32_t i = 0; i < valid_processors; i++) {
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
cluster_id += 1;
diff --git a/src/arm/linux/midr.c b/src/arm/linux/midr.c
index 2c3116b..0d8f03f 100644
--- a/src/arm/linux/midr.c
+++ b/src/arm/linux/midr.c
@@ -675,10 +675,10 @@ static bool cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
/*
* Initializes MIDR for leaders of core clusters in a single sequential scan:
- * - Clusters preceeding the first reported MIDR value are assumed to have default MIDR value.
+ * - Clusters preceding the first reported MIDR value are assumed to have default MIDR value.
* - Clusters following any reported MIDR value to have that MIDR value.
*
- * @param default_midr - MIDR value that will be assigned to cluster leaders preceeding any reported MIDR value.
+ * @param default_midr - MIDR value that will be assigned to cluster leaders preceding any reported MIDR value.
* @param processors_count - number of logical processor descriptions in the @p processors array.
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
* and decoded core cluster (package_leader_id) information.
@@ -833,7 +833,7 @@ uint32_t cpuinfo_arm_linux_detect_cluster_midr(
* 2. For systems with 2 clusters and MIDR known for one cluster, assume big.LITTLE configuration,
* and estimate MIDR for the other cluster under assumption that MIDR for the big cluster is known.
* 3. Initialize MIDRs for core clusters in a single sequential scan:
- * - Clusters preceeding the first reported MIDR value are assumed to have the last reported MIDR value.
+ * - Clusters preceding 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.
*/