[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.