@@ -32,6 +32,7 @@ DEF_HELPER_2(read_pmc, tl, env, i32)
DEF_HELPER_2(insns_inc, void, env, i32)
DEF_HELPER_1(handle_pmc5_overflow, void, env)
#endif
+DEF_HELPER_2(book3s_trace, void, env, tl)
DEF_HELPER_1(check_tlb_flush_local, void, env)
DEF_HELPER_1(check_tlb_flush_global, void, env)
#endif
@@ -1571,9 +1571,11 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
}
}
break;
+ case POWERPC_EXCP_TRACE: /* Trace exception */
+ msr |= env->error_code;
+ /* fall through */
case POWERPC_EXCP_DSEG: /* Data segment exception */
case POWERPC_EXCP_ISEG: /* Instruction segment exception */
- case POWERPC_EXCP_TRACE: /* Trace exception */
case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */
case POWERPC_EXCP_PERFM: /* Performance monitor interrupt */
break;
@@ -3168,6 +3170,18 @@ void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
}
#endif /* TARGET_PPC64 */
+/* Single-step tracing */
+void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip)
+{
+ uint32_t error_code = 0;
+ if (env->insns_flags2 & PPC2_ISA207S) {
+ /* Load/store reporting, SRR1[35, 36] and SDAR, are not implemented. */
+ env->spr[SPR_POWER_SIAR] = prev_ip;
+ error_code = PPC_BIT(33);
+ }
+ raise_exception_err(env, POWERPC_EXCP_TRACE, error_code);
+}
+
void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr)
@@ -338,8 +338,9 @@ static void gen_ppc_maybe_interrupt(DisasContext *ctx)
* The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or
* POWERPC_EXCP_DEBUG (on BookE).
*/
-static uint32_t gen_prep_dbgex(DisasContext *ctx)
+static void gen_debug_exception(DisasContext *ctx)
{
+#if !defined(CONFIG_USER_ONLY)
if (ctx->flags & POWERPC_FLAG_DE) {
target_ulong dbsr = 0;
if (ctx->singlestep_enabled & CPU_SINGLE_STEP) {
@@ -352,16 +353,16 @@ static uint32_t gen_prep_dbgex(DisasContext *ctx)
gen_load_spr(t0, SPR_BOOKE_DBSR);
tcg_gen_ori_tl(t0, t0, dbsr);
gen_store_spr(SPR_BOOKE_DBSR, t0);
- return POWERPC_EXCP_DEBUG;
+ gen_helper_raise_exception(cpu_env,
+ tcg_constant_i32(POWERPC_EXCP_DEBUG));
+ ctx->base.is_jmp = DISAS_NORETURN;
} else {
- return POWERPC_EXCP_TRACE;
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_movi_tl(t0, ctx->cia);
+ gen_helper_book3s_trace(cpu_env, t0);
+ ctx->base.is_jmp = DISAS_NORETURN;
}
-}
-
-static void gen_debug_exception(DisasContext *ctx)
-{
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
- ctx->base.is_jmp = DISAS_NORETURN;
+#endif
}
static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
@@ -4184,7 +4185,7 @@ static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
static void gen_lookup_and_goto_ptr(DisasContext *ctx)
{
if (unlikely(ctx->singlestep_enabled)) {
- gen_debug_exception(ctx);
+ gen_debug_exception(ctx, false);
} else {
/*
* tcg_gen_lookup_and_goto_ptr will exit the TB if