On 11/4/21 11:19 PM, Warner Losh wrote:
> +/* Compare to arm/arm/exec_machdep.c set_mcontext() */
> +abi_long set_mcontext(CPUARMState *env, target_mcontext_t *mcp, int srflag)
> +{
> + int err = 0;
> + const uint32_t *gr = mcp->__gregs;
> + uint32_t cpsr, ccpsr = cpsr_read(env);
> + uint32_t fpscr, mask;
> +
> + cpsr = tswap32(gr[TARGET_REG_CPSR]);
> + /*
> + * Only allow certain bits to change, reject attempted changes to non-user
> + * bits. In addition, make sure we're headed for user mode and none of the
> + * interrupt bits are set.
> + */
> + if ((ccpsr & ~CPSR_USER) != (cpsr & ~CPSR_USER)) {
> + return -TARGET_EINVAL;
> + }
> + if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR ||
> + (cpsr & (CPSR_I | CPSR_F)) != 0) {
> + return -TARGET_EINVAL;
> + }
> + mask = cpsr & CPSR_T ? 0x1 : 0x3;
Should add a sentence or so here, pointing to the exception return instruction used by the
freebsd kernel, which does this masking.
Will do.
> + /*
> + * Make sure T mode matches the PC's notion of thumb mode, although
> + * FreeBSD lets the processor sort this out, so we may need remove
> + * this check, or generate a signal...
> + */
> + if (!!(tswap32(gr[TARGET_REG_PC]) & 1) != !!(cpsr & CPSR_T)) {
> + return -TARGET_EINVAL;
> + }
Remove this.
Gone.
> + env->regs[15] = tswap32(gr[TARGET_REG_PC] & mask);
You wanted ~mask.
Doh! Fixed.
Warner
r~