[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 1/2] ppc/pnv: Add new PowerPC Special Purpose Registers (DAWR1
From: |
dan tan |
Subject: |
[PATCH v2 1/2] ppc/pnv: Add new PowerPC Special Purpose Registers (DAWR1, DAWRX1) |
Date: |
Thu, 2 Jan 2025 21:21:11 -0600 |
The handling of the following two registers are added to POWER10 -
- DAWR1 (0x0bd, 189) - Data Address Watchpoint 1
- DAWRX1 (0x0b5, 181) - Data Address Watchpoint Extension 1
Signed-off-by: dan tan <dantan@linux.vnet.ibm.com>
---
ver 2 summary:
- spec reference: https://files.openpower.foundation/s/EgCy7C43p2NSRfR
- corrected commit message format
- combine DAWR(0/1) handling into a single function
- add DAWR1 & DAWRX1 to init_proc_POWER10() only.
---
include/hw/ppc/spapr.h | 2 +-
target/ppc/cpu.h | 7 ++--
target/ppc/helper.h | 4 +--
target/ppc/spr_common.h | 2 ++
hw/ppc/spapr_hcall.c | 24 ++++++++------
target/ppc/cpu.c | 69 ++++++++++++++++++++++++++--------------
target/ppc/cpu_init.c | 15 +++++++++
target/ppc/excp_helper.c | 11 ++++++-
target/ppc/machine.c | 5 ++-
target/ppc/misc_helper.c | 8 ++---
target/ppc/translate.c | 21 ++++++++++--
11 files changed, 121 insertions(+), 47 deletions(-)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index af4aa1cb0f..8282136745 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -403,7 +403,7 @@ struct SpaprMachineState {
/* Values for 2nd argument to H_SET_MODE */
#define H_SET_MODE_RESOURCE_SET_CIABR 1
-#define H_SET_MODE_RESOURCE_SET_DAWR0 2
+#define H_SET_MODE_RESOURCE_SET_DAWR 2
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
#define H_SET_MODE_RESOURCE_LE 4
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2ffac2ed03..6d074e67dc 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1261,6 +1261,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 */
@@ -1587,9 +1588,9 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val);
void ppc_update_ciabr(CPUPPCState *env);
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_daw(CPUPPCState *env, uint32_t daw);
+void ppc_store_dawr(CPUPPCState *env, target_ulong value, uint32_t dawr);
+void ppc_store_dawrx(CPUPPCState *env, uint32_t value, uint32_t dawrx);
#endif /* !defined(CONFIG_USER_ONLY) */
void ppc_store_msr(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 5a77e761bd..28d6bf1bde 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -26,8 +26,8 @@ DEF_HELPER_2(rfebb, void, env, tl)
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_dawrx0, void, env, tl)
+DEF_HELPER_3(store_dawr, void, env, tl, i32)
+DEF_HELPER_3(store_dawrx, void, env, tl, i32)
DEF_HELPER_2(store_mmcr0, void, env, tl)
DEF_HELPER_2(store_mmcr1, void, env, tl)
DEF_HELPER_2(store_mmcrA, void, env, tl)
diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h
index 01aff449bc..ff67139ec1 100644
--- a/target/ppc/spr_common.h
+++ b/target/ppc/spr_common.h
@@ -164,7 +164,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/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 5e1d020e3d..e693e950a7 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -818,11 +818,11 @@ static target_ulong
h_set_mode_resource_set_ciabr(PowerPCCPU *cpu,
return H_SUCCESS;
}
-static target_ulong h_set_mode_resource_set_dawr0(PowerPCCPU *cpu,
- SpaprMachineState *spapr,
- target_ulong mflags,
- target_ulong value1,
- target_ulong value2)
+static target_ulong h_set_mode_resource_set_dawr(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ target_ulong mflags,
+ target_ulong value1,
+ target_ulong value2)
{
CPUPPCState *env = &cpu->env;
@@ -835,8 +835,12 @@ static target_ulong
h_set_mode_resource_set_dawr0(PowerPCCPU *cpu,
return H_P4;
}
- ppc_store_dawr0(env, value1);
- ppc_store_dawrx0(env, value2);
+ ppc_store_dawr(env, value1, SPR_DAWR0);
+ ppc_store_dawrx(env, value2, SPR_DAWRX0);
+ if (env->excp_model > POWERPC_EXCP_POWER10) {
+ ppc_store_dawr(env, value1, SPR_DAWR1);
+ ppc_store_dawrx(env, value2, SPR_DAWRX1);
+ }
return H_SUCCESS;
}
@@ -914,9 +918,9 @@ static target_ulong h_set_mode(PowerPCCPU *cpu,
SpaprMachineState *spapr,
ret = h_set_mode_resource_set_ciabr(cpu, spapr, args[0], args[2],
args[3]);
break;
- case H_SET_MODE_RESOURCE_SET_DAWR0:
- ret = h_set_mode_resource_set_dawr0(cpu, spapr, args[0], args[2],
- args[3]);
+ case H_SET_MODE_RESOURCE_SET_DAWR:
+ ret = h_set_mode_resource_set_dawr(cpu, spapr, args[0], args[2],
+ args[3]);
break;
case H_SET_MODE_RESOURCE_LE:
ret = h_set_mode_resource_le(cpu, spapr, args[0], args[2], args[3]);
diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
index e3ad8e0c27..d6a58b5497 100644
--- a/target/ppc/cpu.c
+++ b/target/ppc/cpu.c
@@ -130,23 +130,45 @@ void ppc_store_ciabr(CPUPPCState *env, target_ulong val)
ppc_update_ciabr(env);
}
-void ppc_update_daw0(CPUPPCState *env)
+void ppc_update_daw(CPUPPCState *env, uint32_t spr_daw)
{
CPUState *cs = env_cpu(env);
- target_ulong deaw = env->spr[SPR_DAWR0] & PPC_BITMASK(0, 60);
- uint32_t dawrx = env->spr[SPR_DAWRX0];
- 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);
+ struct CPUWatchpoint **dawr_watchpt;
+ target_ulong deaw;
+ uint32_t dawrx;
+ int mrd, flags;
+ bool dw, dr, hv, sv, pr;
vaddr len;
- int flags;
- if (env->dawr0_watchpoint) {
- cpu_watchpoint_remove_by_ref(cs, env->dawr0_watchpoint);
- env->dawr0_watchpoint = NULL;
+ switch (spr_daw) {
+ case SPR_DAWR0:
+ case SPR_DAWRX0:
+ dawr_watchpt = &env->dawr0_watchpoint;
+ deaw = env->spr[SPR_DAWR0] & PPC_BITMASK(0, 60);
+ dawrx = env->spr[SPR_DAWRX0];
+ break;
+
+ case SPR_DAWR1:
+ case SPR_DAWRX1:
+ dawr_watchpt = &env->dawr1_watchpoint;
+ deaw = env->spr[SPR_DAWR1] & PPC_BITMASK(0, 60);
+ dawrx = env->spr[SPR_DAWRX1];
+ break;
+ default:
+ dawrx = 0;
+ *dawr_watchpt = NULL;
+ break;
+ }
+ mrd = extract32(dawrx, PPC_BIT_NR(48), 54 - 48);
+ dw = extract32(dawrx, PPC_BIT_NR(57), 1);
+ dr = extract32(dawrx, PPC_BIT_NR(58), 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 (*dawr_watchpt) {
+ cpu_watchpoint_remove_by_ref(cs, *dawr_watchpt);
+ *dawr_watchpt = NULL;
}
if (!dr && !dw) {
@@ -166,30 +188,31 @@ void ppc_update_daw0(CPUPPCState *env)
flags |= BP_MEM_WRITE;
}
- cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr0_watchpoint);
+ cpu_watchpoint_insert(cs, deaw, len, flags, dawr_watchpt);
}
-void ppc_store_dawr0(CPUPPCState *env, target_ulong val)
+void ppc_store_dawr(CPUPPCState *env, target_ulong val, uint32_t dawr)
{
- env->spr[SPR_DAWR0] = val;
- ppc_update_daw0(env);
+ env->spr[dawr] = val;
+ ppc_update_daw(env, dawr);
}
-void ppc_store_dawrx0(CPUPPCState *env, uint32_t val)
+void ppc_store_dawrx(CPUPPCState *env, uint32_t val, uint32_t dawrx)
{
int hrammc = extract32(val, PPC_BIT_NR(56), 1);
if (hrammc) {
/* 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[HRAMMC] is unimplemented\n",
__func__);
}
- env->spr[SPR_DAWRX0] = val;
- ppc_update_daw0(env);
+ env->spr[dawrx] = val;
+ ppc_update_daw(env, dawrx);
}
-#endif
-#endif
+
+#endif /* TARGET_PPC64 */
+#endif /* !CONFIG_USER_ONLY */
static inline void fpscr_set_rounding_mode(CPUPPCState *env)
{
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 1253dbf622..7844e16ea5 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5910,6 +5910,20 @@ static void register_power10_dexcr_sprs(CPUPPCState *env)
0);
}
+static void register_power10_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_DAWR, 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);
+}
+
/*
* Initialize PMU counter overflow timers for Power8 and
* newer Power chips when using TCG.
@@ -6568,6 +6582,7 @@ static void init_proc_POWER10(CPUPPCState *env)
{
register_power9_common_sprs(env);
register_HEIR64_spr(env);
+ register_power10_dbg_sprs(env);
register_power10_hash_sprs(env);
register_power10_dexcr_sprs(env);
register_power10_pmu_sup_sprs(env);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 9f811af0a4..9512525e52 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -3279,10 +3279,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/machine.c b/target/ppc/machine.c
index 717bf93e88..4c510e6fed 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -264,7 +264,10 @@ static int cpu_post_load(void *opaque, int version_id)
/* Re-set breaks based on regs */
#if defined(TARGET_PPC64)
ppc_update_ciabr(env);
- ppc_update_daw0(env);
+ ppc_update_daw(env, SPR_DAWR0);
+ if (env->excp_model > POWERPC_EXCP_POWER10) {
+ ppc_update_daw(env, SPR_DAWR1);
+ }
#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 f0ca80153b..1bebb5a8a7 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -223,14 +223,14 @@ void helper_store_ciabr(CPUPPCState *env, target_ulong
value)
ppc_store_ciabr(env, value);
}
-void helper_store_dawr0(CPUPPCState *env, target_ulong value)
+void helper_store_dawr(CPUPPCState *env, target_ulong value, uint32_t dawr)
{
- ppc_store_dawr0(env, value);
+ ppc_store_dawr(env, value, dawr);
}
-void helper_store_dawrx0(CPUPPCState *env, target_ulong value)
+void helper_store_dawrx(CPUPPCState *env, target_ulong value, uint32_t dawrx)
{
- ppc_store_dawrx0(env, value);
+ ppc_store_dawrx(env, value, dawrx);
}
/*
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 47ca50a064..0187b5ab2f 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -628,14 +628,31 @@ void spr_write_ciabr(DisasContext *ctx, int sprn, int
gprn)
void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn)
{
translator_io_start(&ctx->base);
- gen_helper_store_dawr0(tcg_env, cpu_gpr[gprn]);
+ gen_helper_store_dawr(tcg_env, cpu_gpr[gprn],
+ tcg_constant_i32(SPR_DAWR0));
}
void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn)
{
translator_io_start(&ctx->base);
- gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]);
+ gen_helper_store_dawrx(tcg_env, cpu_gpr[gprn],
+ tcg_constant_i32(SPR_DAWRX0));
}
+
+void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn)
+{
+ translator_io_start(&ctx->base);
+ gen_helper_store_dawr(tcg_env, cpu_gpr[gprn],
+ tcg_constant_i32(SPR_DAWR1));
+}
+
+void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn)
+{
+ translator_io_start(&ctx->base);
+ gen_helper_store_dawrx(tcg_env, cpu_gpr[gprn],
+ tcg_constant_i32(SPR_DAWRX1));
+}
+
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
/* CTR */
--
2.39.5