From patchwork Tue Jan 31 02:27:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [6/7] PPC: E500: Implement msgsnd Date: Mon, 30 Jan 2012 16:27:43 -0000 From: Alexander Graf X-Patchwork-Id: 138678 Message-Id: <1327976864-30308-7-git-send-email-agraf@suse.de> To: qemu-ppc@nongnu.org Cc: qemu-devel Developers This patch implements the msgsnd instruction. It is part of the Embedded.Processor Control specification and allows one CPU to IPI another CPU without going through an interrupt controller. Signed-off-by: Alexander Graf --- target-ppc/helper.h | 1 + target-ppc/op_helper.c | 18 ++++++++++++++++++ target-ppc/translate.c | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 0 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 48ceb61..148543a 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -358,6 +358,7 @@ DEF_HELPER_FLAGS_1(load_sr, TCG_CALL_CONST, tl, tl); DEF_HELPER_FLAGS_2(store_sr, TCG_CALL_CONST, void, tl, tl) DEF_HELPER_FLAGS_1(602_mfrom, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) +DEF_HELPER_1(msgsnd, void, tl) DEF_HELPER_1(msgclr, void, tl) #endif diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index e2f7614..3f4e067 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -4549,4 +4549,22 @@ void helper_msgclr(target_ulong rb) env->pending_interrupts &= ~(1 << irq); } +void helper_msgsnd(target_ulong rb) +{ + int irq = dbell2irq(rb); + int pir = rb & DBELL_PIRTAG_MASK; + CPUState *cenv; + + if (irq < 0) { + return; + } + + for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { + if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { + cenv->pending_interrupts |= 1 << irq; + cpu_interrupt(cenv, CPU_INTERRUPT_HARD); + } + } +} + #endif /* !CONFIG_USER_ONLY */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 01bfe0a..b2780db 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6236,6 +6236,20 @@ static void gen_msgclr(DisasContext *ctx) #endif } +static void gen_msgsnd(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + if (unlikely(ctx->mem_idx == 0)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + + gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); +#endif +} + /*** Altivec vector extension ***/ /* Altivec registers moves */ @@ -8626,6 +8640,8 @@ GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, PPC_NONE, PPC2_BOOKE206), +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_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),