libnexus-rv
msg-types.h
Go to the documentation of this file.
1 // SPDX-License-Identifer: Apache 2.0
2 /*
3  * msg-types.h - NexusRV message definitions
4  *
5  * Copyright (C) 2025, Bo Gan <ganboing@gmail.com>
6  */
7 
8 #ifndef LIBNEXUS_RV_MSG_TYPES_H
9 #define LIBNEXUS_RV_MSG_TYPES_H
10 
11 #include <stdint.h>
12 #include <stddef.h>
13 #include <stdbool.h>
17 #define NEXUS_RV_BITS_TCODE 6
19 #define NEXUS_RV_BITS_ETYPE 4
21 #define NEXUS_RV_BITS_RCODE 4
23 #define NEXUS_RV_BITS_EVCODE 4
25 #define NEXUS_RV_BITS_CDF 2
27 #define NEXUS_RV_BITS_ADDR_SYNC 4
29 #define NEXUS_RV_BITS_ADDR_BTYPE 2
31 #define NEXUS_RV_BITS_OWNERSHIP_FMT 2
33 #define NEXUS_RV_BITS_OWNERSHIP_PRV 2
35 #define NEXUS_RV_BITS_OWNERSHIP_V 1
36 
40  NEXUSRV_TCODE_Ownership = 2,
41  NEXUSRV_TCODE_DirectBranch = 3,
42  NEXUSRV_TCODE_IndirectBranch = 4,
43  NEXUSRV_TCODE_Error = 8,
44  NEXUSRV_TCODE_ProgTraceSync = 9,
45  NEXUSRV_TCODE_DirectBranchSync = 11,
46  NEXUSRV_TCODE_IndirectBranchSync = 12,
47  NEXUSRV_TCODE_ResourceFull = 27,
48  NEXUSRV_TCODE_IndirectBranchHist = 28,
49  NEXUSRV_TCODE_IndirectBranchHistSync = 29,
50  NEXUSRV_TCODE_RepeatBranch = 30,
51  NEXUSRV_TCODE_ProgTraceCorrelation = 33,
52  NEXUSRV_TCODE_VendorStart = 56,
53  NEXUSRV_TCODE_VendorLast = 62,
54  NEXUSRV_TCODE_Idle = 63,
55 };
56 
57 static inline const char* nexusrv_tcode_str(enum nexusrv_tcodes tcode) {
58  switch (tcode) {
59  case NEXUSRV_TCODE_Ownership:
60  return "Ownership";
61  case NEXUSRV_TCODE_DirectBranch:
62  return "DirectBranch";
63  case NEXUSRV_TCODE_IndirectBranch:
64  return "IndirectBranch";
65  case NEXUSRV_TCODE_Error:
66  return "Error";
67  case NEXUSRV_TCODE_ProgTraceSync:
68  return "ProgTraceSync";
69  case NEXUSRV_TCODE_DirectBranchSync:
70  return "DirectBranchSync";
71  case NEXUSRV_TCODE_IndirectBranchSync:
72  return "IndirectBranchSync";
73  case NEXUSRV_TCODE_ResourceFull:
74  return "ResourceFull";
75  case NEXUSRV_TCODE_IndirectBranchHist:
76  return "IndirectBranchHist";
77  case NEXUSRV_TCODE_IndirectBranchHistSync:
78  return "IndirectBranchHistSync";
79  case NEXUSRV_TCODE_RepeatBranch:
80  return "RepeatBranch";
81  case NEXUSRV_TCODE_ProgTraceCorrelation:
82  return "ProgTraceCorrelation";
83  case NEXUSRV_TCODE_Idle:
84  return "Idle";
85  default:
86  return "Unknown";
87  }
88 }
89 
92 typedef struct nexusrv_msg {
93  uint64_t timestamp;
94  uint16_t src;
95  uint8_t tcode;
96  union {
97  struct {
98  uint8_t sync_type : 4;
99  uint8_t branch_type : 2;
100  };
101  struct {
102  uint8_t error_type : 4;
103  };
104  struct {
105  uint8_t res_code : 4;
106  };
107  struct {
108  uint8_t stop_code : 4;
109  uint8_t cdf : 2;
110  };
111  struct {
112  uint8_t ownership_fmt : 2;
113  uint8_t ownership_priv : 2;
114  uint8_t ownership_v : 1;
115  };
116  };
117  union {
118  uint32_t icnt;
119  uint32_t error_code;
120  uint32_t res_data;
121  };
122  uint32_t hist;
123  uint32_t hrepeat;
124  union {
125  uint64_t xaddr;
126  uint64_t context;
127  };
129 
130 static inline bool nexusrv_msg_known(const nexusrv_msg *msg) {
131  switch (msg->tcode) {
132  case NEXUSRV_TCODE_Idle:
133  case NEXUSRV_TCODE_ResourceFull:
134  case NEXUSRV_TCODE_DirectBranch:
135  case NEXUSRV_TCODE_DirectBranchSync:
136  case NEXUSRV_TCODE_IndirectBranch:
137  case NEXUSRV_TCODE_IndirectBranchSync:
138  case NEXUSRV_TCODE_IndirectBranchHist:
139  case NEXUSRV_TCODE_IndirectBranchHistSync:
140  case NEXUSRV_TCODE_RepeatBranch:
141  case NEXUSRV_TCODE_Error:
142  case NEXUSRV_TCODE_Ownership:
143  case NEXUSRV_TCODE_ProgTraceSync:
144  return true;
145  case NEXUSRV_TCODE_ProgTraceCorrelation:
146  return msg->cdf < 2;
147  default:
148  return false;
149  }
150 }
151 
152 static inline bool nexusrv_msg_idle(const nexusrv_msg *msg) {
153  return msg->tcode == NEXUSRV_TCODE_Idle;
154 }
155 
156 static inline bool nexusrv_msg_has_src(const nexusrv_msg *msg) {
157  return !nexusrv_msg_idle(msg);
158 }
159 
160 static inline bool nexusrv_msg_is_branch(const nexusrv_msg *msg) {
161  switch (msg->tcode) {
162  case NEXUSRV_TCODE_DirectBranch:
163  case NEXUSRV_TCODE_DirectBranchSync:
164  case NEXUSRV_TCODE_IndirectBranch:
165  case NEXUSRV_TCODE_IndirectBranchSync:
166  case NEXUSRV_TCODE_IndirectBranchHist:
167  case NEXUSRV_TCODE_IndirectBranchHistSync:
168  return true;
169  default:
170  return false;
171  }
172 }
173 
174 static inline bool nexusrv_msg_is_indir_branch(const nexusrv_msg *msg) {
175  switch (msg->tcode) {
176  case NEXUSRV_TCODE_IndirectBranch:
177  case NEXUSRV_TCODE_IndirectBranchSync:
178  case NEXUSRV_TCODE_IndirectBranchHist:
179  case NEXUSRV_TCODE_IndirectBranchHistSync:
180  return true;
181  default:
182  return false;
183  }
184 }
185 
186 static inline bool nexusrv_msg_is_res(const nexusrv_msg *msg) {
187  return msg->tcode == NEXUSRV_TCODE_ResourceFull;
188 }
189 
190 static inline bool nexusrv_msg_is_sync(const nexusrv_msg *msg) {
191  switch (msg->tcode) {
192  case NEXUSRV_TCODE_DirectBranchSync:
193  case NEXUSRV_TCODE_IndirectBranchSync:
194  case NEXUSRV_TCODE_IndirectBranchHistSync:
195  case NEXUSRV_TCODE_ProgTraceSync:
196  return true;
197  default:
198  return false;
199  }
200 }
201 
202 static inline bool nexusrv_msg_is_error(const nexusrv_msg *msg) {
203  return msg->tcode == NEXUSRV_TCODE_Error;
204 }
205 
206 static inline bool nexusrv_msg_is_stop(const nexusrv_msg *msg) {
207  return msg->tcode == NEXUSRV_TCODE_ProgTraceCorrelation;
208 }
209 
210 static inline bool nexusrv_msg_has_icnt(const nexusrv_msg *msg) {
211  switch (msg->tcode) {
212  case NEXUSRV_TCODE_ResourceFull:
213  return !msg->res_code;
214  case NEXUSRV_TCODE_DirectBranch:
215  case NEXUSRV_TCODE_DirectBranchSync:
216  case NEXUSRV_TCODE_IndirectBranch:
217  case NEXUSRV_TCODE_IndirectBranchSync:
218  case NEXUSRV_TCODE_IndirectBranchHist:
219  case NEXUSRV_TCODE_IndirectBranchHistSync:
220  case NEXUSRV_TCODE_ProgTraceSync:
221  case NEXUSRV_TCODE_ProgTraceCorrelation:
222  return true;
223  default:
224  return false;
225  }
226 }
227 
228 static inline bool nexusrv_msg_has_xaddr(const nexusrv_msg *msg) {
229  switch (msg->tcode) {
230  case NEXUSRV_TCODE_IndirectBranch:
231  case NEXUSRV_TCODE_IndirectBranchSync:
232  case NEXUSRV_TCODE_IndirectBranchHist:
233  case NEXUSRV_TCODE_IndirectBranchHistSync:
234  case NEXUSRV_TCODE_DirectBranchSync:
235  case NEXUSRV_TCODE_ProgTraceSync:
236  return true;
237  default:
238  return false;
239  }
240 }
241 
242 static inline bool nexusrv_msg_has_hist(const nexusrv_msg *msg) {
243  switch (msg->tcode) {
244  case NEXUSRV_TCODE_ResourceFull:
245  return msg->res_code == 1 || msg->res_code == 2;
246  case NEXUSRV_TCODE_ProgTraceCorrelation:
247  return msg->cdf == 1;
248  case NEXUSRV_TCODE_IndirectBranchHist:
249  case NEXUSRV_TCODE_IndirectBranchHistSync:
250  return true;
251  default:
252  return false;
253  }
254 }
255 
256 static inline bool nexusrv_msg_known_rescode(uint8_t rescode) {
257  return rescode < 3;
258 }
259 
260 static inline unsigned nexusrv_msg_hist_bits(uint32_t hist) {
261  if (!hist)
262  return 0;
263  return sizeof(long) * 8 - 1 - __builtin_clzl(hist);
264 }
265 
266 #endif
struct nexusrv_msg nexusrv_msg
Decoded NexusRV Message.
nexusrv_tcodes
TCODE enumeration.
Definition: msg-types.h:39
Decoded NexusRV Message.
Definition: msg-types.h:92
uint8_t tcode
Definition: msg-types.h:95
uint32_t error_code
Definition: msg-types.h:119
uint32_t icnt
Definition: msg-types.h:118
uint64_t context
Definition: msg-types.h:126
uint8_t branch_type
Definition: msg-types.h:99
uint8_t ownership_priv
Definition: msg-types.h:113
uint8_t ownership_fmt
Definition: msg-types.h:112
uint8_t ownership_v
Definition: msg-types.h:114
uint32_t hrepeat
Definition: msg-types.h:123
uint16_t src
Definition: msg-types.h:94
uint8_t res_code
Definition: msg-types.h:105
uint8_t sync_type
Definition: msg-types.h:98
uint8_t cdf
Definition: msg-types.h:109
uint64_t xaddr
Definition: msg-types.h:125
uint32_t res_data
Definition: msg-types.h:120
uint8_t stop_code
Definition: msg-types.h:108
uint32_t hist
Definition: msg-types.h:122
uint64_t timestamp
Definition: msg-types.h:93
uint8_t error_type
Definition: msg-types.h:102