aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2021-10-17 17:36:33 +0000
committerOlivier Houchard <cognet@FreeBSD.org>2022-11-18 09:45:31 +0000
commite5c0e6d7810cbfc57b80f123ca48b485bdcd48d1 (patch)
treeb3bded0ef4f4659e7ea58dedc8089694f3419860
parentc74589394de149469510811bfd42a4fe90bbe566 (diff)
downloadsrc-e5c0e6d7810cbfc57b80f123ca48b485bdcd48d1.tar.gz
src-e5c0e6d7810cbfc57b80f123ca48b485bdcd48d1.zip
arm: Fix handling of undefined instruction aborts in THUMB2 mode.
Correctly recognize NEON/SIMD and VFP instructions in THUMB2 mode and pass these to the appropriate handler. Note that it is not necessary to filter all undefined instruction variant or register combinations, this is a job for given handler. Reported by: Robert Clausecker <fuz@fuz.su> PR: 259187 MFC after: 2 weks (cherry picked from commit a670e1c13a522df4fb8c63bb023b88b1d65de797) Signed-off-by: Olivier Houchard <cognet@FreeBSD.org>
-rw-r--r--sys/arm/arm/undefined.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/sys/arm/arm/undefined.c b/sys/arm/arm/undefined.c
index f6fd5bfab266..74ed1c2acc41 100644
--- a/sys/arm/arm/undefined.c
+++ b/sys/arm/arm/undefined.c
@@ -91,13 +91,25 @@ __FBSDID("$FreeBSD$");
#define ARM_COPROC_INSN(insn) (((insn) & (1 << 27)) != 0)
#define ARM_VFP_INSN(insn) ((((insn) & 0xfe000000) == 0xf2000000) || \
- (((insn) & 0xff100000) == 0xf4000000))
+ (((insn) & 0xff100000) == 0xf4000000))
#define ARM_COPROC(insn) (((insn) >> 8) & 0xf)
-#define THUMB_32BIT_INSN(insn) ((insn) >= 0xe800)
+#define THUMB_32BIT_INSN(insn) ((((insn) & 0xe000) == 0xe000) && \
+ (((insn) & 0x1800) != 0))
+/*
+ * Coprocessor, Advanced SIMD, and
+ * Floating-point instructions on page A6-251
+ * OP1 == 01 OR 11
+ * OP2 == 1xxxxxx
+ */
#define THUMB_COPROC_INSN(insn) (((insn) & (3 << 26)) == (3 << 26))
-#define THUMB_COPROC_UNDEFINED(insn) (((insn) & 0x3e << 20) == 0)
-#define THUMB_VFP_INSN(insn) (((insn) & (3 << 24)) == (3 << 24))
+/*
+ * Advanced SIMD element or structure
+ * load/store instructions on page A7-275
+ * OP1 == 11
+ * OP2 == 001xxx0
+*/
+#define THUMB_VFP_INSN(insn) (((insn) & (0x1F1 << 20)) == (0x190 << 20))
#define THUMB_COPROC(insn) (((insn) >> 8) & 0xf)
#define COPROC_VFP 10
@@ -282,18 +294,13 @@ undefinedinstruction(struct trapframe *frame)
fault_instruction <<= 16;
fault_instruction |= *(uint16_t *)(fault_pc + 2);
- /*
- * Is it a Coprocessor, Advanced SIMD, or
- * Floating-point instruction.
- */
- if (THUMB_COPROC_INSN(fault_instruction)) {
- if (THUMB_COPROC_UNDEFINED(fault_instruction)) {
- /* undefined insn */
- } else if (THUMB_VFP_INSN(fault_instruction))
- coprocessor = COPROC_VFP;
- else
- coprocessor =
- THUMB_COPROC(fault_instruction);
+ /* Coprocessor, Advanced SIMD and Floating-point */
+ if (THUMB_COPROC_INSN(fault_instruction))
+ coprocessor = THUMB_COPROC(fault_instruction);
+ else {
+ /* Advanced SIMD load/store */
+ if (THUMB_VFP_INSN(fault_instruction))
+ coprocessor = COPROC_VFP; /* SIMD */
}
}
#else