From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ao60p-0002Je-JS for qemu-devel@nongnu.org; Thu, 07 Apr 2016 05:14:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ao60l-00070d-Fn for qemu-devel@nongnu.org; Thu, 07 Apr 2016 05:14:03 -0400 References: <1459822643-4770-1-git-send-email-david@gibson.dropbear.id.au> <1459822643-4770-2-git-send-email-david@gibson.dropbear.id.au> From: Laurent Vivier Message-ID: <570624CF.6020703@redhat.com> Date: Thu, 7 Apr 2016 11:13:51 +0200 MIME-Version: 1.0 In-Reply-To: <1459822643-4770-2-git-send-email-david@gibson.dropbear.id.au> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [Qemu-ppc] [PULL 1/3] ppc: Rework POWER7 & POWER8 exception model List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: David Gibson , peter.maydell@linaro.org Cc: pbonzini@redhat.com, clg@fr.ibm.com, qemu-ppc@nongnu.org, qemu-devel@nongnu.org, mdroth@linux.vnet.ibm.com On 05/04/2016 04:17, David Gibson wrote: > From: C=C3=A9dric Le Goater >=20 > From: Benjamin Herrenschmidt >=20 > This patch fixes the current AIL implementation for POWER8. The > interrupt vector address can be calculated directly from LPCR when the > exception is handled. The excp_prefix update becomes useless and we > can cleanup the H_SET_MODE hcall. I know it's a little bit late to comment this patch but: what about the initialization of the NIP in ppc_cpu_reset()? env->nip =3D env->hreset_vector | env->excp_prefix; on POWER8 "env->excp_prefix" is always 0, but LPCR can have an AIL define= d? Laurent >=20 > Signed-off-by: Benjamin Herrenschmidt > [clg: Removed LPES0/1 handling for HV vs. !HV > Fixed LPCR_ILE case for POWERPC_EXCP_POWER8 ] > Signed-off-by: C=C3=A9dric Le Goater > [dwg: This was written as a cleanup, but it also fixes a real bug > where setting an alternative interrupt location would not be > correctly migrated] > Signed-off-by: David Gibson > --- > hw/ppc/spapr_hcall.c | 16 +-------------- > include/hw/ppc/spapr.h | 5 ----- > target-ppc/cpu.h | 10 +++++++++ > target-ppc/excp_helper.c | 49 +++++++++++++++++++++++++++++++++++++= ++++++-- > target-ppc/translate_init.c | 2 +- > 5 files changed, 59 insertions(+), 23 deletions(-) >=20 > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index 2dcb676..8f40602 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -824,7 +824,6 @@ static target_ulong h_set_mode_resource_addr_trans_= mode(PowerPCCPU *cpu, > { > CPUState *cs; > PowerPCCPUClass *pcc =3D POWERPC_CPU_GET_CLASS(cpu); > - target_ulong prefix; > =20 > if (!(pcc->insns_flags2 & PPC2_ISA207S)) { > return H_P2; > @@ -836,25 +835,12 @@ static target_ulong h_set_mode_resource_addr_tran= s_mode(PowerPCCPU *cpu, > return H_P4; > } > =20 > - switch (mflags) { > - case H_SET_MODE_ADDR_TRANS_NONE: > - prefix =3D 0; > - break; > - case H_SET_MODE_ADDR_TRANS_0001_8000: > - prefix =3D 0x18000; > - break; > - case H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000: > - prefix =3D 0xC000000000004000ULL; > - break; > - default: > + if (mflags =3D=3D AIL_RESERVED) { > return H_UNSUPPORTED_FLAG; > } > =20 > CPU_FOREACH(cs) { > - CPUPPCState *env =3D &POWERPC_CPU(cpu)->env; > - > set_spr(cs, SPR_LPCR, mflags << LPCR_AIL_SHIFT, LPCR_AIL); > - env->excp_prefix =3D prefix; > } > =20 > return H_SUCCESS; > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 098d85d..815d5ee 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -204,11 +204,6 @@ struct sPAPRMachineState { > #define H_SET_MODE_ENDIAN_BIG 0 > #define H_SET_MODE_ENDIAN_LITTLE 1 > =20 > -/* Flags for H_SET_MODE_RESOURCE_ADDR_TRANS_MODE */ > -#define H_SET_MODE_ADDR_TRANS_NONE 0 > -#define H_SET_MODE_ADDR_TRANS_0001_8000 2 > -#define H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000 3 > - > /* VASI States */ > #define H_VASI_INVALID 0 > #define H_VASI_ENABLED 1 > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 676081e..9d4e43c 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -167,6 +167,8 @@ enum powerpc_excp_t { > POWERPC_EXCP_970, > /* POWER7 exception model */ > POWERPC_EXCP_POWER7, > + /* POWER8 exception model */ > + POWERPC_EXCP_POWER8, > #endif /* defined(TARGET_PPC64) */ > }; > =20 > @@ -2277,6 +2279,14 @@ enum { > HMER_XSCOM_STATUS_LSH =3D (63 - 23), > }; > =20 > +/* Alternate Interrupt Location (AIL) */ > +enum { > + AIL_NONE =3D 0, > + AIL_RESERVED =3D 1, > + AIL_0001_8000 =3D 2, > + AIL_C000_0000_0000_4000 =3D 3, > +}; > + > /*********************************************************************= ********/ > =20 > static inline target_ulong cpu_read_xer(CPUPPCState *env) > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c > index c890853..ca4ffe8 100644 > --- a/target-ppc/excp_helper.c > +++ b/target-ppc/excp_helper.c > @@ -77,7 +77,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int = excp_model, int excp) > CPUPPCState *env =3D &cpu->env; > target_ulong msr, new_msr, vector; > int srr0, srr1, asrr0, asrr1; > - int lpes0, lpes1, lev; > + int lpes0, lpes1, lev, ail; > =20 > if (0) { > /* XXX: find a suitable condition to enable the hypervisor mod= e */ > @@ -108,6 +108,25 @@ static inline void powerpc_excp(PowerPCCPU *cpu, i= nt excp_model, int excp) > asrr0 =3D -1; > asrr1 =3D -1; > =20 > + /* Exception targetting modifiers > + * > + * AIL is initialized here but can be cleared by > + * selected exceptions > + */ > +#if defined(TARGET_PPC64) > + if (excp_model =3D=3D POWERPC_EXCP_POWER7 || > + excp_model =3D=3D POWERPC_EXCP_POWER8) { > + if (excp_model =3D=3D POWERPC_EXCP_POWER8) { > + ail =3D (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; > + } else { > + ail =3D 0; > + } > + } else > +#endif /* defined(TARGET_PPC64) */ > + { > + ail =3D 0; > + } > + > switch (excp) { > case POWERPC_EXCP_NONE: > /* Should never happen */ > @@ -146,6 +165,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, in= t excp_model, int excp) > /* XXX: find a suitable condition to enable the hypervisor= mode */ > new_msr |=3D (target_ulong)MSR_HVB; > } > + ail =3D 0; > =20 > /* machine check exceptions don't have ME set */ > new_msr &=3D ~((target_ulong)1 << MSR_ME); > @@ -344,6 +364,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, in= t excp_model, int excp) > /* XXX: find a suitable condition to enable the hypervisor= mode */ > new_msr |=3D (target_ulong)MSR_HVB; > } > + ail =3D 0; > goto store_next; > case POWERPC_EXCP_DSEG: /* Data segment exception = */ > if (lpes1 =3D=3D 0) { > @@ -630,7 +651,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, in= t excp_model, int excp) > } > =20 > #ifdef TARGET_PPC64 > - if (excp_model =3D=3D POWERPC_EXCP_POWER7) { > + if (excp_model =3D=3D POWERPC_EXCP_POWER7 || > + excp_model =3D=3D POWERPC_EXCP_POWER8) { > if (env->spr[SPR_LPCR] & LPCR_ILE) { > new_msr |=3D (target_ulong)1 << MSR_LE; > } > @@ -650,6 +672,29 @@ static inline void powerpc_excp(PowerPCCPU *cpu, i= nt excp_model, int excp) > excp); > } > vector |=3D env->excp_prefix; > + > + /* AIL only works if there is no HV transition and we are running = with > + * translations enabled > + */ > + if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) { > + ail =3D 0; > + } > + /* Handle AIL */ > + if (ail) { > + new_msr |=3D (1 << MSR_IR) | (1 << MSR_DR); > + switch(ail) { > + case AIL_0001_8000: > + vector |=3D 0x18000; > + break; > + case AIL_C000_0000_0000_4000: > + vector |=3D 0xc000000000004000ull; > + break; > + default: > + cpu_abort(cs, "Invalid AIL combination %d\n", ail); > + break; > + } > + } > + > #if defined(TARGET_PPC64) > if (excp_model =3D=3D POWERPC_EXCP_BOOKE) { > if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { > diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c > index 0a33597..f515725 100644 > --- a/target-ppc/translate_init.c > +++ b/target-ppc/translate_init.c > @@ -8487,7 +8487,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *dat= a) > pcc->handle_mmu_fault =3D ppc_hash64_handle_mmu_fault; > pcc->sps =3D &POWER7_POWER8_sps; > #endif > - pcc->excp_model =3D POWERPC_EXCP_POWER7; > + pcc->excp_model =3D POWERPC_EXCP_POWER8; > pcc->bus_model =3D PPC_FLAGS_INPUT_POWER7; > pcc->bfd_mach =3D bfd_mach_ppc64; > pcc->flags =3D POWERPC_FLAG_VRE | POWERPC_FLAG_SE | >=20