diff --git a/qemu/hw/ppc/ppc.c b/qemu/hw/ppc/ppc.c index 6f3bba6d3b..c62897728b 100644 --- a/qemu/hw/ppc/ppc.c +++ b/qemu/hw/ppc/ppc.c @@ -54,7 +54,7 @@ # define LOG_TB(...) do { } while (0) #endif -#if 0 +#if 1 static void cpu_ppc_tb_stop (CPUPPCState *env); static void cpu_ppc_tb_start (CPUPPCState *env); #endif @@ -90,7 +90,9 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) env->pending_interrupts, CPU(cpu)->interrupt_request); } -#if 0 +#if 1 +// Broadway clock speed +#define TB_TIMER_CLOCK (243000000u/4000) /* PowerPC 6xx / 7xx internal IRQ controller */ static void ppc6xx_set_irq(void *opaque, int pin, int level) { @@ -111,6 +113,7 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) LOG_IRQ("%s: %s the time base\n", __func__, level ? "start" : "stop"); if (level) { + cpu_ppc_tb_init(env, TB_TIMER_CLOCK); cpu_ppc_tb_start(env); } else { cpu_ppc_tb_stop(env); @@ -174,6 +177,7 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) void ppc6xx_irq_init(PowerPCCPU *cpu) { + ppc6xx_set_irq((void*)cpu, PPC6xx_INPUT_TBEN, 1); #if 0 CPUPPCState *env = &cpu->env; @@ -735,7 +739,7 @@ void cpu_ppc_store_tbu40(CPUPPCState *env, uint64_t value) &tb_env->tb_offset, tb); } -#if 0 +#if 1 static void cpu_ppc_tb_stop (CPUPPCState *env) { ppc_tb_t *tb_env = env->tb_env; @@ -1565,5 +1569,6 @@ void ppc_irq_reset(PowerPCCPU *cpu) CPUPPCState *env = &cpu->env; env->irq_input_state = 0; + ppc6xx_set_irq((void*)cpu, PPC6xx_INPUT_TBEN, 0); // kvmppc_set_interrupt(cpu, PPC_INTERRUPT_EXT, 0); } diff --git a/qemu/target/ppc/translate_init.inc.c b/qemu/target/ppc/translate_init.inc.c index d2fb1974ad..1242f36d16 100644 --- a/qemu/target/ppc/translate_init.inc.c +++ b/qemu/target/ppc/translate_init.inc.c @@ -171,7 +171,7 @@ static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn) /* SPR common to all non-embedded PowerPC */ /* DECR */ -#if 0 +#if 1 static void spr_read_decr(DisasContext *ctx, int gprn, int sprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -187,7 +187,7 @@ static void spr_read_decr(DisasContext *ctx, int gprn, int sprn) #define spr_read_decr spr_read_generic #endif -#if 0 +#if 1 static void spr_write_decr(DisasContext *ctx, int sprn, int gprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -205,7 +205,7 @@ static void spr_write_decr(DisasContext *ctx, int sprn, int gprn) /* SPR common to all non-embedded PowerPC, except 601 */ /* Time base */ -#if 0 +#if 1 static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -222,7 +222,7 @@ static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn) #define spr_read_tbl spr_read_generic #endif -#if 0 +#if 1 static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -255,7 +255,7 @@ static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn) } #endif -#if 0 +#if 1 static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -273,7 +273,7 @@ static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn) #endif -#if 0 +#if 1 static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; diff --git a/tests/unit/test_ppc.c b/tests/unit/test_ppc.c index 5463b21f0e..771dc53da4 100644 --- a/tests/unit/test_ppc.c +++ b/tests/unit/test_ppc.c @@ -107,15 +107,34 @@ static void test_ppc32_cr(void) static void test_ppc32_spr_time(void) { - char code[] = ("\x7c\x76\x02\xa6" // mfspr r3, DEC - "\x7c\x6d\x42\xa6" // mfspr r3, TBUr - ); - + uint32_t r3_val; uc_engine *uc; - uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code, - sizeof(code) - 1); - OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + char code_dec[] = "\x7c\x76\x02\xa6"; // mfspr r3, DEC + uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code_dec, + sizeof(code_dec) - 1); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code_dec) - 1, 0, 0)); + OK(uc_reg_read(uc, UC_PPC_REG_3, &r3_val)); + printf("DEC: 0x%08x\n", BEINT32(r3_val)); + OK(uc_close(uc)); + + char code_tbur[] = "\x7c\x6d\x42\xa6"; // mfspr r3, TBUr + uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code_tbur, + sizeof(code_tbur) - 1); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code_tbur) - 1, 0, 0)); + OK(uc_reg_read(uc, UC_PPC_REG_3, &r3_val)); + printf("TBUr: 0x%08x\n", BEINT32(r3_val)); + OK(uc_close(uc)); + + char code_tblr[] = "\x7c\x6c\x42\xa6"; // mfspr r3, TBLr + uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code_tblr, + sizeof(code_tblr) - 1); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code_tblr) - 1, 0, 0)); + OK(uc_reg_read(uc, UC_PPC_REG_3, &r3_val)); + printf("TBLr: 0x%08x\n", BEINT32(r3_val)); OK(uc_close(uc)); }