Commit 1df31050 authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Will Deacon

arm64: Add helpers for checking CPU MIDR against a range

Add helpers for checking if the given CPU midr falls in a range
of variants/revisions for a given model.

Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: default avatarDave Martin <dave.martin@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 5e7951ce
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define __ASM_CPUFEATURE_H #define __ASM_CPUFEATURE_H
#include <asm/cpucaps.h> #include <asm/cpucaps.h>
#include <asm/cputype.h>
#include <asm/fpsimd.h> #include <asm/fpsimd.h>
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
...@@ -306,8 +307,7 @@ struct arm64_cpu_capabilities { ...@@ -306,8 +307,7 @@ struct arm64_cpu_capabilities {
void (*cpu_enable)(const struct arm64_cpu_capabilities *cap); void (*cpu_enable)(const struct arm64_cpu_capabilities *cap);
union { union {
struct { /* To be used for erratum handling only */ struct { /* To be used for erratum handling only */
u32 midr_model; struct midr_range midr_range;
u32 midr_range_min, midr_range_max;
const struct arm64_midr_revidr { const struct arm64_midr_revidr {
u32 midr_rv; /* revision/variant */ u32 midr_rv; /* revision/variant */
u32 revidr_mask; u32 revidr_mask;
......
...@@ -117,6 +117,36 @@ ...@@ -117,6 +117,36 @@
#define read_cpuid(reg) read_sysreg_s(SYS_ ## reg) #define read_cpuid(reg) read_sysreg_s(SYS_ ## reg)
/*
* Represent a range of MIDR values for a given CPU model and a
* range of variant/revision values.
*
* @model - CPU model as defined by MIDR_CPU_MODEL
* @rv_min - Minimum value for the revision/variant as defined by
* MIDR_CPU_VAR_REV
* @rv_max - Maximum value for the variant/revision for the range.
*/
struct midr_range {
u32 model;
u32 rv_min;
u32 rv_max;
};
#define MIDR_RANGE(m, v_min, r_min, v_max, r_max) \
{ \
.model = m, \
.rv_min = MIDR_CPU_VAR_REV(v_min, r_min), \
.rv_max = MIDR_CPU_VAR_REV(v_max, r_max), \
}
#define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
{
return MIDR_IS_CPU_MODEL_RANGE(midr, range->model,
range->rv_min, range->rv_max);
}
/* /*
* The CPU ID never changes at run time, so we might as well tell the * The CPU ID never changes at run time, so we might as well tell the
* compiler that it's constant. Use this function to read the CPU ID * compiler that it's constant. Use this function to read the CPU ID
......
...@@ -28,9 +28,7 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) ...@@ -28,9 +28,7 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
u32 midr = read_cpuid_id(), revidr; u32 midr = read_cpuid_id(), revidr;
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
if (!MIDR_IS_CPU_MODEL_RANGE(midr, entry->midr_model, if (!is_midr_in_range(midr, &entry->midr_range))
entry->midr_range_min,
entry->midr_range_max))
return false; return false;
midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK; midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
...@@ -53,7 +51,7 @@ is_kryo_midr(const struct arm64_cpu_capabilities *entry, int scope) ...@@ -53,7 +51,7 @@ is_kryo_midr(const struct arm64_cpu_capabilities *entry, int scope)
model &= MIDR_IMPLEMENTOR_MASK | (0xf00 << MIDR_PARTNUM_SHIFT) | model &= MIDR_IMPLEMENTOR_MASK | (0xf00 << MIDR_PARTNUM_SHIFT) |
MIDR_ARCHITECTURE_MASK; MIDR_ARCHITECTURE_MASK;
return model == entry->midr_model; return model == entry->midr_range.model;
} }
static bool static bool
...@@ -239,15 +237,11 @@ qcom_enable_link_stack_sanitization(const struct arm64_cpu_capabilities *entry) ...@@ -239,15 +237,11 @@ qcom_enable_link_stack_sanitization(const struct arm64_cpu_capabilities *entry)
#define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \ #define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \
.matches = is_affected_midr_range, \ .matches = is_affected_midr_range, \
.midr_model = model, \ .midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
.midr_range_min = MIDR_CPU_VAR_REV(v_min, r_min), \
.midr_range_max = MIDR_CPU_VAR_REV(v_max, r_max)
#define CAP_MIDR_ALL_VERSIONS(model) \ #define CAP_MIDR_ALL_VERSIONS(model) \
.matches = is_affected_midr_range, \ .matches = is_affected_midr_range, \
.midr_model = model, \ .midr_range = MIDR_ALL_VERSIONS(model)
.midr_range_min = MIDR_CPU_VAR_REV(0, 0), \
.midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
#define MIDR_FIXED(rev, revidr_mask) \ #define MIDR_FIXED(rev, revidr_mask) \
.fixed_revs = (struct arm64_midr_revidr[]){{ (rev), (revidr_mask) }, {}} .fixed_revs = (struct arm64_midr_revidr[]){{ (rev), (revidr_mask) }, {}}
...@@ -390,7 +384,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -390,7 +384,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.desc = "Qualcomm Technologies Kryo erratum 1003", .desc = "Qualcomm Technologies Kryo erratum 1003",
.capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003, .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.midr_model = MIDR_QCOM_KRYO, .midr_range.model = MIDR_QCOM_KRYO,
.matches = is_kryo_midr, .matches = is_kryo_midr,
}, },
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment