[PATCH 02/13] hw/riscv/trace-encoder.c: add trace ntrace/etrace selection logic
Konstantin Semichastnov <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Selecting trace message format rely on `TraceEncoder->ntrace` flag. This flag mirrors trTeFormat bit. For now only two values supported: - E-Trace (trTeFormat = 0), trace format, described by Efficient trace spec. - N-Trace (trTeFormat = 1), trace format, described by Nexus trace spec. For now we not yet implemented any N-Trace messages, so currently `ntrace` field only disables E-Trace messages competely. We will reuse this field in following commits, when N-Trace messages added. Signed-off-by: Konstantin Semichastnov <[email protected]> --- hw/riscv/trace-encoder.c | 29 +++++++++++++++++++++++++---- target/riscv/trace_helper.c | 8 ++++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/hw/riscv/trace-encoder.c b/hw/riscv/trace-encoder.c index 53345a478c..34c8f60ce1 100644 --- a/hw/riscv/trace-encoder.c +++ b/hw/riscv/trace-encoder.c @@ -254,7 +254,11 @@ static void trencoder_te_ctrl_postw(RegisterInfo *reg, uint64_t val) if (!te->trace_running && trTeInstTracing) { /* Starting trace. Ask the CPU for the first trace insn */ - te->trace_next_insn = true; + if (te->ntrace) { + /* send ProgTraceSync message */ + } else { + te->trace_next_insn = true; + } te->ramsink_ramstart = trencoder_read_ramsink_writep(te); te->ramsink_ramlimit = trencoder_read_ramsink_ramlimit(te); @@ -442,6 +446,8 @@ static void trencoder_send_sync_msg(Object *trencoder_obj, uint64_t pc) uint8_t msg_size; bool is_branch_taken; + g_assert(!trencoder->ntrace); + trencoder->first_pc = pc; is_branch_taken = trencoder_addr_is_branch_taken(trencoder, pc); msg_size = rv_etrace_gen_encoded_sync_msg(msg, pc, priv, @@ -458,6 +464,8 @@ static void trencoder_send_updiscon(TraceEncoder *trencoder, uint64_t pc) bool updiscon = !notify; uint8_t msg_size; + g_assert(!trencoder->ntrace); + if (trencoder->branches > 0) { msg_size = rv_etrace_gen_encoded_format1(format2_msg, trencoder->branches, @@ -485,6 +493,8 @@ void trencoder_set_first_trace_insn(Object *trencoder_obj, uint64_t pc) uint8_t msg_size; bool is_branch_taken; + g_assert(!trencoder->ntrace); + if (trencoder->updiscon_pending) { trencoder_send_updiscon(trencoder, pc); } @@ -508,6 +518,11 @@ void trencoder_trace_trap_insn(Object *trencoder_obj, g_autofree uint8_t *msg = g_malloc0(TRACE_MSG_MAX_SIZE); uint8_t msg_size; + if (trencoder->ntrace) { + /* send IndirectBranchHist message */ + return; + } + if (trencoder->updiscon_pending) { trencoder_send_updiscon(trencoder, pc); } @@ -525,9 +540,15 @@ static void trencoder_send_branch_map(Object *trencoder_obj) g_autofree uint8_t *msg = g_malloc0(TRACE_MSG_MAX_SIZE); uint8_t msg_size; - msg_size = rv_etrace_gen_encoded_format1_noaddr(msg, - te->branches, - te->branch_map); + if (te->ntrace) { + /* send ResourceFull message */ + return; + } else { + msg_size = rv_etrace_gen_encoded_format1_noaddr(msg, + te->branches, + te->branch_map); + } + trencoder_send_message_smem(te, msg, msg_size); } diff --git a/target/riscv/trace_helper.c b/target/riscv/trace_helper.c index cd57641d9b..9b43aeac09 100644 --- a/target/riscv/trace_helper.c +++ b/target/riscv/trace_helper.c @@ -34,8 +34,12 @@ void helper_trace_updiscon(CPURISCVState *env) RISCVCPU *cpu = env_archcpu(env); TraceEncoder *te = TRACE_ENCODER(cpu->trencoder); - te->updiscon_pending = true; - te->trace_next_insn = true; + if (te->ntrace) { + /* send IndirectBranchHist message */ + } else { + te->updiscon_pending = true; + te->trace_next_insn = true; + } } void helper_trace_branch(CPURISCVState *env, target_ulong pc, int taken) -- 2.43.0