Add generation, encoding and sending logic for N-Trace ResourceFull
message.

Signed-off-by: Konstantin Semichastnov <[email protected]>
---
 hw/riscv/rv-trace-messages.c | 29 +++++++++++++++++++++++++++++
 hw/riscv/rv-trace-messages.h |  1 +
 hw/riscv/trace-encoder.c     |  5 +++--
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/rv-trace-messages.c b/hw/riscv/rv-trace-messages.c
index 2ee38c4354..8a9a3c6955 100644
--- a/hw/riscv/rv-trace-messages.c
+++ b/hw/riscv/rv-trace-messages.c
@@ -359,10 +359,12 @@ typedef enum {
     WIDTH_FADDR  = 63,
     WIDTH_UADDR  = 63,
     WIDTH_HIST   = 32,
+    WIDTH_RCODE  = 4,
 } NTraceFieldWidth;
 
 typedef enum {
     TCODE_PROG_TRACE_SYNC        = 0x9,
+    TCODE_RESOURCE_FULL          = 0x1b,
     TCODE_INDIRECT_BRANCH_HIST   = 0x1c,
 } NTraceTcodeFieldValues;
 
@@ -371,6 +373,10 @@ typedef enum {
     SYNC_TRACE_ENABLED = 5,
 } NTraceSyncFieldValues;
 
+typedef enum {
+    RCODE_HIST_PRESENT = 1,
+} NTraceRcodeFieldValues;
+
 typedef struct NTraceFieldPayload {
     NTraceFieldType type;
     NTraceFieldWidth width;
@@ -425,6 +431,14 @@ typedef struct NTraceFieldPayload {
         .width = WIDTH_HIST, \
         .value = (val),      \
     }
+
+#define PAYLOAD_RCODE(val)    \
+    {                         \
+        .type = FIELD_FIXED,  \
+        .width = WIDTH_RCODE, \
+        .value = (val),       \
+    }
+
 #define PAYLOAD_END()      \
     {                      \
         .type = FIELD_END, \
@@ -517,6 +531,21 @@ size_t rv_ntrace_gen_encoded_prog_trace_sync_msg(uint8_t 
*buf, uint64_t faddr)
     return rv_ntrace_gen_encoded_msg(buf, msg_fields);
 }
 
+size_t rv_ntrace_gen_encoded_resource_full_msg(uint8_t *buf, uint32_t hist)
+{
+    const NTraceFieldPayload msg_fields[] = {
+        PAYLOAD_TCODE(TCODE_RESOURCE_FULL),
+        /* SRC field is not supported for now */
+        PAYLOAD_RCODE(RCODE_HIST_PRESENT),
+        /* I-CNT overflow is not supported for now */
+        PAYLOAD_HIST(hist),
+        /* TSTAMP field is not supported for now */
+        PAYLOAD_END(),
+    };
+
+    return rv_ntrace_gen_encoded_msg(buf, msg_fields);
+}
+
 size_t rv_ntrace_gen_indirect_branch_hist_msg(uint8_t *buf, uint8_t btype,
                                               uint32_t icnt, uint64_t uaddr,
                                               uint32_t hist)
diff --git a/hw/riscv/rv-trace-messages.h b/hw/riscv/rv-trace-messages.h
index d113129d65..7ed8737d14 100644
--- a/hw/riscv/rv-trace-messages.h
+++ b/hw/riscv/rv-trace-messages.h
@@ -38,6 +38,7 @@ size_t rv_etrace_gen_encoded_format1(uint8_t *buf,
                                      bool notify, bool updiscon);
 
 size_t rv_ntrace_gen_encoded_prog_trace_sync_msg(uint8_t *buf, uint64_t faddr);
+size_t rv_ntrace_gen_encoded_resource_full_msg(uint8_t *buf, uint32_t hist);
 size_t rv_ntrace_gen_indirect_branch_hist_msg(uint8_t *buf, uint8_t btype,
                                               uint32_t icnt, uint64_t uaddr,
                                               uint32_t hist);
diff --git a/hw/riscv/trace-encoder.c b/hw/riscv/trace-encoder.c
index face6f83b7..302458bfba 100644
--- a/hw/riscv/trace-encoder.c
+++ b/hw/riscv/trace-encoder.c
@@ -694,8 +694,9 @@ static void trencoder_send_branch_map(Object *trencoder_obj)
     uint8_t msg_size;
 
     if (te->ntrace) {
-        /* send ResourceFull message */
-        return;
+        uint32_t hist = rv_ntrace_encode_and_reset_branch_map(te);
+
+        msg_size = rv_ntrace_gen_encoded_resource_full_msg(msg, hist);
     } else {
         msg_size = rv_etrace_gen_encoded_format1_noaddr(msg,
                                                         te->branches,

-- 
2.43.0


Reply via email to