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

Commit 4dcafb42 authored by Suzuki K. Poulose's avatar Suzuki K. Poulose Committed by Kyle Yan
Browse files

arm64: Add assembly helpers for MIDR range check



Add a helper to check the MIDR of the running CPU against a given
MODEL and a range of revision and variants (just like we do in
is_affected_midr_range()). This will be useful for early checks
for MIDR to detect CPU errata.

Change-Id: I8cee3c92d2903d401d0b4235312904b706b38f7f
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Patch-mainline: linux-arm-kernel @ 01/16/2018, 10:23
[kyan@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: default avatarKyle Yan <kyan@codeaurora.org>
parent eb8323cc
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <asm/asm-offsets.h>
#include <asm/cpufeature.h>
#include <asm/cputype.h>
#include <asm/page.h>
#include <asm/pgtable-hwdef.h>
#include <asm/ptrace.h>
@@ -452,4 +453,43 @@ alternative_endif
	mrs	\rd, sp_el0
	.endm

/*
 * Check the MIDR_EL1 of the current CPU for a given model and a range of
 * variant/revision. See asm/cputype.h for the macros used below.
 *
 *	model:		MIDR_CPU_MODEL of CPU
 *	rv_min:		Minimum of MIDR_CPU_VAR_REV()
 *	rv_max:		Maximum of MIDR_CPU_VAR_REV()
 *	res:		Result register.
 *	tmp1, tmp2, tmp3: Temporary registers
 *
 * Corrupts: res, tmp1, tmp2, tmp3
 * Returns:  0, if the CPU id doesn't match. Non-zero otherwise
 */
	.macro	cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
	mrs		\res, midr_el1
	mov_q		\tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
	mov_q		\tmp2, MIDR_CPU_MODEL_MASK
	and		\tmp3, \res, \tmp2	// Extract model
	and		\tmp1, \res, \tmp1	// rev & variant
	mov_q		\tmp2, \model
	cmp		\tmp3, \tmp2
	cset		\res, eq
	cbz		\res, .Ldone\@		// Model matches ?

	.if (\rv_min != 0)			// Skip min check if rv_min == 0
	mov_q		\tmp3, \rv_min
	cmp		\tmp1, \tmp3
	cset		\res, ge
	.endif					// \rv_min != 0
	/* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
	.if ((\rv_min != \rv_max) || \rv_min == 0)
	mov_q		\tmp2, \rv_max
	cmp		\tmp1, \tmp2
	cset		\tmp2, le
	and		\res, \res, \tmp2
	.endif
.Ldone\@:
	.endm

#endif	/* __ASM_ASSEMBLER_H */