target-arm queue:
* fix MSR/MRS decoding for M profile CPUs -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJYz9DGAAoJEDwlJe0UNgzemKQQAKX4NK+hhBfMjgH7Q8yJED8k 6OaCZRG7PKwDrxQ0yzBUDbDqAEHRG8qs0V6rFv9e7tfx0Sfwq52bvnBL5SiPBz/c suqLDYRCByUMCyRz7AfWAWfnxlmHEXee7sRUB9W0/S92kD1RaAI+bh6Po9A6Yfyw O1o5SA+oqCSiPajbb1ef3PuKWRnGvvX40dwsB02dr+dvqukwd4qINtuns/9ZCBdK KyXA+BPNJ92VjNl3rCcAuP0Xrh3n7RZGMS+uTY9CAmZgLftMlGrH8LIAbI+81x8Q iG06T9R6bF0wTMZ9VeLhupRI2WOA5sZisQj+qD3WJzjcfQXzhNbHoAmZHkdCtwtg KlFr8IADaTXGbYxFBKIIqRPQZYFsphqPuqEkx/WF1kj2cWAT1G+7E58/hknreyjW R07Nmz+IsM8RrrFVROy7cnygIYFKt9ppzuG0z4SHhg4SyIFlhgD0gdgAtjKi12a5 QwHfVf2iC+PPM266Ei4QwpnN48eUKcXRrMjwn9Hc83PIQDWyu6jPey8V8/C4peSy Bd5BSRe2VkzorRzWOgVPnh/6UYilcKC20uRoAty82D3iU/vxopd/eBX6SsMdesdm 37rjgZ67li6W6Uh13USXpudmwidX5W6Qva1V9w3SbeG6hiOVJXs7sHEHGhNQE7Ng yg0e/BTC9V8SbZIG0MUB =Qxlq -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170320' into staging target-arm queue: * fix MSR/MRS decoding for M profile CPUs # gpg: Signature made Mon 20 Mar 2017 12:53:26 GMT # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170320: arm: Fix APSR writes via M profile MSR arm: Enforce should-be-1 bits in MRS decoding arm: Don't decode MRS(banked) or MSR(banked) for M profile arm: HVC and SMC encodings don't exist for M profile Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
32f70d7659
|
@ -8548,8 +8548,18 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
|
|||
}
|
||||
}
|
||||
|
||||
void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
|
||||
void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
|
||||
{
|
||||
/* We're passed bits [11..0] of the instruction; extract
|
||||
* SYSm and the mask bits.
|
||||
* Invalid combinations of SYSm and mask are UNPREDICTABLE;
|
||||
* we choose to treat them as if the mask bits were valid.
|
||||
* NB that the pseudocode 'mask' variable is bits [11..10],
|
||||
* whereas ours is [11..8].
|
||||
*/
|
||||
uint32_t mask = extract32(maskreg, 8, 4);
|
||||
uint32_t reg = extract32(maskreg, 0, 8);
|
||||
|
||||
if (arm_current_el(env) == 0 && reg > 7) {
|
||||
/* only xPSR sub-fields may be written by unprivileged */
|
||||
return;
|
||||
|
@ -8558,8 +8568,16 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
|
|||
switch (reg) {
|
||||
case 0 ... 7: /* xPSR sub-fields */
|
||||
/* only APSR is actually writable */
|
||||
if (reg & 4) {
|
||||
xpsr_write(env, val, 0xf8000000); /* APSR */
|
||||
if (!(reg & 4)) {
|
||||
uint32_t apsrmask = 0;
|
||||
|
||||
if (mask & 8) {
|
||||
apsrmask |= 0xf8000000; /* APSR NZCVQ */
|
||||
}
|
||||
if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
|
||||
apsrmask |= 0x000f0000; /* APSR GE[3:0] */
|
||||
}
|
||||
xpsr_write(env, val, apsrmask);
|
||||
}
|
||||
break;
|
||||
case 8: /* MSP */
|
||||
|
|
|
@ -10377,6 +10377,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
goto illegal_op;
|
||||
|
||||
if (insn & (1 << 26)) {
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
if (!(insn & (1 << 20))) {
|
||||
/* Hypervisor call (v7) */
|
||||
int imm16 = extract32(insn, 16, 4) << 12
|
||||
|
@ -10400,7 +10403,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
case 0: /* msr cpsr. */
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
tmp = load_reg(s, rn);
|
||||
addr = tcg_const_i32(insn & 0xff);
|
||||
/* the constant is the mask and SYSm fields */
|
||||
addr = tcg_const_i32(insn & 0xfff);
|
||||
gen_helper_v7m_msr(cpu_env, addr, tmp);
|
||||
tcg_temp_free_i32(addr);
|
||||
tcg_temp_free_i32(tmp);
|
||||
|
@ -10497,7 +10501,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
gen_exception_return(s, tmp);
|
||||
break;
|
||||
case 6: /* MRS */
|
||||
if (extract32(insn, 5, 1)) {
|
||||
if (extract32(insn, 5, 1) &&
|
||||
!arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/* MRS (banked) */
|
||||
int sysm = extract32(insn, 16, 4) |
|
||||
(extract32(insn, 4, 1) << 4);
|
||||
|
@ -10506,6 +10511,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
break;
|
||||
}
|
||||
|
||||
if (extract32(insn, 16, 4) != 0xf) {
|
||||
goto illegal_op;
|
||||
}
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_M) &&
|
||||
extract32(insn, 0, 8) != 0) {
|
||||
goto illegal_op;
|
||||
}
|
||||
|
||||
/* mrs cpsr */
|
||||
tmp = tcg_temp_new_i32();
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
|
@ -10518,7 +10531,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
case 7: /* MRS */
|
||||
if (extract32(insn, 5, 1)) {
|
||||
if (extract32(insn, 5, 1) &&
|
||||
!arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/* MRS (banked) */
|
||||
int sysm = extract32(insn, 16, 4) |
|
||||
(extract32(insn, 4, 1) << 4);
|
||||
|
@ -10532,6 +10546,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
|
||||
if (extract32(insn, 16, 4) != 0xf ||
|
||||
extract32(insn, 0, 8) != 0) {
|
||||
goto illegal_op;
|
||||
}
|
||||
|
||||
tmp = load_cpu_field(spsr);
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue