Skip to content

Commit

Permalink
Fix #1520
Browse files Browse the repository at this point in the history
  • Loading branch information
wtdcode committed Jan 4, 2022
1 parent 73149f3 commit 47097b5
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 6 deletions.
1 change: 1 addition & 0 deletions qemu/target/arm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@ typedef enum CPSRWriteType {
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
CPSRWriteByGDBStub = 3, /* from the GDB stub */
CPSRWriteByUnicorn = 4 /* from uc_reg_write */
} CPSRWriteType;

/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
Expand Down
9 changes: 6 additions & 3 deletions qemu/target/arm/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -7983,9 +7983,12 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
* to switch mode. (Those are caught by translate.c for writes
* triggered by guest instructions.)
*/
// mask &= ~CPSR_M;
// Unicorn: No, it can also be uc_reg_write
switch_mode(env, val & CPSR_M);
mask &= ~CPSR_M;

// Unicorn: No, it can also be uc_reg_write, let user switch registers banks.
if (write_type == CPSRWriteByUnicorn) {
switch_mode(env, val & CPSR_M);
}
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
* v7, and has defined behaviour in v8:
Expand Down
6 changes: 3 additions & 3 deletions qemu/target/arm/unicorn_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,17 +251,17 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
case UC_ARM_REG_APSR:
if (!arm_feature(env, ARM_FEATURE_M)) {
cpsr_write(env, *(uint32_t *)value,
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByInstr);
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn);
} else {
// Same with UC_ARM_REG_APSR_NZCVQ
v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value);
}
break;
case UC_ARM_REG_APSR_NZCV:
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByInstr);
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn);
break;
case UC_ARM_REG_CPSR:
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByInstr);
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn);
break;
case UC_ARM_REG_SPSR:
env->spsr = *(uint32_t *)value;
Expand Down

0 comments on commit 47097b5

Please sign in to comment.