git: b47a6c93e262 - main - arm64: Reduce where we decode msr/mrs instructions
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 23 Jun 2025 12:07:40 UTC
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);