target-arm: Add write_type argument to cpsr_write()

Add an argument to cpsr_write() to indicate what kind of CPSR
write is being requested, since the exact behaviour should
differ for the different cases.

Backports commit 50866ba5a2cfe922aaf3edb79f6eac5b0653477a from qemu
This commit is contained in:
Peter Maydell 2018-02-20 22:10:52 -05:00 committed by Lioncash
parent 6ae2357be6
commit 611d4dad4b
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
5 changed files with 19 additions and 9 deletions

View file

@ -724,8 +724,17 @@ static inline void pstate_write(CPUARMState *env, uint32_t val)
/* Return the current CPSR value. */ /* Return the current CPSR value. */
uint32_t cpsr_read(CPUARMState *env); uint32_t cpsr_read(CPUARMState *env);
typedef enum CPSRWriteType {
CPSRWriteByInstr = 0, /* from guest MSR or CPS */
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
CPSRWriteByGDBStub = 3, /* from the GDB stub */
} CPSRWriteType;
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/ /* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type);
/* Return the current xPSR value. */ /* Return the current xPSR value. */
static inline uint32_t xpsr_read(CPUARMState *env) static inline uint32_t xpsr_read(CPUARMState *env)

View file

@ -4536,7 +4536,8 @@ uint32_t cpsr_read(CPUARMState *env)
| (env->GE << 16) | (env->daif & CPSR_AIF); | (env->GE << 16) | (env->daif & CPSR_AIF);
} }
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type)
{ {
uint32_t changed_daif; uint32_t changed_daif;

View file

@ -422,13 +422,13 @@ uint32_t HELPER(cpsr_read)(CPUARMState *env)
void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
{ {
cpsr_write(env, val, mask); cpsr_write(env, val, mask, CPSRWriteByInstr);
} }
/* Write the CPSR for a 32-bit exception return */ /* Write the CPSR for a 32-bit exception return */
void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val) void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
{ {
cpsr_write(env, val, CPSR_ERET_MASK); cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
} }
/* Access to user mode registers from privileged modes. */ /* Access to user mode registers from privileged modes. */
@ -780,7 +780,7 @@ void HELPER(exception_return)(CPUARMState *env)
if (!return_to_aa64) { if (!return_to_aa64) {
env->aarch64 = 0; env->aarch64 = 0;
env->uncached_cpsr = spsr & CPSR_M; env->uncached_cpsr = spsr & CPSR_M;
cpsr_write(env, spsr, ~0); cpsr_write(env, spsr, ~0, CPSRWriteRaw);
if (!arm_singlestep_active(env)) { if (!arm_singlestep_active(env)) {
env->uncached_cpsr &= ~PSTATE_SS; env->uncached_cpsr &= ~PSTATE_SS;
} }

View file

@ -181,7 +181,7 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals,
ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value; ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value;
break; break;
case UC_ARM64_REG_NZCV: case UC_ARM64_REG_NZCV:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *) value, CPSR_NZCV); cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *) value, CPSR_NZCV, CPSRWriteRaw);
break; break;
case UC_ARM64_REG_PSTATE: case UC_ARM64_REG_PSTATE:
pstate_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value); pstate_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value);

View file

@ -112,10 +112,10 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i
else { else {
switch(regid) { switch(regid) {
case UC_ARM_REG_APSR: case UC_ARM_REG_APSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV); cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteRaw);
break; break;
case UC_ARM_REG_CPSR: case UC_ARM_REG_CPSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, ~0); cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, ~0, CPSRWriteRaw);
break; break;
//case UC_ARM_REG_SP: //case UC_ARM_REG_SP:
case UC_ARM_REG_R13: case UC_ARM_REG_R13: