ppc: Enable 2nd DAWR support on Power10 PowerNV machine

Extend the existing watchpoint facility from TCG DAWR0 emulation
to DAWR1 on POWER10.

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Message-ID: <173708680684.1678.13237334676438770057.stgit@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
Shivaprasad G Bhat 2025-01-17 04:06:51 +00:00 committed by Nicholas Piggin
parent 0829b6f0a8
commit 7ea6e12529
9 changed files with 109 additions and 43 deletions

View File

@ -130,11 +130,13 @@ void ppc_store_ciabr(CPUPPCState *env, target_ulong val)
ppc_update_ciabr(env); ppc_update_ciabr(env);
} }
void ppc_update_daw0(CPUPPCState *env) void ppc_update_daw(CPUPPCState *env, int rid)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
target_ulong deaw = env->spr[SPR_DAWR0] & PPC_BITMASK(0, 60); int spr_dawr = rid ? SPR_DAWR1 : SPR_DAWR0;
uint32_t dawrx = env->spr[SPR_DAWRX0]; int spr_dawrx = rid ? SPR_DAWRX1 : SPR_DAWRX0;
target_ulong deaw = env->spr[spr_dawr] & PPC_BITMASK(0, 60);
uint32_t dawrx = env->spr[spr_dawrx];
int mrd = extract32(dawrx, PPC_BIT_NR(48), 54 - 48); int mrd = extract32(dawrx, PPC_BIT_NR(48), 54 - 48);
bool dw = extract32(dawrx, PPC_BIT_NR(57), 1); bool dw = extract32(dawrx, PPC_BIT_NR(57), 1);
bool dr = extract32(dawrx, PPC_BIT_NR(58), 1); bool dr = extract32(dawrx, PPC_BIT_NR(58), 1);
@ -144,9 +146,9 @@ void ppc_update_daw0(CPUPPCState *env)
vaddr len; vaddr len;
int flags; int flags;
if (env->dawr0_watchpoint) { if (env->dawr_watchpoint[rid]) {
cpu_watchpoint_remove_by_ref(cs, env->dawr0_watchpoint); cpu_watchpoint_remove_by_ref(cs, env->dawr_watchpoint[rid]);
env->dawr0_watchpoint = NULL; env->dawr_watchpoint[rid] = NULL;
} }
if (!dr && !dw) { if (!dr && !dw) {
@ -166,28 +168,45 @@ void ppc_update_daw0(CPUPPCState *env)
flags |= BP_MEM_WRITE; flags |= BP_MEM_WRITE;
} }
cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr0_watchpoint); cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr_watchpoint[rid]);
} }
void ppc_store_dawr0(CPUPPCState *env, target_ulong val) void ppc_store_dawr0(CPUPPCState *env, target_ulong val)
{ {
env->spr[SPR_DAWR0] = val; env->spr[SPR_DAWR0] = val;
ppc_update_daw0(env); ppc_update_daw(env, 0);
} }
void ppc_store_dawrx0(CPUPPCState *env, uint32_t val) static void ppc_store_dawrx(CPUPPCState *env, uint32_t val, int rid)
{ {
int hrammc = extract32(val, PPC_BIT_NR(56), 1); int hrammc = extract32(val, PPC_BIT_NR(56), 1);
if (hrammc) { if (hrammc) {
/* This might be done with a second watchpoint at the xor of DEAW[0] */ /* This might be done with a second watchpoint at the xor of DEAW[0] */
qemu_log_mask(LOG_UNIMP, "%s: DAWRX0[HRAMMC] is unimplemented\n", qemu_log_mask(LOG_UNIMP, "%s: DAWRX%d[HRAMMC] is unimplemented\n",
__func__); __func__, rid);
} }
env->spr[SPR_DAWRX0] = val; env->spr[rid ? SPR_DAWRX1 : SPR_DAWRX0] = val;
ppc_update_daw0(env); ppc_update_daw(env, rid);
} }
void ppc_store_dawrx0(CPUPPCState *env, uint32_t val)
{
ppc_store_dawrx(env, val, 0);
}
void ppc_store_dawr1(CPUPPCState *env, target_ulong val)
{
env->spr[SPR_DAWR1] = val;
ppc_update_daw(env, 1);
}
void ppc_store_dawrx1(CPUPPCState *env, uint32_t val)
{
ppc_store_dawrx(env, val, 1);
}
#endif #endif
#endif #endif

View File

@ -1260,7 +1260,7 @@ struct CPUArchState {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */ ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */
struct CPUBreakpoint *ciabr_breakpoint; struct CPUBreakpoint *ciabr_breakpoint;
struct CPUWatchpoint *dawr0_watchpoint; struct CPUWatchpoint *dawr_watchpoint[2];
#endif #endif
target_ulong sr[32]; /* segment registers */ target_ulong sr[32]; /* segment registers */
uint32_t nb_BATs; /* number of BATs */ uint32_t nb_BATs; /* number of BATs */
@ -1589,9 +1589,11 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val);
void ppc_update_ciabr(CPUPPCState *env); void ppc_update_ciabr(CPUPPCState *env);
void ppc_store_ciabr(CPUPPCState *env, target_ulong value); void ppc_store_ciabr(CPUPPCState *env, target_ulong value);
void ppc_update_daw0(CPUPPCState *env); void ppc_update_daw(CPUPPCState *env, int rid);
void ppc_store_dawr0(CPUPPCState *env, target_ulong value); void ppc_store_dawr0(CPUPPCState *env, target_ulong value);
void ppc_store_dawrx0(CPUPPCState *env, uint32_t value); void ppc_store_dawrx0(CPUPPCState *env, uint32_t value);
void ppc_store_dawr1(CPUPPCState *env, target_ulong value);
void ppc_store_dawrx1(CPUPPCState *env, uint32_t value);
#endif /* !defined(CONFIG_USER_ONLY) */ #endif /* !defined(CONFIG_USER_ONLY) */
void ppc_store_msr(CPUPPCState *env, target_ulong value); void ppc_store_msr(CPUPPCState *env, target_ulong value);

View File

@ -5172,6 +5172,20 @@ static void register_book3s_207_dbg_sprs(CPUPPCState *env)
KVM_REG_PPC_CIABR, 0x00000000); KVM_REG_PPC_CIABR, 0x00000000);
} }
static void register_book3s_310_dbg_sprs(CPUPPCState *env)
{
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_DAWR1, 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_DAWRX1, 0x00000000);
}
static void register_970_dbg_sprs(CPUPPCState *env) static void register_970_dbg_sprs(CPUPPCState *env)
{ {
/* Breakpoints */ /* Breakpoints */
@ -6584,6 +6598,7 @@ static void init_proc_POWER10(CPUPPCState *env)
{ {
register_power9_common_sprs(env); register_power9_common_sprs(env);
register_HEIR64_spr(env); register_HEIR64_spr(env);
register_book3s_310_dbg_sprs(env);
register_power10_hash_sprs(env); register_power10_hash_sprs(env);
register_power10_dexcr_sprs(env); register_power10_dexcr_sprs(env);
register_power10_pmu_sup_sprs(env); register_power10_pmu_sup_sprs(env);

View File

@ -28,6 +28,8 @@ DEF_HELPER_2(store_pcr, void, env, tl)
DEF_HELPER_2(store_ciabr, void, env, tl) DEF_HELPER_2(store_ciabr, void, env, tl)
DEF_HELPER_2(store_dawr0, void, env, tl) DEF_HELPER_2(store_dawr0, void, env, tl)
DEF_HELPER_2(store_dawrx0, void, env, tl) DEF_HELPER_2(store_dawrx0, void, env, tl)
DEF_HELPER_2(store_dawr1, void, env, tl)
DEF_HELPER_2(store_dawrx1, void, env, tl)
DEF_HELPER_2(store_mmcr0, void, env, tl) DEF_HELPER_2(store_mmcr0, void, env, tl)
DEF_HELPER_2(store_mmcr1, void, env, tl) DEF_HELPER_2(store_mmcr1, void, env, tl)
DEF_HELPER_2(store_mmcrA, void, env, tl) DEF_HELPER_2(store_mmcrA, void, env, tl)

View File

@ -264,7 +264,8 @@ static int cpu_post_load(void *opaque, int version_id)
/* Re-set breaks based on regs */ /* Re-set breaks based on regs */
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
ppc_update_ciabr(env); ppc_update_ciabr(env);
ppc_update_daw0(env); ppc_update_daw(env, 0);
ppc_update_daw(env, 1);
#endif #endif
/* /*
* TCG needs to re-start the decrementer timer and/or raise the * TCG needs to re-start the decrementer timer and/or raise the

View File

@ -234,6 +234,16 @@ void helper_store_dawrx0(CPUPPCState *env, target_ulong value)
ppc_store_dawrx0(env, value); ppc_store_dawrx0(env, value);
} }
void helper_store_dawr1(CPUPPCState *env, target_ulong value)
{
ppc_store_dawr1(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 * DPDES register is shared. Each bit reflects the state of the
* doorbell interrupt of a thread of the same core. * doorbell interrupt of a thread of the same core.

View File

@ -165,6 +165,8 @@ void spr_write_cfar(DisasContext *ctx, int sprn, int gprn);
void spr_write_ciabr(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_dawr0(DisasContext *ctx, int sprn, int gprn);
void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn); void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn);
void spr_write_dawr1(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_write_ureg(DisasContext *ctx, int sprn, int gprn);
void spr_read_purr(DisasContext *ctx, int gprn, int sprn); void spr_read_purr(DisasContext *ctx, int gprn, int sprn);
void spr_write_purr(DisasContext *ctx, int sprn, int gprn); void spr_write_purr(DisasContext *ctx, int sprn, int gprn);

View File

@ -345,15 +345,24 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
{ {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
CPUPPCState *env = cpu_env(cs); CPUPPCState *env = cpu_env(cs);
bool wt, wti, hv, sv, pr;
uint32_t dawrx;
if (env->insns_flags2 & PPC2_ISA207S) { if ((env->insns_flags2 & PPC2_ISA207S) &&
if (wp == env->dawr0_watchpoint) { (wp == env->dawr_watchpoint[0])) {
uint32_t dawrx = env->spr[SPR_DAWRX0]; dawrx = env->spr[SPR_DAWRX0];
bool wt = extract32(dawrx, PPC_BIT_NR(59), 1); } else if ((env->insns_flags2 & PPC2_ISA310) &&
bool wti = extract32(dawrx, PPC_BIT_NR(60), 1); (wp == env->dawr_watchpoint[1])) {
bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); dawrx = env->spr[SPR_DAWRX1];
bool sv = extract32(dawrx, PPC_BIT_NR(62), 1); } else {
bool pr = extract32(dawrx, PPC_BIT_NR(62), 1); return false;
}
wt = extract32(dawrx, PPC_BIT_NR(59), 1);
wti = extract32(dawrx, PPC_BIT_NR(60), 1);
hv = extract32(dawrx, PPC_BIT_NR(61), 1);
sv = extract32(dawrx, PPC_BIT_NR(62), 1);
pr = extract32(dawrx, PPC_BIT_NR(62), 1);
if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) { if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) {
return false; return false;
@ -365,19 +374,13 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
if (!wti) { if (!wti) {
if (env->msr & ((target_ulong)1 << MSR_DR)) { if (env->msr & ((target_ulong)1 << MSR_DR)) {
if (!wt) { return wt;
return false;
}
} else { } else {
if (wt) { return !wt;
return false;
}
} }
} }
return true; return true;
}
}
#endif #endif
return false; return false;

View File

@ -637,6 +637,18 @@ void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn)
translator_io_start(&ctx->base); translator_io_start(&ctx->base);
gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]); gen_helper_store_dawrx0(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_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) */ #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
/* CTR */ /* CTR */