From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38452) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X72ya-0007B6-9j for qemu-devel@nongnu.org; Tue, 15 Jul 2014 09:41:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X72yY-0003QC-95 for qemu-devel@nongnu.org; Tue, 15 Jul 2014 09:41:00 -0400 Received: from [2001:4b98:dc0:45:216:3eff:fe3d:166f] (port=52305 helo=afflict.kos.to) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X72yX-0003Pz-Uc for qemu-devel@nongnu.org; Tue, 15 Jul 2014 09:40:58 -0400 Date: Tue, 15 Jul 2014 16:40:57 +0300 From: Riku Voipio Message-ID: <20140715134057.GF607@afflict.kos.to> References: <1405007407-23549-1-git-send-email-alex.bennee@linaro.org> <1405007407-23549-5-git-send-email-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <1405007407-23549-5-git-send-email-alex.bennee@linaro.org> Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v2 04/10] target-arm: replace cpsr/xpsr/pstate_read calls List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex =?utf-8?Q?Benn=C3=A9e?= Cc: Peter Maydell , qemu-devel@nongnu.org On Thu, Jul 10, 2014 at 04:50:01PM +0100, Alex Benn=C3=A9e wrote: > Use the unified save_state_to_spsr. I've also updated the interrupt > helpers to restore via the restore_state_from_spsr() functions. In the > aarch32 case this also needs to call switch_mode() to do the appropriat= e > fiddling. For the linux-user part, Acked-by: Riku Voipio > Signed-off-by: Alex Benn=C3=A9e >=20 > -- >=20 > v2 > - include xpsr_read conversions > - checkpatch fixes >=20 > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 60777fe..577e1d3 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -321,7 +321,7 @@ static void elf_core_copy_regs(target_elf_gregset_t= *regs, const CPUARMState *en > (*regs)[14] =3D tswapreg(env->regs[14]); > (*regs)[15] =3D tswapreg(env->regs[15]); > =20 > - (*regs)[16] =3D tswapreg(cpsr_read((CPUARMState *)env)); > + (*regs)[16] =3D tswapreg(save_state_to_spsr((CPUARMState *)env)); > (*regs)[17] =3D tswapreg(env->regs[0]); /* XXX */ > } > =20 > @@ -509,7 +509,7 @@ static void elf_core_copy_regs(target_elf_gregset_t= *regs, > (*regs)[i] =3D tswapreg(env->xregs[i]); > } > (*regs)[32] =3D tswapreg(env->pc); > - (*regs)[33] =3D tswapreg(pstate_read((CPUARMState *)env)); > + (*regs)[33] =3D tswapreg(save_state_to_spsr((CPUARMState *)env)); > } > =20 > #define USE_ELF_CORE_DUMP > diff --git a/linux-user/main.c b/linux-user/main.c > index b453a39..8848e15 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -546,7 +546,7 @@ do_kernel_trap(CPUARMState *env) > operations. However things like ldrex/strex are much harde= r so > there's not much point trying. */ > start_exclusive(); > - cpsr =3D cpsr_read(env); > + cpsr =3D save_state_to_spsr(env); > addr =3D env->regs[2]; > /* FIXME: This should SEGV if the access fails. */ > if (get_user_u32(val, addr)) > diff --git a/linux-user/signal.c b/linux-user/signal.c > index 86fae3d..9c6727b 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -1224,7 +1224,7 @@ static int target_setup_sigframe(struct target_rt= _sigframe *sf, > } > __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp); > __put_user(env->pc, &sf->uc.tuc_mcontext.pc); > - __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate); > + __put_user(save_state_to_spsr(env), &sf->uc.tuc_mcontext.pstate); > =20 > __put_user(env->exception.vaddress, &sf->uc.tuc_mcontext.fault_add= ress); > =20 > @@ -1572,7 +1572,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*= struct _fpstate *fpstate,*/ > __put_user(env->regs[14], &sc->arm_lr); > __put_user(env->regs[15], &sc->arm_pc); > #ifdef TARGET_CONFIG_CPU_32 > - __put_user(cpsr_read(env), &sc->arm_cpsr); > + __put_user(save_state_to_spsr(env), &sc->arm_cpsr); > #endif > =20 > __put_user(/* current->thread.trap_no */ 0, &sc->trap_no); > @@ -1604,7 +1604,7 @@ setup_return(CPUARMState *env, struct target_siga= ction *ka, > abi_ulong handler =3D ka->_sa_handler; > abi_ulong retcode; > int thumb =3D handler & 1; > - uint32_t cpsr =3D cpsr_read(env); > + uint32_t cpsr =3D save_state_to_spsr(env); > =20 > cpsr &=3D ~CPSR_IT; > if (thumb) { > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index fe4d4f3..3f23167 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -480,30 +480,8 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr = address, int rw, > #define PSTATE_MODE_EL1t 4 > #define PSTATE_MODE_EL0t 0 > =20 > -/* ARMv8 ARM D1.7 Process state, PSTATE > - * > - * 31 28 27 24 23 22 21 20 22 21 20 19 16 15 8 7 5 4 = 0 > - * +------+------+-------+-----+--------+---+------+------+-----+-----= -+ > - * | NZCV | DAIF | SS IL | EL | nRW SP | Q | GE | IT | JTE | Mode= | > - * +------+------+-------+-----+--------+---+------+------+-----+-----= -+ > - * > - * The PSTATE is an abstraction of a number of Return the current > - * PSTATE value. This is only valid for A64 hardware although can be > - * read when in AArch32 mode. > - */ > -static inline uint32_t pstate_read(CPUARMState *env) > -{ > - int ZF; > - > - g_assert(is_a64(env)); > - > - ZF =3D (env->ZF =3D=3D 0); > - return (env->NF & 0x80000000) | (ZF << 30) > - | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) > - | env->pstate | env->daif; > -} > - > -/* Update the current PSTATE value. This doesn't include nRW which is = */ > +/* Update the current PSTATE value. This doesn't include nRW which > + * indicates if we are in 64 or 32 bit mode */ > static inline void pstate_write(CPUARMState *env, uint32_t val) > { > g_assert(is_a64(env)); > @@ -520,26 +498,10 @@ static inline void pstate_write(CPUARMState *env,= uint32_t val) > * > * Unlike the above PSTATE implementation these functions will attempt > * to switch processor mode when the M[4:0] bits are set. > - */ > -uint32_t cpsr_read(CPUARMState *env); > -/* Set the CPSR. Note that some bits of mask must be all-set or all-c= lear. */ > + * > + * Note that some bits of mask must be all-set or all-clear. */ > void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); > =20 > -/* ARMv7-M ARM B1.4.2, special purpose program status register xPSR */ > -static inline uint32_t xpsr_read(CPUARMState *env) > -{ > - int ZF; > - > - g_assert(!is_a64(env)); > - > - ZF =3D (env->ZF =3D=3D 0); > - return (env->NF & 0x80000000) | (ZF << 30) > - | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF <= < 27) > - | (env->thumb << 24) | ((env->condexec_bits & 3) << 25) > - | ((env->condexec_bits & 0xfc) << 8) > - | env->v7m.exception; > -} > - > /* Set the xPSR. Note that some bits of mask must be all-set or all-c= lear. */ > static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t= mask) > { > diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c > index 1c34396..ec25f30 100644 > --- a/target-arm/gdbstub.c > +++ b/target-arm/gdbstub.c > @@ -53,7 +53,7 @@ int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *= mem_buf, int n) > return gdb_get_reg32(mem_buf, 0); > case 25: > /* CPSR */ > - return gdb_get_reg32(mem_buf, cpsr_read(env)); > + return gdb_get_reg32(mem_buf, save_state_to_spsr(env)); > } > /* Unknown register. */ > return 0; > diff --git a/target-arm/gdbstub64.c b/target-arm/gdbstub64.c > index 8f3b8d1..76d1b91 100644 > --- a/target-arm/gdbstub64.c > +++ b/target-arm/gdbstub64.c > @@ -35,7 +35,7 @@ int aarch64_cpu_gdb_read_register(CPUState *cs, uint8= _t *mem_buf, int n) > case 32: > return gdb_get_reg64(mem_buf, env->pc); > case 33: > - return gdb_get_reg32(mem_buf, pstate_read(env)); > + return gdb_get_reg32(mem_buf, save_state_to_spsr(env)); > } > /* Unknown register. */ > return 0; > @@ -62,7 +62,7 @@ int aarch64_cpu_gdb_write_register(CPUState *cs, uint= 8_t *mem_buf, int n) > env->pc =3D tmp; > return 8; > case 33: > - /* CPSR */ > + /* SPSR */ > pstate_write(env, tmp); > return 4; > } > diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c > index ec1fef5..03cd64f 100644 > --- a/target-arm/helper-a64.c > +++ b/target-arm/helper-a64.c > @@ -445,6 +445,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > CPUARMState *env =3D &cpu->env; > target_ulong addr =3D env->cp15.vbar_el[1]; > int i; > + uint32_t spsr =3D save_state_to_spsr(env); > =20 > if (arm_current_pl(env) =3D=3D 0) { > if (env->aarch64) { > @@ -452,7 +453,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > } else { > addr +=3D 0x600; > } > - } else if (pstate_read(env) & PSTATE_SP) { > + } else if (spsr & PSTATE_SP) { > addr +=3D 0x200; > } > =20 > @@ -488,12 +489,12 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > } > =20 > if (is_a64(env)) { > - env->banked_spsr[aarch64_banked_spsr_index(1)] =3D pstate_read= (env); > + env->banked_spsr[aarch64_banked_spsr_index(1)] =3D spsr; > env->sp_el[arm_current_pl(env)] =3D env->xregs[31]; > env->xregs[31] =3D env->sp_el[1]; > env->elr_el[1] =3D env->pc; > } else { > - env->banked_spsr[0] =3D cpsr_read(env); > + env->banked_spsr[0] =3D spsr; > if (!env->thumb) { > env->cp15.esr_el[1] |=3D 1 << 25; > } > @@ -506,6 +507,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > env->condexec_bits =3D 0; > } > =20 > + // TODO: restore_state_from_spsr() > env->aarch64 =3D 1; > pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h); > =20 > diff --git a/target-arm/helper.c b/target-arm/helper.c > index d343856..030bcdd 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -2990,17 +2990,6 @@ static int bad_mode_switch(CPUARMState *env, int= mode) > } > } > =20 > -uint32_t cpsr_read(CPUARMState *env) > -{ > - int ZF; > - ZF =3D (env->ZF =3D=3D 0); > - return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) | > - (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << = 27) > - | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) > - | ((env->condexec_bits & 0xfc) << 8) > - | (env->GE << 16) | (env->daif & CPSR_AIF); > -} > - > void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) > { > if (mask & CPSR_NZCV) { > @@ -3278,7 +3267,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) > { > ARMCPU *cpu =3D ARM_CPU(cs); > CPUARMState *env =3D &cpu->env; > - uint32_t xpsr =3D xpsr_read(env); > + uint32_t xpsr =3D save_state_to_spsr(env); > uint32_t lr; > uint32_t addr; > =20 > @@ -3479,7 +3468,8 @@ void arm_cpu_do_interrupt(CPUState *cs) > addr +=3D env->cp15.vbar_el[1]; > } > switch_mode (env, new_mode); > - env->spsr =3D cpsr_read(env); > + env->spsr =3D save_state_to_spsr(env); > + /* TODO: restore_state_from_spsr */ > /* Clear IT bits. */ > env->condexec_bits =3D 0; > /* Switch to the new mode, and to the correct instruction set. */ > @@ -4212,19 +4202,19 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint= 32_t reg) > =20 > switch (reg) { > case 0: /* APSR */ > - return xpsr_read(env) & 0xf8000000; > + return save_state_to_spsr(env) & 0xf8000000; > case 1: /* IAPSR */ > - return xpsr_read(env) & 0xf80001ff; > + return save_state_to_spsr(env) & 0xf80001ff; > case 2: /* EAPSR */ > - return xpsr_read(env) & 0xff00fc00; > + return save_state_to_spsr(env) & 0xff00fc00; > case 3: /* xPSR */ > - return xpsr_read(env) & 0xff00fdff; > + return save_state_to_spsr(env) & 0xff00fdff; > case 5: /* IPSR */ > - return xpsr_read(env) & 0x000001ff; > + return save_state_to_spsr(env) & 0x000001ff; > case 6: /* EPSR */ > - return xpsr_read(env) & 0x0700fc00; > + return save_state_to_spsr(env) & 0x0700fc00; > case 7: /* IEPSR */ > - return xpsr_read(env) & 0x0700edff; > + return save_state_to_spsr(env) & 0x0700edff; > case 8: /* MSP */ > return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]= ; > case 9: /* PSP */ > diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c > index 5ec4eb1..789f52f 100644 > --- a/target-arm/kvm32.c > +++ b/target-arm/kvm32.c > @@ -384,7 +384,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) > } > =20 > /* Special cases which aren't a single CPUARMState field */ > - cpsr =3D cpsr_read(env); > + cpsr =3D save_state_to_spsr(env); > r.id =3D KVM_REG_ARM | KVM_REG_SIZE_U32 | > KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr); > r.addr =3D (uintptr_t)(&cpsr); > diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c > index 5d217ca..eaf6ff8 100644 > --- a/target-arm/kvm64.c > +++ b/target-arm/kvm64.c > @@ -153,7 +153,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) > } > =20 > /* Note that KVM thinks pstate is 64 bit but we use a uint32_t */ > - val =3D pstate_read(env); > + val =3D save_state_to_spsr(env); > reg.id =3D AARCH64_CORE_REG(regs.pstate); > reg.addr =3D (uintptr_t) &val; > ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); > diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c > index 9c1ef52..052a4bd 100644 > --- a/target-arm/op_helper.c > +++ b/target-arm/op_helper.c > @@ -258,7 +258,7 @@ void HELPER(exception_with_syndrome)(CPUARMState *e= nv, uint32_t excp, > =20 > uint32_t HELPER(cpsr_read)(CPUARMState *env) > { > - return cpsr_read(env) & ~CPSR_EXEC; > + return save_state_to_spsr(env) & ~CPSR_EXEC; > } > =20 > void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) > @@ -386,10 +386,9 @@ void HELPER(exception_return)(CPUARMState *env) > =20 > if (spsr & PSTATE_nRW) { > /* TODO: We currently assume EL1/2/3 are running in AArch64. = */ > - env->aarch64 =3D 0; > new_el =3D 0; > - env->uncached_cpsr =3D 0x10; > - cpsr_write(env, spsr, ~0); > + switch_mode(env, spsr & CPSR_M); > + > for (i =3D 0; i < 15; i++) { > env->regs[i] =3D env->xregs[i]; > } > @@ -412,11 +411,11 @@ void HELPER(exception_return)(CPUARMState *env) > /* Return to EL0 with M[0] bit set */ > goto illegal_return; > } > - env->aarch64 =3D 1; > - pstate_write(env, spsr); > env->xregs[31] =3D env->sp_el[new_el]; > env->pc =3D env->elr_el[cur_el]; > } > + /* This will set env->aarch64 as appropriate */ > + restore_state_from_spsr(env, spsr); > =20 > return; > =20 > @@ -431,8 +430,8 @@ illegal_return: > env->pstate |=3D PSTATE_IL; > env->pc =3D env->elr_el[cur_el]; > spsr &=3D PSTATE_NZCV | PSTATE_DAIF; > - spsr |=3D pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF); > - pstate_write(env, spsr); > + spsr |=3D save_state_to_spsr(env) & ~(PSTATE_NZCV | PSTATE_DAIF); > + restore_state_from_spsr(env, spsr); > } > =20 > /* ??? Flag setting arithmetic is awkward because we need to do compar= isons. > diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c > index 33b5025..3b4a676 100644 > --- a/target-arm/translate-a64.c > +++ b/target-arm/translate-a64.c > @@ -126,7 +126,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f, > { > ARMCPU *cpu =3D ARM_CPU(cs); > CPUARMState *env =3D &cpu->env; > - uint32_t psr =3D pstate_read(env); > + uint32_t psr =3D save_state_to_spsr(env); > int i; > =20 > cpu_fprintf(f, "PC=3D%016"PRIx64" SP=3D%016"PRIx64"\n", > diff --git a/target-arm/translate.c b/target-arm/translate.c > index cf4e767..8427396 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -11192,7 +11192,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, = fprintf_function cpu_fprintf, > else > cpu_fprintf(f, " "); > } > - psr =3D cpsr_read(env); > + psr =3D save_state_to_spsr(env); > cpu_fprintf(f, "PSR=3D%08x %c%c%c%c %c %s%d\n", > psr, > psr & (1 << 31) ? 'N' : '-', > --=20 > 2.0.1 >=20