[PATCH 13/13] hw/riscv/trace-encoder: refactor register accesses

Konstantin Semichastnov <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Refactor pre-write and post-write trace register accesses.
Remove unused `enabled` flag.

Signed-off-by: Konstantin Semichastnov <[email protected]>
---
 hw/riscv/trace-encoder.c | 79 +++++++++++++++++++++---------------------------
 hw/riscv/trace-encoder.h |  9 +++---
 2 files changed, 39 insertions(+), 49 deletions(-)

diff --git a/hw/riscv/trace-encoder.c b/hw/riscv/trace-encoder.c
index 58ed4b2646..7fd5c3a578 100644
--- a/hw/riscv/trace-encoder.c
+++ b/hw/riscv/trace-encoder.c
@@ -161,6 +161,7 @@ static hwaddr trencoder_read_ramsink_ramlimit(TraceEncoder *te)
 
 static uint64_t trencoder_te_ctrl_set_hardwire_vals(uint64_t input)
 {
+    input = FIELD_DP32(input, TR_TE_CONTROL, EMPTY, 1);
     input = FIELD_DP32(input, TR_TE_CONTROL, INST_MODE, 0x6);
     input = FIELD_DP32(input, TR_TE_CONTROL, CONTEXT, 0);
     input = FIELD_DP32(input, TR_TE_CONTROL, INST_TRIG_ENABLE, 0);
@@ -179,6 +180,7 @@ static uint64_t trencoder_te_ctrl_prew(RegisterInfo *reg, uint64_t val)
 {
     TraceEncoder *te = TRACE_ENCODER(reg->opaque);
     uint32_t trTeActive = ARRAY_FIELD_EX32(te->regs, TR_TE_CONTROL, ACTIVE);
+    uint32_t trTeEnable = ARRAY_FIELD_EX32(te->regs, TR_TE_CONTROL, ENABLE);
     uint32_t trTeInstTracing = ARRAY_FIELD_EX32(te->regs, TR_TE_CONTROL,
                                                 INST_TRACING);
     uint32_t trTeFormat = ARRAY_FIELD_EX32(te->regs, TR_TE_CONTROL, FORMAT);
@@ -187,40 +189,30 @@ static uint64_t trencoder_te_ctrl_prew(RegisterInfo *reg, uint64_t val)
     val = trencoder_te_ctrl_set_hardwire_vals(val);
 
     if (!trTeActive) {
-        /*
-         * 11.2 Reset and discovery, table 58, trTeControl = 0x1
-         * means "Release from reset and set all defaults." Do
-         * that only if trTeActive is 0.
-         */
-        if (val == 0x1) {
-            val = FIELD_DP32(val, TR_TE_CONTROL, EMPTY, 1);
-
-            return val;
-        }
-
         /*
          * 11.3 Enabling and Disabling hints that the device must
          * be activated first (trTeActive = 1), then enabled.
          * Do not enable the device if it's not active
          * beforehand.
          */
-        temp = FIELD_EX32(val, TR_TE_CONTROL, ENABLE);
-        if (temp) {
+        if (FIELD_EX32(val, TR_TE_CONTROL, ENABLE)) {
             val = FIELD_DP32(val, TR_TE_CONTROL, ENABLE, 0);
         }
     }
 
-    /*
-     * Do not allow inst tracing to start if the device isn't
-     * already enabled. Do not allow enabling the devince and
-     * and enable tracing at the same time.
-     */
-    if (!te->enabled && trTeInstTracing) {
-        val = FIELD_DP32(val, TR_TE_CONTROL, INST_TRACING, 0);
+    if (FIELD_EX32(val, TR_TE_CONTROL, INST_TRACING)) {
+        /*
+         * Do not allow inst tracing to start if the device isn't
+         * already enabled. Do not allow enabling the device and
+         * and enable tracing at the same time.
+         */
+        if (!trTeEnable) {
+            val = FIELD_DP32(val, TR_TE_CONTROL, INST_TRACING, 0);
+        }
     }
 
     temp = FIELD_EX32(val, TR_TE_CONTROL, FORMAT);
-    if (te->trace_running) {
+    if (trTeInstTracing) {
         /* Do not allow to change tracing format while tracing is enabled. */
         val = FIELD_DP32(val, TR_TE_CONTROL, FORMAT, trTeFormat);
     } else if (temp != TR_TE_CONTROL_FORMAT_ETRACE &&
@@ -232,6 +224,15 @@ static uint64_t trencoder_te_ctrl_prew(RegisterInfo *reg, uint64_t val)
         val = FIELD_DP32(val, TR_TE_CONTROL, FORMAT, trTeFormat);
     }
 
+    if (!FIELD_EX32(val, TR_TE_CONTROL, ACTIVE)) {
+        /* Disable trace encoder if it becoming not active */
+        val = FIELD_DP32(val, TR_TE_CONTROL, ENABLE, 0);
+    }
+    if (!FIELD_EX32(val, TR_TE_CONTROL, ENABLE)) {
+        /* Disable tracing if trace incoder being disabled */
+        val = FIELD_DP32(val, TR_TE_CONTROL, INST_TRACING, 0);
+    }
+
     return val;
 }
 
@@ -263,35 +264,27 @@ static void trencoder_te_ctrl_postw(RegisterInfo *reg, uint64_t val)
     RISCVCPU *cpu = te->cpu;
     CPURISCVState *env = &cpu->env;
 
+    bool trace_disabled = !trTeActive || !trTeEnable || !trTeInstTracing;
 
-    if (te->ntrace && te->enabled) {
-        if (!trTeActive || !trTeEnable || !trTeInstTracing) {
-            uint32_t inst_len = get_inst_len_at(env->pc);
+    if (te->trace_running && trace_disabled) {
+        /* Stopping trace. */
+        /* TODO: this should cause a pending trace data flush. */
+        te->trace_next_insn = false;
 
+        if (te->ntrace) {
+            uint32_t inst_len = get_inst_len_at(env->pc);
             trencoder_send_prog_trace_correlation(OBJECT(te), env->pc, inst_len,
                                                   CORRELATION_TRACE_DISABLED);
         }
     }
 
-    if (!trTeActive) {
-        te->enabled = false;
-        te->trace_running = false;
-        te->trace_next_insn = false;
-
-        env->trace_running = false;
-        return;
-    }
-
-    if (te->enabled && !trTeEnable) {
-        /* TODO: this should cause a pending trace data flush. */
-    }
-
-    te->enabled = trTeEnable ? true : false;
-
     te->ntrace = (trTeFormat == TR_TE_CONTROL_FORMAT_NTRACE);
 
     if (!te->trace_running && trTeInstTracing) {
         /* Starting trace. Ask the CPU for the first trace insn */
+        te->ramsink_ramstart = trencoder_read_ramsink_writep(te);
+        te->ramsink_ramlimit = trencoder_read_ramsink_ramlimit(te);
+
         if (te->ntrace) {
             /*
              * N-Trace require to trace from very first instruction,
@@ -305,13 +298,10 @@ static void trencoder_te_ctrl_postw(RegisterInfo *reg, uint64_t val)
         } else {
             te->trace_next_insn = true;
         }
-
-        te->ramsink_ramstart = trencoder_read_ramsink_writep(te);
-        te->ramsink_ramlimit = trencoder_read_ramsink_ramlimit(te);
     }
 
-    te->trace_running = trTeInstTracing ? true : false;
-    env->trace_running = te->trace_running;
+    te->trace_running = trTeInstTracing;
+    env->trace_running = trTeInstTracing;
 }
 
 static RegisterAccessInfo trencoder_regs_info[] = {
@@ -380,7 +370,6 @@ static void trencoder_reset(DeviceState *dev)
         register_reset(&te->regs_info[i]);
     }
 
-    te->enabled = false;
     te->trace_running = false;
     te->trace_next_insn = false;
     te->ntrace = false;
diff --git a/hw/riscv/trace-encoder.h b/hw/riscv/trace-encoder.h
index 55d53c2582..b3cdbf9374 100644
--- a/hw/riscv/trace-encoder.h
+++ b/hw/riscv/trace-encoder.h
@@ -39,13 +39,14 @@ struct TraceEncoder {
     uint32_t regs[TRACE_R_MAX];
     RegisterInfo regs_info[TRACE_R_MAX];
 
-    bool updiscon_pending;
-
-    bool enabled;
+    bool ntrace;
     bool trace_running;
+
+    /* etrace specific */
+    bool updiscon_pending;
     bool trace_next_insn;
 
-    bool ntrace;
+    /* ntrace specific */
     uint64_t last_addr_reported;
     uint64_t last_icnt_reset;
     uint64_t icnt_accumulated;

-- 
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.