The handling of the following two registers are added - DAWR1 (0x0bd, 189) - Data Address Watchpoint 1 DAWRX1 (0x0b5, 181) - Data Address Watchpoint Extension 1
Signed-off-by: dan tan <dan...@linux.vnet.ibm.com> --- target/ppc/cpu.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu.h | 6 ++++++ target/ppc/cpu_init.c | 10 ++++++++++ target/ppc/excp_helper.c | 11 ++++++++++- target/ppc/helper.h | 2 ++ target/ppc/machine.c | 1 + target/ppc/misc_helper.c | 10 ++++++++++ target/ppc/spr_common.h | 2 ++ target/ppc/translate.c | 12 ++++++++++++ 9 files changed, 104 insertions(+), 1 deletion(-) diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index e3ad8e0..8a77328 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -188,6 +188,57 @@ void ppc_store_dawrx0(CPUPPCState *env, uint32_t val) env->spr[SPR_DAWRX0] = val; ppc_update_daw0(env); } + +void ppc_update_daw1(CPUPPCState *env) +{ + CPUState *cs = env_cpu(env); + target_ulong deaw = env->spr[SPR_DAWR1] & PPC_BITMASK(0, 60); + uint32_t dawrx = env->spr[SPR_DAWRX1]; + int mrd = extract32(dawrx, PPC_BIT_NR(48), 54 - 48); + bool dw = extract32(dawrx, PPC_BIT_NR(57), 1); + bool dr = extract32(dawrx, PPC_BIT_NR(58), 1); + bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); + bool sv = extract32(dawrx, PPC_BIT_NR(62), 1); + bool pr = extract32(dawrx, PPC_BIT_NR(62), 1); + vaddr len; + int flags; + + if (env->dawr1_watchpoint) { + cpu_watchpoint_remove_by_ref(cs, env->dawr1_watchpoint); + env->dawr1_watchpoint = NULL; + } + + if (!dr && !dw) { + return; + } + + if (!hv && !sv && !pr) { + return; + } + + len = (mrd + 1) * 8; + flags = BP_CPU | BP_STOP_BEFORE_ACCESS; + if (dr) { + flags |= BP_MEM_READ; + } + if (dw) { + flags |= BP_MEM_WRITE; + } + + cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr1_watchpoint); +} + +void ppc_store_dawr1(CPUPPCState *env, target_ulong val) +{ + env->spr[SPR_DAWR1] = val; + ppc_update_daw1(env); +} + +void ppc_store_dawrx1(CPUPPCState *env, uint32_t val) +{ + env->spr[SPR_DAWRX1] = val; + ppc_update_daw1(env); +} #endif #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index f8101ff..ab34fc7 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1237,6 +1237,7 @@ struct CPUArchState { ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */ struct CPUBreakpoint *ciabr_breakpoint; struct CPUWatchpoint *dawr0_watchpoint; + struct CPUWatchpoint *dawr1_watchpoint; #endif target_ulong sr[32]; /* segment registers */ uint32_t nb_BATs; /* number of BATs */ @@ -1552,6 +1553,9 @@ void ppc_store_ciabr(CPUPPCState *env, target_ulong value); void ppc_update_daw0(CPUPPCState *env); void ppc_store_dawr0(CPUPPCState *env, target_ulong value); void ppc_store_dawrx0(CPUPPCState *env, uint32_t value); +void ppc_update_daw1(CPUPPCState *env); +void ppc_store_dawr1(CPUPPCState *env, target_ulong value); +void ppc_store_dawrx1(CPUPPCState *env, uint32_t value); #endif /* !defined(CONFIG_USER_ONLY) */ void ppc_store_msr(CPUPPCState *env, target_ulong value); @@ -1737,9 +1741,11 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_PSPB (0x09F) #define SPR_DPDES (0x0B0) #define SPR_DAWR0 (0x0B4) +#define SPR_DAWR1 (0x0B5) #define SPR_RPR (0x0BA) #define SPR_CIABR (0x0BB) #define SPR_DAWRX0 (0x0BC) +#define SPR_DAWRX1 (0x0BD) #define SPR_HFSCR (0x0BE) #define SPR_VRSAVE (0x100) #define SPR_USPRG0 (0x100) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 40fe14a..d75c359 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5119,11 +5119,21 @@ static void register_book3s_207_dbg_sprs(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_dawr0, KVM_REG_PPC_DAWR, 0x00000000); + spr_register_kvm_hv(env, SPR_DAWR1, "DAWR1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_dawr1, + KVM_REG_PPC_DAWR, 0x00000000); spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_dawrx0, KVM_REG_PPC_DAWRX, 0x00000000); + spr_register_kvm_hv(env, SPR_DAWRX1, "DAWRX1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_dawrx1, + KVM_REG_PPC_DAWRX, 0x00000000); spr_register_kvm_hv(env, SPR_CIABR, "CIABR", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index a42743a..0b87b85 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -3314,10 +3314,19 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) { #if defined(TARGET_PPC64) CPUPPCState *env = cpu_env(cs); + bool match = false; + uint32_t dawrx; if (env->insns_flags2 & PPC2_ISA207S) { if (wp == env->dawr0_watchpoint) { - uint32_t dawrx = env->spr[SPR_DAWRX0]; + dawrx = env->spr[SPR_DAWRX0]; + match = true; + } else if (wp == env->dawr1_watchpoint) { + dawrx = env->spr[SPR_DAWRX1]; + match = true; + } + + if (match == true) { bool wt = extract32(dawrx, PPC_BIT_NR(59), 1); bool wti = extract32(dawrx, PPC_BIT_NR(60), 1); bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 86f97ee..da6ada4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -27,7 +27,9 @@ DEF_HELPER_2(store_lpcr, void, env, tl) DEF_HELPER_2(store_pcr, void, env, tl) DEF_HELPER_2(store_ciabr, void, env, tl) DEF_HELPER_2(store_dawr0, void, env, tl) +DEF_HELPER_2(store_dawr1, void, env, tl) DEF_HELPER_2(store_dawrx0, void, env, tl) +DEF_HELPER_2(store_dawrx1, void, env, tl) DEF_HELPER_2(store_mmcr0, void, env, tl) DEF_HELPER_2(store_mmcr1, void, env, tl) DEF_HELPER_3(store_pmc, void, env, i32, i64) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 68cbdff..eef596d 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -326,6 +326,7 @@ static int cpu_post_load(void *opaque, int version_id) #if defined(TARGET_PPC64) ppc_update_ciabr(env); ppc_update_daw0(env); + ppc_update_daw1(env); #endif /* * TCG needs to re-start the decrementer timer and/or raise the diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index a05bdf7..1fc0705 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -209,11 +209,21 @@ void helper_store_dawr0(CPUPPCState *env, target_ulong value) ppc_store_dawr0(env, value); } +void helper_store_dawr1(CPUPPCState *env, target_ulong value) +{ + ppc_store_dawr1(env, value); +} + void helper_store_dawrx0(CPUPPCState *env, target_ulong value) { ppc_store_dawrx0(env, value); } +void helper_store_dawrx1(CPUPPCState *env, target_ulong value) +{ + ppc_store_dawrx1(env, value); +} + /* * DPDES register is shared. Each bit reflects the state of the * doorbell interrupt of a thread of the same core. diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h index 8a9d6cd..2f9b31f 100644 --- a/target/ppc/spr_common.h +++ b/target/ppc/spr_common.h @@ -161,7 +161,9 @@ void spr_read_cfar(DisasContext *ctx, int gprn, int sprn); void spr_write_cfar(DisasContext *ctx, int sprn, int gprn); void spr_write_ciabr(DisasContext *ctx, int sprn, int gprn); void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn); +void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn); void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn); +void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn); void spr_write_ureg(DisasContext *ctx, int sprn, int gprn); void spr_read_purr(DisasContext *ctx, int gprn, int sprn); void spr_write_purr(DisasContext *ctx, int sprn, int gprn); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 329da4d..171e080 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -588,11 +588,23 @@ void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn) gen_helper_store_dawr0(tcg_env, cpu_gpr[gprn]); } +void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn) +{ + translator_io_start(&ctx->base); + gen_helper_store_dawr1(tcg_env, cpu_gpr[gprn]); +} + void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn) { translator_io_start(&ctx->base); gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]); } + +void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn) +{ + translator_io_start(&ctx->base); + gen_helper_store_dawrx1(tcg_env, cpu_gpr[gprn]); +} #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ /* CTR */ -- 1.8.3.1