Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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 {
	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;
+30 −0
Original line number Original line Diff line number Diff line
@@ -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
+5 −11
Original line number Original line Diff line number Diff line
@@ -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)
	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)


#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[] = {
		.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