Use the rv_etrace_gen_encoded_trap_msg() helper we added in the previous patch to encode trap packets to be written in the RAM sink SMEM.
Signed-off-by: Daniel Henrique Barboza <[email protected]> --- hw/riscv/trace-encoder.c | 17 +++++++++++++++++ hw/riscv/trace-encoder.h | 4 ++++ target/riscv/cpu_helper.c | 13 +++++++++++++ 3 files changed, 34 insertions(+) diff --git a/hw/riscv/trace-encoder.c b/hw/riscv/trace-encoder.c index 16c9475d46..0750bd22b5 100644 --- a/hw/riscv/trace-encoder.c +++ b/hw/riscv/trace-encoder.c @@ -403,6 +403,23 @@ void trencoder_set_first_trace_insn(Object *trencoder_obj, uint64_t pc) trencoder_send_message_smem(trencoder, msg, msg_size); } +void trencoder_trace_trap_insn(Object *trencoder_obj, + uint64_t pc, uint32_t ecause, + bool is_interrupt, + uint64_t tval) +{ + TraceEncoder *trencoder = TRACE_ENCODER(trencoder_obj); + TracePrivLevel priv = trencoder_get_curr_priv_level(trencoder); + g_autofree uint8_t *msg = g_malloc0(TRACE_MSG_MAX_SIZE); + uint8_t msg_size; + + msg_size = rv_etrace_gen_encoded_trap_msg(msg, pc, priv, + ecause, is_interrupt, + tval); + + trencoder_send_message_smem(trencoder, msg, msg_size); +} + static const Property trencoder_props[] = { /* * We need a link to the associated CPU to diff --git a/hw/riscv/trace-encoder.h b/hw/riscv/trace-encoder.h index cf3177aefe..4898026f2b 100644 --- a/hw/riscv/trace-encoder.h +++ b/hw/riscv/trace-encoder.h @@ -46,5 +46,9 @@ struct TraceEncoder { OBJECT_DECLARE_SIMPLE_TYPE(TraceEncoder, TRACE_ENCODER) void trencoder_set_first_trace_insn(Object *trencoder_obj, uint64_t pc); +void trencoder_trace_trap_insn(Object *trencoder_obj, + uint64_t pc, uint32_t ecause, + bool is_interrupt, + uint64_t tval); #endif diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index c4fb68b5de..f2990cf7c4 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -38,6 +38,10 @@ #include "pmp.h" #include "qemu/plugin.h" +#ifndef CONFIG_USER_ONLY +#include "hw/riscv/trace-encoder.h" +#endif + int riscv_env_mmu_index(CPURISCVState *env, bool ifetch) { #ifdef CONFIG_USER_ONLY @@ -2285,6 +2289,15 @@ void riscv_cpu_do_interrupt(CPUState *cs) __func__, env->mhartid, async, cause, env->pc, tval, riscv_cpu_get_trap_name(cause, async)); + if (cpu->trencoder) { + TraceEncoder *te = TRACE_ENCODER(cpu->trencoder); + + if (te->trace_running) { + trencoder_trace_trap_insn(cpu->trencoder, env->pc, + cause, async, tval); + } + } + mode = env->priv <= PRV_S && cause < 64 && (((deleg >> cause) & 1) || s_injected || vs_injected) ? PRV_S : PRV_M; -- 2.51.1
