diff options
author | Alexander Graf <agraf@suse.de> | 2012-01-31 03:18:35 +0100 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2012-02-02 02:47:47 +0100 |
commit | 9e0b5cb1ecf5543864fad0628a17be23bb617ed7 (patch) | |
tree | 96d5d130a7e73b4ed44e56b6e88a2a34098dd3a6 | |
parent | a9abd71770e64d22ba6cb40c30e4c35998e5c743 (diff) | |
download | qemu-9e0b5cb1ecf5543864fad0628a17be23bb617ed7.zip |
PPC: E500: Implement msgclr
This patch implements the msgclr instruction. It is part of the
Embedded.Processor Control specification and clears pending doorbell
interrupts on the current CPU.
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | target-ppc/helper.h | 1 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 35 | ||||
-rw-r--r-- | target-ppc/translate.c | 18 |
3 files changed, 54 insertions, 0 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 4798fd57ee..48ceb61462 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(msgclr, void, tl) #endif DEF_HELPER_3(dlmzb, tl, tl, tl, i32) diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 0d1206a649..e2f7614c27 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -4514,4 +4514,39 @@ void helper_booke206_tlbflush(uint32_t type) booke206_flush_tlb(env, flags, 1); } +/* Embedded.Processor Control */ +static int dbell2irq(target_ulong rb) +{ + int msg = rb & DBELL_TYPE_MASK; + int irq = -1; + + switch (msg) { + case DBELL_TYPE_DBELL: + irq = PPC_INTERRUPT_DOORBELL; + break; + case DBELL_TYPE_DBELL_CRIT: + irq = PPC_INTERRUPT_CDOORBELL; + break; + case DBELL_TYPE_G_DBELL: + case DBELL_TYPE_G_DBELL_CRIT: + case DBELL_TYPE_G_DBELL_MC: + /* XXX implement */ + default: + break; + } + + return irq; +} + +void helper_msgclr(target_ulong rb) +{ + int irq = dbell2irq(rb); + + if (irq < 0) { + return; + } + + env->pending_interrupts &= ~(1 << irq); +} + #endif /* !CONFIG_USER_ONLY */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 58a4853a0d..01bfe0a1de 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6220,6 +6220,22 @@ static void gen_icbt_440(DisasContext *ctx) */ } +/* Embedded.Processor Control */ + +static void gen_msgclr(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_msgclr(cpu_gpr[rB(ctx->opcode)]); +#endif +} + /*** Altivec vector extension ***/ /* Altivec registers moves */ @@ -8610,6 +8626,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(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, + 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), |