@@ -262,7 +262,7 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
/* 54: DecFP, 56: DecI, 58: SHA */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
- /* 60: NM atomic, 62: RNG */
+ /* 60: NM atomic, 62: RNG, 64: DAWR1 (ISA 3.1) */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
};
uint8_t *pa_features = NULL;
@@ -303,6 +303,9 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
* in pa-features. So hide it from them. */
pa_features[40 + 2] &= ~0x80; /* Radix MMU */
}
+ if (spapr_get_cap(spapr, SPAPR_CAP_DAWR1)) {
+ pa_features[66] |= 0x80;
+ }
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
}
@@ -2138,6 +2141,7 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_cap_fwnmi,
&vmstate_spapr_fwnmi,
&vmstate_spapr_cap_rpt_invalidate,
+ &vmstate_spapr_cap_dawr1,
NULL
}
};
@@ -4717,6 +4721,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_RPT_INVALIDATE] = SPAPR_CAP_OFF;
+ smc->default_caps.caps[SPAPR_CAP_DAWR1] = SPAPR_CAP_OFF;
/*
* This cap specifies whether the AIL 3 mode for
@@ -655,6 +655,31 @@ static void cap_ail_mode_3_apply(SpaprMachineState *spapr,
}
}
+static void cap_dawr1_apply(SpaprMachineState *spapr, uint8_t val,
+ Error **errp)
+{
+ ERRP_GUARD();
+
+ if (!val) {
+ return; /* Disable by default */
+ }
+
+ if (!ppc_type_check_compat(MACHINE(spapr)->cpu_type, CPU_POWERPC_LOGICAL_3_10,
+ 0, spapr->max_compat_pvr)) {
+ warn_report("DAWR1 supported only on POWER10 and later CPUs");
+ }
+
+ if (kvm_enabled()) {
+ if (!kvmppc_has_cap_dawr1()) {
+ error_setg(errp, "DAWR1 not supported by KVM.");
+ error_append_hint(errp, "Try appending -machine cap-dawr1=off");
+ } else if (kvmppc_set_cap_dawr1(val) < 0) {
+ error_setg(errp, "Error enabling cap-dawr1 with KVM.");
+ error_append_hint(errp, "Try appending -machine cap-dawr1=off");
+ }
+ }
+}
+
SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_HTM] = {
.name = "htm",
@@ -781,6 +806,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
.type = "bool",
.apply = cap_ail_mode_3_apply,
},
+ [SPAPR_CAP_DAWR1] = {
+ .name = "dawr1",
+ .description = "Allow 2nd Data Address Watchpoint Register (DAWR1)",
+ .index = SPAPR_CAP_DAWR1,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_dawr1_apply,
+ },
};
static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
@@ -923,6 +957,7 @@ SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);
SPAPR_CAP_MIG_STATE(rpt_invalidate, SPAPR_CAP_RPT_INVALIDATE);
+SPAPR_CAP_MIG_STATE(dawr1, SPAPR_CAP_DAWR1);
void spapr_caps_init(SpaprMachineState *spapr)
{
@@ -815,29 +815,33 @@ 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)
-{
- CPUPPCState *env = &cpu->env;
-
- assert(tcg_enabled()); /* KVM will have handled this */
-
- if (mflags) {
- return H_UNSUPPORTED_FLAG;
- }
- if (value2 & PPC_BIT(61)) {
- return H_P4;
- }
-
- ppc_store_dawr0(env, value1);
- ppc_store_dawrx0(env, value2);
-
- return H_SUCCESS;
+#define DEF_H_SET_MODE_RESOURCE_SET_DAWR(id) \
+static target_ulong h_set_mode_resource_set_dawr##id(PowerPCCPU *cpu, \
+ SpaprMachineState *spapr,\
+ target_ulong mflags, \
+ target_ulong value1, \
+ target_ulong value2) \
+{ \
+ CPUPPCState *env = &cpu->env; \
+ \
+ assert(tcg_enabled()); /* KVM will have handled this */ \
+ \
+ if (mflags) { \
+ return H_UNSUPPORTED_FLAG; \
+ } \
+ if (value2 & PPC_BIT(61)) { \
+ return H_P4; \
+ } \
+ \
+ ppc_store_dawr##id(env, value1); \
+ ppc_store_dawrx##id(env, value2); \
+ \
+ return H_SUCCESS; \
}
+DEF_H_SET_MODE_RESOURCE_SET_DAWR(0)
+DEF_H_SET_MODE_RESOURCE_SET_DAWR(1)
+
static target_ulong h_set_mode_resource_le(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong mflags,
@@ -915,6 +919,10 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr,
ret = h_set_mode_resource_set_dawr0(cpu, spapr, args[0], args[2],
args[3]);
break;
+ case H_SET_MODE_RESOURCE_SET_DAWR1:
+ ret = h_set_mode_resource_set_dawr1(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]);
break;
@@ -80,8 +80,10 @@ typedef enum {
#define SPAPR_CAP_RPT_INVALIDATE 0x0B
/* Support for AIL modes */
#define SPAPR_CAP_AIL_MODE_3 0x0C
+/* DAWR1 */
+#define SPAPR_CAP_DAWR1 0x0D
/* Num Caps */
-#define SPAPR_CAP_NUM (SPAPR_CAP_AIL_MODE_3 + 1)
+#define SPAPR_CAP_NUM (SPAPR_CAP_DAWR1 + 1)
/*
* Capability Values
@@ -403,6 +405,7 @@ struct SpaprMachineState {
#define H_SET_MODE_RESOURCE_SET_DAWR0 2
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
#define H_SET_MODE_RESOURCE_LE 4
+#define H_SET_MODE_RESOURCE_SET_DAWR1 5
/* Flags for H_SET_MODE_RESOURCE_LE */
#define H_SET_MODE_ENDIAN_BIG 0
@@ -986,6 +989,7 @@ extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
extern const VMStateDescription vmstate_spapr_cap_fwnmi;
extern const VMStateDescription vmstate_spapr_cap_rpt_invalidate;
extern const VMStateDescription vmstate_spapr_wdt;
+extern const VMStateDescription vmstate_spapr_cap_dawr1;
static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap)
{
@@ -130,64 +130,76 @@ void ppc_store_ciabr(CPUPPCState *env, target_ulong val)
ppc_update_ciabr(env);
}
-void ppc_update_daw0(CPUPPCState *env)
-{
- 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);
- vaddr len;
- int flags;
-
- if (env->dawr0_watchpoint) {
- cpu_watchpoint_remove_by_ref(cs, env->dawr0_watchpoint);
- env->dawr0_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;
- }
+#define DEF_PPC_UPDATE_DAW(id) \
+void ppc_update_daw##id(CPUPPCState *env) \
+{ \
+ CPUState *cs = env_cpu(env); \
+ target_ulong deaw = env->spr[SPR_DAWR##id] & PPC_BITMASK(0, 60); \
+ uint32_t dawrx = env->spr[SPR_DAWRX##id]; \
+ 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->dawr##id##_watchpoint) { \
+ cpu_watchpoint_remove_by_ref(cs, env->dawr##id##_watchpoint); \
+ env->dawr##id##_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->dawr##id##_watchpoint); \
+}
- cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr0_watchpoint);
+#define DEF_PPC_STORE_DAWR(id) \
+void ppc_store_dawr##id(CPUPPCState *env, target_ulong val) \
+{ \
+ env->spr[SPR_DAWR##id] = val; \
+ ppc_update_daw##id(env); \
}
-void ppc_store_dawr0(CPUPPCState *env, target_ulong val)
-{
- env->spr[SPR_DAWR0] = val;
- ppc_update_daw0(env);
+#define DEF_PPC_STORE_DAWRX(id) \
+void ppc_store_dawrx##id(CPUPPCState *env, uint32_t val) \
+{ \
+ int hrammc = extract32(val, PPC_BIT_NR(56), 1); \
+ \
+ if (hrammc) { \
+ /* This might be done with a 2nd watchpoint at the xor of DEAW[0] */ \
+ qemu_log_mask(LOG_UNIMP, "%s: DAWRX##id[HRAMMC] is unimplemented\n", \
+ __func__); \
+ } \
+ \
+ env->spr[SPR_DAWRX##id] = val; \
+ ppc_update_daw##id(env); \
}
-void ppc_store_dawrx0(CPUPPCState *env, uint32_t val)
-{
- int hrammc = extract32(val, PPC_BIT_NR(56), 1);
+DEF_PPC_UPDATE_DAW(0)
+DEF_PPC_STORE_DAWR(0)
+DEF_PPC_STORE_DAWRX(0)
- 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",
- __func__);
- }
+DEF_PPC_UPDATE_DAW(1)
+DEF_PPC_STORE_DAWR(1)
+DEF_PPC_STORE_DAWRX(1)
- env->spr[SPR_DAWRX0] = val;
- ppc_update_daw0(env);
-}
#endif
#endif
@@ -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)
@@ -5131,6 +5131,20 @@ static void register_book3s_207_dbg_sprs(CPUPPCState *env)
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)
{
/* Breakpoints */
@@ -6473,6 +6487,7 @@ static void init_proc_POWER10(CPUPPCState *env)
/* Common Registers */
init_proc_book3s_common(env);
register_book3s_207_dbg_sprs(env);
+ register_book3s_310_dbg_sprs(env);
/* Common TCG PMU */
init_tcg_pmu_power8(env);
@@ -3314,39 +3314,46 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
{
#if defined(TARGET_PPC64)
CPUPPCState *env = cpu_env(cs);
+ bool wt, wti, hv, sv, pr;
+ uint32_t dawrx;
+
+ if ((env->insns_flags2 & PPC2_ISA207S) &&
+ (wp == env->dawr0_watchpoint)) {
+ dawrx = env->spr[SPR_DAWRX0];
+ } else if ((env->insns_flags2 & PPC2_ISA310) &&
+ (wp == env->dawr1_watchpoint)) {
+ dawrx = env->spr[SPR_DAWRX1];
+ } else {
+ return false;
+ }
- if (env->insns_flags2 & PPC2_ISA207S) {
- if (wp == env->dawr0_watchpoint) {
- uint32_t dawrx = env->spr[SPR_DAWRX0];
- 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);
- bool sv = extract32(dawrx, PPC_BIT_NR(62), 1);
- bool pr = extract32(dawrx, PPC_BIT_NR(62), 1);
-
- if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) {
- return false;
- } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) {
- return false;
- } else if (!sv) {
+ 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) {
+ return false;
+ } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) {
+ return false;
+ } else if (!sv) {
+ return false;
+ }
+
+ if (!wti) {
+ if (env->msr & ((target_ulong)1 << MSR_DR)) {
+ if (!wt) {
return false;
}
-
- if (!wti) {
- if (env->msr & ((target_ulong)1 << MSR_DR)) {
- if (!wt) {
- return false;
- }
- } else {
- if (wt) {
- return false;
- }
- }
+ } else {
+ if (wt) {
+ return false;
}
-
- return true;
}
}
+
+ return true;
#endif
return false;
@@ -28,6 +28,8 @@ 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_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_mmcr1, void, env, tl)
DEF_HELPER_3(store_pmc, void, env, i32, i64)
@@ -89,6 +89,7 @@ static int cap_large_decr;
static int cap_fwnmi;
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
+static int cap_dawr1;
static uint32_t debug_inst_opcode;
@@ -143,6 +144,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
cap_large_decr = kvmppc_get_dec_bits();
cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI);
+ cap_dawr1 = kvm_vm_check_extension(s, KVM_CAP_PPC_DAWR1);
/*
* Note: setting it to false because there is not such capability
* in KVM at this moment.
@@ -2109,6 +2111,16 @@ int kvmppc_set_fwnmi(PowerPCCPU *cpu)
return kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_FWNMI, 0);
}
+bool kvmppc_has_cap_dawr1(void)
+{
+ return !!cap_dawr1;
+}
+
+int kvmppc_set_cap_dawr1(int enable)
+{
+ return kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_DAWR1, 0, enable);
+}
+
int kvmppc_smt_threads(void)
{
return cap_ppc_smt ? cap_ppc_smt : 1;
@@ -68,6 +68,8 @@ bool kvmppc_has_cap_htm(void);
bool kvmppc_has_cap_mmu_radix(void);
bool kvmppc_has_cap_mmu_hash_v3(void);
bool kvmppc_has_cap_xive(void);
+bool kvmppc_has_cap_dawr1(void);
+int kvmppc_set_cap_dawr1(int enable);
int kvmppc_get_cap_safe_cache(void);
int kvmppc_get_cap_safe_bounds_check(void);
int kvmppc_get_cap_safe_indirect_branch(void);
@@ -377,6 +379,16 @@ static inline bool kvmppc_has_cap_xive(void)
return false;
}
+static inline bool kvmppc_has_cap_dawr1(void)
+{
+ return false;
+}
+
+static inline int kvmppc_set_cap_dawr1(int enable)
+{
+ abort();
+}
+
static inline int kvmppc_get_cap_safe_cache(void)
{
return 0;
@@ -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
@@ -204,16 +204,24 @@ void helper_store_ciabr(CPUPPCState *env, target_ulong value)
ppc_store_ciabr(env, value);
}
-void helper_store_dawr0(CPUPPCState *env, target_ulong value)
-{
- ppc_store_dawr0(env, value);
+#define HELPER_STORE_DAWR(id) \
+void helper_store_dawr##id(CPUPPCState *env, target_ulong value) \
+{ \
+ env->spr[SPR_DAWR##id] = value; \
}
-void helper_store_dawrx0(CPUPPCState *env, target_ulong value)
-{
- ppc_store_dawrx0(env, value);
+#define HELPER_STORE_DAWRX(id) \
+void helper_store_dawrx##id(CPUPPCState *env, target_ulong value) \
+{ \
+ env->spr[SPR_DAWRX##id] = value; \
}
+HELPER_STORE_DAWR(0)
+HELPER_STORE_DAWRX(0)
+
+HELPER_STORE_DAWR(1)
+HELPER_STORE_DAWRX(1)
+
/*
* DPDES register is shared. Each bit reflects the state of the
* doorbell interrupt of a thread of the same core.
@@ -162,6 +162,8 @@ 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_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_read_purr(DisasContext *ctx, int gprn, int sprn);
void spr_write_purr(DisasContext *ctx, int sprn, int gprn);
@@ -582,17 +582,26 @@ void spr_write_ciabr(DisasContext *ctx, int sprn, int gprn)
}
/* Watchpoint */
-void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn)
-{
- translator_io_start(&ctx->base);
- gen_helper_store_dawr0(tcg_env, cpu_gpr[gprn]);
+#define SPR_WRITE_DAWR(id) \
+void spr_write_dawr##id(DisasContext *ctx, int sprn, int gprn) \
+{ \
+ translator_io_start(&ctx->base); \
+ gen_helper_store_dawr##id(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]);
+#define SPR_WRITE_DAWRX(id) \
+void spr_write_dawrx##id(DisasContext *ctx, int sprn, int gprn) \
+{ \
+ translator_io_start(&ctx->base); \
+ gen_helper_store_dawrx##id(tcg_env, cpu_gpr[gprn]); \
}
+
+SPR_WRITE_DAWR(0)
+SPR_WRITE_DAWRX(0)
+
+SPR_WRITE_DAWR(1)
+SPR_WRITE_DAWRX(1)
+
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
/* CTR */