Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jun 2025 12:07:40 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b47a6c93e262 - main - arm64: Reduce where we decode msr/mrs instructions
Message-ID:  <202506231207.55NC7eUN059375@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=b47a6c93e262f4245492c947af8a600a4b1fe308

commit b47a6c93e262f4245492c947af8a600a4b1fe308
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-06-23 10:16:03 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-06-23 10:18:19 +0000

    arm64: Reduce where we decode msr/mrs instructions
    
    We only use the mrs_Op* and mrs_CR* functions and MRS_* macros when
    handling userspace executing a msr/msr instruction.
    
    Move the macros to where they are used and expand the functions to
    just use the macros directly.
    
    While here update MRS_Op0_MASK to include bit 20 as this will cause
    the correct op0 value to be calculated for all instructions we decode.
    
    Reviewed by:    Harry Moulton <harry.moulton@arm.com>
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D50214
---
 sys/arm64/arm64/undefined.c   | 49 ++++++++++++++++++++++++++++++++++++-------
 sys/arm64/include/armreg.h    | 19 -----------------
 sys/arm64/include/undefined.h | 20 ------------------
 3 files changed, 42 insertions(+), 46 deletions(-)

diff --git a/sys/arm64/arm64/undefined.c b/sys/arm64/arm64/undefined.c
index a88d47c182cf..19f34fa91702 100644
--- a/sys/arm64/arm64/undefined.c
+++ b/sys/arm64/arm64/undefined.c
@@ -327,16 +327,30 @@ static bool
 undef_sys_insn(struct trapframe *frame, uint32_t insn)
 {
 	uint64_t esr;
-	int op0;
 	bool read;
 
+#define	MRS_MASK			0xfff00000
+#define	MRS_VALUE			0xd5300000
+#define	MSR_REG_VALUE			0xd5100000
+#define	MSR_IMM_VALUE			0xd5000000
+#define	MRS_REGISTER(insn)		((insn) & 0x0000001f)
+#define	 MRS_Op0_SHIFT			19
+#define	 MRS_Op0_MASK			0x00180000
+#define	 MRS_Op1_SHIFT			16
+#define	 MRS_Op1_MASK			0x00070000
+#define	 MRS_CRn_SHIFT			12
+#define	 MRS_CRn_MASK			0x0000f000
+#define	 MRS_CRm_SHIFT			8
+#define	 MRS_CRm_MASK			0x00000f00
+#define	 MRS_Op2_SHIFT			5
+#define	 MRS_Op2_MASK			0x000000e0
+
 	read = false;
 	switch (insn & MRS_MASK) {
 	case MRS_VALUE:
 		read = true;
-		/* FALLTHROUGH */
+		break;
 	case MSR_REG_VALUE:
-		op0 = mrs_Op0(insn);
 		break;
 	case MSR_IMM_VALUE:
 		/*
@@ -346,9 +360,10 @@ undef_sys_insn(struct trapframe *frame, uint32_t insn)
 		 */
 		if (MRS_REGISTER(insn) != 31)
 			return (false);
-		if (mrs_CRn(insn) != 4)
+		if ((insn & MRS_CRn_MASK) >> MRS_CRn_SHIFT != 4)
+			return (false);
+		if ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT != 0)
 			return (false);
-		op0 = 0;
 		break;
 	default:
 		return (false);
@@ -357,12 +372,32 @@ undef_sys_insn(struct trapframe *frame, uint32_t insn)
 	/* Create a fake EXCP_MSR esr value */
 	esr = EXCP_MSR << ESR_ELx_EC_SHIFT;
 	esr |= ESR_ELx_IL;
-	esr |= __ISS_MSR_REG(op0, mrs_Op1(insn), mrs_CRn(insn), mrs_CRm(insn),
-	    mrs_Op2(insn));
+	esr |= __ISS_MSR_REG(
+	    (insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT,
+	    (insn & MRS_Op1_MASK) >> MRS_Op1_SHIFT,
+	    (insn & MRS_CRn_MASK) >> MRS_CRn_SHIFT,
+	    (insn & MRS_CRm_MASK) >> MRS_CRm_SHIFT,
+	    (insn & MRS_Op2_MASK) >> MRS_Op2_SHIFT);
 	esr |= MRS_REGISTER(insn) << ISS_MSR_Rt_SHIFT;
 	if (read)
 		esr |= ISS_MSR_DIR;
 
+#undef MRS_MASK
+#undef MRS_VALUE
+#undef MSR_REG_VALUE
+#undef MSR_IMM_VALUE
+#undef MRS_REGISTER
+#undef MRS_Op0_SHIFT
+#undef MRS_Op0_MASK
+#undef MRS_Op1_SHIFT
+#undef MRS_Op1_MASK
+#undef MRS_CRn_SHIFT
+#undef MRS_CRn_MASK
+#undef MRS_CRm_SHIFT
+#undef MRS_CRm_MASK
+#undef MRS_Op2_SHIFT
+#undef MRS_Op2_MASK
+
 	return (undef_sys(esr, frame));
 }
 
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index a44cc4343dee..cd770386f852 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -36,25 +36,6 @@
 
 #define	INSN_SIZE		4
 
-#define	MRS_MASK			0xfff00000
-#define	MRS_VALUE			0xd5300000
-#define	MSR_REG_VALUE			0xd5100000
-#define	MSR_IMM_VALUE			0xd5000000
-#define	MRS_SPECIAL(insn)		((insn) & 0x000fffe0)
-#define	MRS_REGISTER(insn)		((insn) & 0x0000001f)
-#define	 MRS_Op0_SHIFT			19
-#define	 MRS_Op0_MASK			0x00080000
-#define	 MRS_Op1_SHIFT			16
-#define	 MRS_Op1_MASK			0x00070000
-#define	 MRS_CRn_SHIFT			12
-#define	 MRS_CRn_MASK			0x0000f000
-#define	 MRS_CRm_SHIFT			8
-#define	 MRS_CRm_MASK			0x00000f00
-#define	 MRS_Op2_SHIFT			5
-#define	 MRS_Op2_MASK			0x000000e0
-#define	 MRS_Rt_SHIFT			0
-#define	 MRS_Rt_MASK			0x0000001f
-
 #define	__MRS_REG_ALT_NAME(op0, op1, crn, crm, op2)			\
     S##op0##_##op1##_C##crn##_C##crm##_##op2
 #define	_MRS_REG_ALT_NAME(op0, op1, crn, crm, op2)			\
diff --git a/sys/arm64/include/undefined.h b/sys/arm64/include/undefined.h
index c23b020e960f..71b2eed22a84 100644
--- a/sys/arm64/include/undefined.h
+++ b/sys/arm64/include/undefined.h
@@ -37,26 +37,6 @@ typedef int (*undef_handler_t)(vm_offset_t, uint32_t, struct trapframe *,
     uint32_t);
 typedef bool (*undef_sys_handler_t)(uint64_t, struct trapframe *);
 
-static inline int
-mrs_Op0(uint32_t insn)
-{
-
-	/* op0 is encoded without the top bit in a mrs instruction */
-	return (2 | ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT));
-}
-
-#define	MRS_GET(op)						\
-static inline int						\
-mrs_##op(uint32_t insn)						\
-{								\
-								\
-	return ((insn & MRS_##op##_MASK) >> MRS_##op##_SHIFT);	\
-}
-MRS_GET(Op1)
-MRS_GET(CRn)
-MRS_GET(CRm)
-MRS_GET(Op2)
-
 void undef_init(void);
 void install_sys_handler(undef_sys_handler_t);
 void *install_undef_handler(undef_handler_t);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506231207.55NC7eUN059375>