diff options
-rw-r--r-- | hw/ppc/ppc.c | 17 | ||||
-rw-r--r-- | include/hw/ppc/ppc.h | 3 | ||||
-rw-r--r-- | target/ppc/cpu.h | 1 | ||||
-rw-r--r-- | target/ppc/helper.h | 1 | ||||
-rw-r--r-- | target/ppc/timebase_helper.c | 5 | ||||
-rw-r--r-- | target/ppc/translate_init.inc.c | 23 |
6 files changed, 30 insertions, 20 deletions
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index d8c4028..2856d69 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -809,12 +809,9 @@ target_ulong cpu_ppc_load_hdecr(CPUPPCState *env) uint64_t cpu_ppc_load_purr (CPUPPCState *env) { ppc_tb_t *tb_env = env->tb_env; - uint64_t diff; - diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start; - - return tb_env->purr_load + - muldiv64(diff, tb_env->tb_freq, NANOSECONDS_PER_SECOND); + return cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + tb_env->purr_offset); } /* When decrementer expires, @@ -973,12 +970,12 @@ static void cpu_ppc_hdecr_cb(void *opaque) cpu_ppc_hdecr_excp(cpu); } -static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value) +void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value) { - ppc_tb_t *tb_env = cpu->env.tb_env; + ppc_tb_t *tb_env = env->tb_env; - tb_env->purr_load = value; - tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + &tb_env->purr_offset, value); } static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) @@ -995,7 +992,7 @@ static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) */ _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32); _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32); - cpu_ppc_store_purr(cpu, 0x0000000000000000ULL); + cpu_ppc_store_purr(env, 0x0000000000000000ULL); } static void timebase_save(PPCTimebase *tb) diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index d7a9560..4ea5436 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -33,8 +33,7 @@ struct ppc_tb_t { /* Hypervisor decrementer management */ uint64_t hdecr_next; /* Tick for next hdecr interrupt */ QEMUTimer *hdecr_timer; - uint64_t purr_load; - uint64_t purr_start; + int64_t purr_offset; void *opaque; uint32_t flags; }; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index eb7d2c7..da44cc8 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1311,6 +1311,7 @@ void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value); target_ulong cpu_ppc_load_hdecr(CPUPPCState *env); void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value); uint64_t cpu_ppc_load_purr(CPUPPCState *env); +void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value); uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env); uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env); #if !defined(CONFIG_USER_ONLY) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index a5f53bb..356a14d 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -655,6 +655,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env) #if !defined(CONFIG_USER_ONLY) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env) +DEF_HELPER_FLAGS_2(store_purr, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_2(store_ptcr, void, env, tl) #endif DEF_HELPER_2(store_sdr1, void, env, tl) diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c index 8c3c2fe..2395295 100644 --- a/target/ppc/timebase_helper.c +++ b/target/ppc/timebase_helper.c @@ -55,6 +55,11 @@ target_ulong helper_load_purr(CPUPPCState *env) { return (target_ulong)cpu_ppc_load_purr(env); } + +void helper_store_purr(CPUPPCState *env, target_ulong val) +{ + cpu_ppc_store_purr(env, val); +} #endif target_ulong helper_load_601_rtcl(CPUPPCState *env) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 226aecf..c5e4d45 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -287,6 +287,11 @@ static void spr_read_purr(DisasContext *ctx, int gprn, int sprn) gen_helper_load_purr(cpu_gpr[gprn], cpu_env); } +static void spr_write_purr(DisasContext *ctx, int sprn, int gprn) +{ + gen_helper_store_purr(cpu_env, cpu_gpr[gprn]); +} + /* HDECR */ static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn) { @@ -8013,14 +8018,16 @@ static void gen_spr_book3s_purr(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ - spr_register_kvm(env, SPR_PURR, "PURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_PURR, 0x00000000); - spr_register_kvm(env, SPR_SPURR, "SPURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_SPURR, 0x00000000); + spr_register_kvm_hv(env, SPR_PURR, "PURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, &spr_write_purr, + KVM_REG_PPC_PURR, 0x00000000); + spr_register_kvm_hv(env, SPR_SPURR, "SPURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, &spr_write_purr, + KVM_REG_PPC_SPURR, 0x00000000); #endif } |