On Thu, Jan 18, 2018 at 03:54:03PM +0100, Cédric Le Goater wrote: > The hypervisor doorbells are used by skiboot and Linux on POWER9 > processors to wake up secondaries. > > This adds processor control support to the Server architecture by > reusing the Embedded support. They are very similar, only the bits > definition of the CPU identifier differ. > > Still to be done is message broadcast to all threads of the same > processor. > > Signed-off-by: Cédric Le Goater <c...@kaod.org>
Applied to ppc-for-2.12, thanks. > --- > > Changes since v2: > > - introduced specific msgclr/snd helpers for book3s > > target/ppc/cpu.h | 8 +++++-- > target/ppc/excp_helper.c | 52 > +++++++++++++++++++++++++++++++++++++++++++++ > target/ppc/helper.h | 2 ++ > target/ppc/translate.c | 25 ++++++++++++++++++++-- > target/ppc/translate_init.c | 2 +- > 5 files changed, 84 insertions(+), 5 deletions(-) > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index b8f4dfc1084a..603a38cae83f 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -930,7 +930,7 @@ enum { > #define BOOKE206_MAX_TLBN 4 > > > /*****************************************************************************/ > -/* Embedded.Processor Control */ > +/* Server and Embedded Processor Control */ > > #define DBELL_TYPE_SHIFT 27 > #define DBELL_TYPE_MASK (0x1f << DBELL_TYPE_SHIFT) > @@ -940,11 +940,15 @@ enum { > #define DBELL_TYPE_G_DBELL_CRIT (0x03 << DBELL_TYPE_SHIFT) > #define DBELL_TYPE_G_DBELL_MC (0x04 << DBELL_TYPE_SHIFT) > > -#define DBELL_BRDCAST (1 << 26) > +#define DBELL_TYPE_DBELL_SERVER (0x05 << DBELL_TYPE_SHIFT) > + > +#define DBELL_BRDCAST PPC_BIT(37) > #define DBELL_LPIDTAG_SHIFT 14 > #define DBELL_LPIDTAG_MASK (0xfff << DBELL_LPIDTAG_SHIFT) > #define DBELL_PIRTAG_MASK 0x3fff > > +#define DBELL_PROCIDTAG_MASK PPC_BITMASK(44, 63) > + > > /*****************************************************************************/ > /* Segment page size information, used by recent hash MMUs > * The format of this structure mirrors kvm_ppc_smmu_info > diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c > index 4e548a448747..c092fbead036 100644 > --- a/target/ppc/excp_helper.c > +++ b/target/ppc/excp_helper.c > @@ -417,6 +417,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int > excp_model, int excp) > case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception > */ > case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception > */ > case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception > */ > + case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt > */ > case POWERPC_EXCP_HV_EMU: > srr0 = SPR_HSRR0; > srr1 = SPR_HSRR1; > @@ -846,6 +847,11 @@ static void ppc_hw_interrupt(CPUPPCState *env) > powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI); > return; > } > + if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { > + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); > + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV); > + return; > + } > if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { > env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); > powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM); > @@ -1145,4 +1151,50 @@ void helper_msgsnd(target_ulong rb) > } > qemu_mutex_unlock_iothread(); > } > + > +/* Server Processor Control */ > +static int book3s_dbell2irq(target_ulong rb) > +{ > + int msg = rb & DBELL_TYPE_MASK; > + > + /* A Directed Hypervisor Doorbell message is sent only if the > + * message type is 5. All other types are reserved and the > + * instruction is a no-op */ > + return msg == DBELL_TYPE_DBELL_SERVER ? PPC_INTERRUPT_HDOORBELL : -1; > +} > + > +void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) > +{ > + int irq = book3s_dbell2irq(rb); > + > + if (irq < 0) { > + return; > + } > + > + env->pending_interrupts &= ~(1 << irq); > +} > + > +void helper_book3s_msgsnd(target_ulong rb) > +{ > + int irq = book3s_dbell2irq(rb); > + int pir = rb & DBELL_PROCIDTAG_MASK; > + CPUState *cs; > + > + if (irq < 0) { > + return; > + } > + > + qemu_mutex_lock_iothread(); > + CPU_FOREACH(cs) { > + PowerPCCPU *cpu = POWERPC_CPU(cs); > + CPUPPCState *cenv = &cpu->env; > + > + /* TODO: broadcast message to all threads of the same processor */ > + if (cenv->spr_cb[SPR_PIR].default_value == pir) { > + cenv->pending_interrupts |= 1 << irq; > + cpu_interrupt(cs, CPU_INTERRUPT_HARD); > + } > + } > + qemu_mutex_unlock_iothread(); > +} > #endif > diff --git a/target/ppc/helper.h b/target/ppc/helper.h > index bb6a94a8b390..5b739179b8b5 100644 > --- a/target/ppc/helper.h > +++ b/target/ppc/helper.h > @@ -679,6 +679,8 @@ DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, > tl, tl) > DEF_HELPER_FLAGS_1(602_mfrom, TCG_CALL_NO_RWG_SE, tl, tl) > DEF_HELPER_1(msgsnd, void, tl) > DEF_HELPER_2(msgclr, void, env, tl) > +DEF_HELPER_1(book3s_msgsnd, void, tl) > +DEF_HELPER_2(book3s_msgclr, void, env, tl) > #endif > > DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32) > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index 396f422cf407..4325aa90a6fa 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -6175,7 +6175,12 @@ static void gen_msgclr(DisasContext *ctx) > GEN_PRIV; > #else > CHK_HV; > - gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); > + /* 64-bit server processors compliant with arch 2.x */ > + if (ctx->insns_flags & PPC_SEGMENT_64B) { > + gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); > + } else { > + gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); > + } > #endif /* defined(CONFIG_USER_ONLY) */ > } > > @@ -6185,10 +6190,24 @@ static void gen_msgsnd(DisasContext *ctx) > GEN_PRIV; > #else > CHK_HV; > - gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); > + /* 64-bit server processors compliant with arch 2.x */ > + if (ctx->insns_flags & PPC_SEGMENT_64B) { > + gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]); > + } else { > + gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); > + } > #endif /* defined(CONFIG_USER_ONLY) */ > } > > +static void gen_msgsync(DisasContext *ctx) > +{ > +#if defined(CONFIG_USER_ONLY) > + GEN_PRIV; > +#else > + CHK_HV; > +#endif /* defined(CONFIG_USER_ONLY) */ > + /* interpreted as no-op */ > +} > > #if defined(TARGET_PPC64) > static void gen_maddld(DisasContext *ctx) > @@ -6669,6 +6688,8 @@ GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, > 0x03ff0001, > PPC_NONE, PPC2_PRCNTL), > GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, > PPC_NONE, PPC2_PRCNTL), > +GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, > + PPC_NONE, PPC2_PRCNTL), > GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), > GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), > GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), > diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c > index ab70b3a25c1d..87a23f0f6265 100644 > --- a/target/ppc/translate_init.c > +++ b/target/ppc/translate_init.c > @@ -8866,7 +8866,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) > PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | > PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | > PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | > - PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300; > + PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300 | PPC2_PRCNTL; > pcc->msr_mask = (1ull << MSR_SF) | > (1ull << MSR_TM) | > (1ull << MSR_VR) | -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature