From 0c06666800965b3e9f0261e11a59dc5af4c23050 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 5 Mar 2018 03:47:18 -0500 Subject: [PATCH] target/arm: Implement SG instruction corner cases The common situation of the SG instruction is that it is executed from S&NSC memory by a CPU in NS state. That case is handled by v7m_handle_execute_nsc(). However the instruction also has defined behaviour in a couple of other cases: * SG instruction in NS memory (behaves as a NOP) * SG in S memory but CPU already secure (clears IT bits and does nothing else) * SG instruction in v8M without Security Extension (NOP) These can be implemented in translate.c. Backports commit 76eff04d166b8fe747adbe82de8b7e060e668ff9 from qemu --- qemu/target/arm/translate.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 0a41e3f2..46c60c59 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -9961,7 +9961,28 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn) * - load/store doubleword, load/store exclusive, ldacq/strel, * table branch. */ - if (insn & 0x01200000) { + if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) && + arm_dc_feature(s, ARM_FEATURE_V8)) { + /* 0b1110_1001_0111_1111_1110_1001_0111_111 + * - SG (v8M only) + * The bulk of the behaviour for this instruction is implemented + * in v7m_handle_execute_nsc(), which deals with the insn when + * it is executed by a CPU in non-secure state from memory + * which is Secure & NonSecure-Callable. + * Here we only need to handle the remaining cases: + * * in NS memory (including the "security extension not + * implemented" case) : NOP + * * in S memory but CPU already secure (clear IT bits) + * We know that the attribute for the memory this insn is + * in must match the current CPU state, because otherwise + * get_phys_addr_pmsav8 would have generated an exception. + */ + if (s->v8m_secure) { + /* Like the IT insn, we don't need to generate any code */ + s->condexec_cond = 0; + s->condexec_mask = 0; + } + } else if (insn & 0x01200000) { /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx * - load/store dual (post-indexed) * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx