qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 1/2] ppc/pnv: Add new PowerPC Special Purpose Registers (DAWR1


From: dan tan
Subject: [PATCH v3 1/2] ppc/pnv: Add new PowerPC Special Purpose Registers (DAWR1, DAWRX1)
Date: Tue, 7 Jan 2025 14:51:01 -0600

From: dan tan <dantan@linux.ibm.com>

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 3 no change

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]