1 /*
2 * \file trc_pkt_elem_etmv4i.h
3 * \brief OpenCSD :
4 *
5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
6 */
7
8
9 /*
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of the copyright holder nor the names of its contributors
21 * may be used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #ifndef ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
37 #define ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
38
39 #include "trc_pkt_types_etmv4.h"
40 #include "common/trc_printable_elem.h"
41 #include "common/trc_pkt_elem_base.h"
42
43 /** @addtogroup trc_pkts
44 @{*/
45
46 /*!
47 * @class Etmv4PktAddrStack
48 * @brief ETMv4 Address packet values stack
49 * @ingroup trc_pkts
50 *
51 * This class represents a stack of recent broadcast address values -
52 * used to fulfil the ExactMatch address type where no address is output.
53 *
54 */
55 class Etmv4PktAddrStack
56 {
57 public:
Etmv4PktAddrStack()58 Etmv4PktAddrStack()
59 {
60 reset_stack();
61 }
~Etmv4PktAddrStack()62 ~Etmv4PktAddrStack() {};
63
push(const ocsd_pkt_vaddr vaddr,const uint8_t isa)64 void push(const ocsd_pkt_vaddr vaddr, const uint8_t isa)
65 {
66 m_v_addr[2] = m_v_addr[1];
67 m_v_addr[1] = m_v_addr[0];
68 m_v_addr[0] = vaddr;
69 m_v_addr_ISA[2] = m_v_addr_ISA[1];
70 m_v_addr_ISA[1] = m_v_addr_ISA[0];
71 m_v_addr_ISA[0] = isa;
72 }
73
get_idx(const uint8_t idx,ocsd_pkt_vaddr & vaddr,uint8_t & isa)74 void get_idx(const uint8_t idx, ocsd_pkt_vaddr &vaddr, uint8_t &isa)
75 {
76 if (idx < 3)
77 {
78 vaddr = m_v_addr[idx];
79 isa = m_v_addr_ISA[idx];
80 }
81 }
82
83 // explicit reset for TInfo.
reset_stack()84 void reset_stack()
85 {
86 for (int i = 0; i < 3; i++)
87 {
88 m_v_addr[i].pkt_bits = 0;
89 m_v_addr[i].size = OCSD_MAX_VA_BITSIZE == 64 ? VA_64BIT : VA_32BIT;
90 m_v_addr[i].val = 0;
91 m_v_addr[i].valid_bits = OCSD_MAX_VA_BITSIZE;
92 m_v_addr_ISA[i] = 0;
93 }
94
95 }
96
97 private:
98 ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet
99 uint8_t m_v_addr_ISA[3];
100 };
101
102 /*!
103 * @class EtmV4ITrcPacket
104 * @brief ETMv4 Instuction Trace Protocol Packet.
105 * @ingroup trc_pkts
106 *
107 * This class represents a single ETMv4 data trace packet, along with intra packet state.
108 *
109 */
110 class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public trcPrintableElem
111 {
112 public:
113 EtmV4ITrcPacket();
114 ~EtmV4ITrcPacket();
115
116 EtmV4ITrcPacket &operator =(const ocsd_etmv4_i_pkt* p_pkt);
117
c_pkt()118 virtual const void *c_pkt() const { return (const ocsd_etmv4_i_pkt *)this; };
119
120 // update interface - set packet values
121 void initStartState(); //!< Set to initial state - no intra packet state valid. Use on start of trace / discontinuities.
122 void initNextPacket(); //!< clear any single packet only flags / state.
123
setType(const ocsd_etmv4_i_pkt_type pkt_type)124 void setType(const ocsd_etmv4_i_pkt_type pkt_type) { type = pkt_type; };
125 void updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t val = 0);
126
127 void clearTraceInfo(); //!< clear all the trace info data prior to setting for new trace info packet.
128 void setTraceInfo(const uint32_t infoVal);
129 void setTraceInfoKey(const uint32_t keyVal);
130 void setTraceInfoSpec(const uint32_t specVal);
131 void setTraceInfoCyct(const uint32_t cyctVal);
132
133 void setTS(const uint64_t value, const uint8_t bits);
134 void setCycleCount(const uint32_t value);
135 void setCommitElements(const uint32_t commit_elem);
136 void setCancelElements(const uint32_t cancel_elem);
137 void setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num);
138
139 void setCondIF1(uint32_t const cond_key);
140 void setCondIF2(uint8_t const c_elem_idx);
141 void setCondIF3(uint8_t const num_c_elem, const bool finalElem);
142
143 void setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2], const bool set2Keys);
144 void setCondRF2(const uint8_t key_incr, const uint8_t token);
145 void setCondRF3(const uint16_t tokens);
146 void setCondRF4(const uint8_t token);
147
148 void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0);
149 void setContextVMID(const uint32_t VMID);
150 void setContextCID(const uint32_t CID);
151
152 void setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type);
153
154 void set64BitAddress(const uint64_t addr, const uint8_t IS);
155 void set32BitAddress(const uint32_t addr, const uint8_t IS);
156 void updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits);
157 void setAddressExactMatch(const uint8_t idx);
158
159 void setDataSyncMarker(const uint8_t dsm_val);
160 void setEvent(const uint8_t event_val);
161
162 void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type);
163
164 // packet status interface - get packet info.
getType()165 const ocsd_etmv4_i_pkt_type getType() const { return type; };
getErrType()166 const ocsd_etmv4_i_pkt_type getErrType() const { return err_type; };
167
168 //! return true if this packet has set the commit packet count.
hasCommitElementsCount()169 const bool hasCommitElementsCount() const
170 {
171 return pkt_valid.bits.commit_elem_valid ? true : false;
172 };
173
174 // trace info
getTraceInfo()175 const etmv4_trace_info_t &getTraceInfo() const { return trace_info; };
176 const uint32_t getCCThreshold() const;
177 const uint32_t getP0Key() const;
178 const uint32_t getCurrSpecDepth() const;
179
180 // atom
getAtom()181 const ocsd_pkt_atom &getAtom() const { return atom; };
getNumAtoms()182 const int getNumAtoms() const { return atom.num; };
183
184 // context
getContext()185 const etmv4_context_t &getContext() const { return context; };
186
187 // address
getAddrMatch()188 const uint8_t &getAddrMatch() const { return addr_exact_match_idx; };
getAddrVal()189 const ocsd_vaddr_t &getAddrVal() const { return v_addr.val; };
getAddrIS()190 const uint8_t &getAddrIS() const { return v_addr_ISA; };
getAddr64Bit()191 const bool getAddr64Bit() const { return v_addr.size == VA_64BIT; };
192
193 // ts
getTS()194 const uint64_t getTS() const { return pkt_valid.bits.ts_valid ? ts.timestamp : 0; };
195
196 // cc
getCC()197 const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; };
198
199 // speculation
getCommitElem()200 const int getCommitElem() const { return commit_elements; };
getCancelElem()201 const int getCancelElem() const { return cancel_elements; };
202
203 // packet type
204 const bool isBadPacket() const;
205
206 // printing
207 virtual void toString(std::string &str) const;
208 virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
209
setProtocolVersion(const uint8_t version)210 void setProtocolVersion(const uint8_t version) { protocol_version = version; };
211
212 private:
213 const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const;
214 void contextStr(std::string &ctxtStr) const;
215 void atomSeq(std::string &valStr) const;
216 void addrMatchIdx(std::string &valStr) const;
217 void exceptionInfo(std::string &valStr) const;
218
219 void push_vaddr();
220 void pop_vaddr_idx(const uint8_t idx);
221
isETE()222 const bool isETE() const { return (protocol_version & 0xF0) == 0x50; };
223
224 Etmv4PktAddrStack m_addr_stack;
225 };
226
updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type,const uint8_t err_val)227 inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t err_val /* = 0 */)
228 {
229 // set primary type to incoming error type, set packet err type to previous primary type.
230 err_type = type;
231 type = err_pkt_type;
232 err_hdr_val = err_val;
233 }
234
clearTraceInfo()235 inline void EtmV4ITrcPacket::clearTraceInfo()
236 {
237 pkt_valid.bits.ts_valid = 0;
238 pkt_valid.bits.trace_info_valid = 0;
239 pkt_valid.bits.p0_key_valid = 0;
240 pkt_valid.bits.spec_depth_valid = 0;
241 pkt_valid.bits.cc_thresh_valid = 0;
242
243 // set these as defaults - if they don't appear in TINFO this is the state.
244 setTraceInfo(0);
245 setTraceInfoSpec(0);
246
247 // explicitly reset the stack & zero the current address.
248 m_addr_stack.reset_stack();
249 m_addr_stack.get_idx(0, v_addr, v_addr_ISA);
250 }
251
setTraceInfo(const uint32_t infoVal)252 inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal)
253 {
254 trace_info.val = infoVal;
255 pkt_valid.bits.trace_info_valid = 1;
256 }
257
setTraceInfoKey(const uint32_t keyVal)258 inline void EtmV4ITrcPacket::setTraceInfoKey(const uint32_t keyVal)
259 {
260 p0_key = keyVal;
261 pkt_valid.bits.p0_key_valid = 1;
262 }
263
setTraceInfoSpec(const uint32_t specVal)264 inline void EtmV4ITrcPacket::setTraceInfoSpec(const uint32_t specVal)
265 {
266 curr_spec_depth = specVal;
267 pkt_valid.bits.spec_depth_valid = 1;
268 }
269
setTraceInfoCyct(const uint32_t cyctVal)270 inline void EtmV4ITrcPacket::setTraceInfoCyct(const uint32_t cyctVal)
271 {
272 cc_threshold = cyctVal;
273 pkt_valid.bits.cc_thresh_valid = 1;
274 }
275
setTS(const uint64_t value,const uint8_t bits)276 inline void EtmV4ITrcPacket::setTS(const uint64_t value, const uint8_t bits)
277 {
278 uint64_t mask = (uint64_t)-1LL;
279 if(bits < 64) mask = (1ULL << bits) - 1;
280 ts.timestamp = (ts.timestamp & ~mask) | (value & mask);
281 ts.bits_changed = bits;
282 pkt_valid.bits.ts_valid = 1;
283 }
284
setCycleCount(const uint32_t value)285 inline void EtmV4ITrcPacket::setCycleCount(const uint32_t value)
286 {
287 pkt_valid.bits.cc_valid = 1;
288 cycle_count = value;
289 }
290
setCommitElements(const uint32_t commit_elem)291 inline void EtmV4ITrcPacket::setCommitElements(const uint32_t commit_elem)
292 {
293 pkt_valid.bits.commit_elem_valid = 1;
294 commit_elements = commit_elem;
295 }
296
getCCThreshold()297 inline const uint32_t EtmV4ITrcPacket::getCCThreshold() const
298 {
299 if(pkt_valid.bits.cc_thresh_valid)
300 return cc_threshold;
301 return 0;
302 }
303
getP0Key()304 inline const uint32_t EtmV4ITrcPacket::getP0Key() const
305 {
306 if(pkt_valid.bits.p0_key_valid)
307 return p0_key;
308 return 0;
309 }
310
getCurrSpecDepth()311 inline const uint32_t EtmV4ITrcPacket::getCurrSpecDepth() const
312 {
313 if(pkt_valid.bits.spec_depth_valid)
314 return curr_spec_depth;
315 return 0;
316 }
317
setCancelElements(const uint32_t cancel_elem)318 inline void EtmV4ITrcPacket::setCancelElements(const uint32_t cancel_elem)
319 {
320 cancel_elements = cancel_elem;
321 }
322
setAtomPacket(const ocsd_pkt_atm_type type,const uint32_t En_bits,const uint8_t num)323 inline void EtmV4ITrcPacket::setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num)
324 {
325 if(type == ATOM_REPEAT)
326 {
327 uint32_t bit_patt = En_bits & 0x1;
328 if(bit_patt)
329 {
330 // none zero - all 1s
331 bit_patt = (bit_patt << num) - 1;
332 }
333 atom.En_bits = bit_patt;
334 }
335 else
336 atom.En_bits = En_bits;
337 atom.num = num;
338 }
339
setCondIF1(const uint32_t cond_key)340 inline void EtmV4ITrcPacket::setCondIF1(const uint32_t cond_key)
341 {
342 cond_instr.cond_key_set = 1;
343 cond_instr.f3_final_elem = 0;
344 cond_instr.f2_cond_incr = 0;
345 cond_instr.num_c_elem = 1;
346 cond_instr.cond_c_key = cond_key;
347 }
348
setCondIF2(const uint8_t c_elem_idx)349 inline void EtmV4ITrcPacket::setCondIF2(const uint8_t c_elem_idx)
350 {
351 cond_instr.cond_key_set = 0;
352 cond_instr.f3_final_elem = 0;
353 switch(c_elem_idx & 0x3)
354 {
355 case 0:
356 cond_instr.f2_cond_incr = 1;
357 cond_instr.num_c_elem = 1;
358 break;
359
360 case 1:
361 cond_instr.f2_cond_incr = 0;
362 cond_instr.num_c_elem = 1;
363 break;
364
365 case 2:
366 cond_instr.f2_cond_incr = 1;
367 cond_instr.num_c_elem = 2;
368 break;
369 }
370 }
371
setCondIF3(const uint8_t num_c_elem,const bool finalElem)372 inline void EtmV4ITrcPacket::setCondIF3(const uint8_t num_c_elem, const bool finalElem)
373 {
374 cond_instr.cond_key_set = 0;
375 cond_instr.f3_final_elem = finalElem ? 1: 0;
376 cond_instr.f2_cond_incr = 0;
377 cond_instr.num_c_elem = num_c_elem;
378 }
379
setCondRF1(const uint32_t key[2],const uint8_t res[2],const uint8_t CI[2],const bool set2Keys)380 inline void EtmV4ITrcPacket::setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2],const bool set2Keys)
381 {
382 cond_result.key_res_0_set = 1;
383 cond_result.cond_r_key_0 = key[0];
384 cond_result.res_0 = res[0];
385 cond_result.ci_0 = CI[0];
386
387 if(set2Keys)
388 {
389 cond_result.key_res_1_set = 1;
390 cond_result.cond_r_key_1 = key[1];
391 cond_result.res_1 = res[1];
392 cond_result.ci_1 = CI[1];
393 }
394 }
395
396
setCondRF2(const uint8_t key_incr,const uint8_t token)397 inline void EtmV4ITrcPacket::setCondRF2(const uint8_t key_incr, const uint8_t token)
398 {
399 cond_result.key_res_0_set = 0;
400 cond_result.key_res_1_set = 0;
401 cond_result.f2_key_incr = key_incr;
402 cond_result.f2f4_token = token;
403 }
404
setCondRF3(const uint16_t tokens)405 inline void EtmV4ITrcPacket::setCondRF3(const uint16_t tokens)
406 {
407 cond_result.key_res_0_set = 0;
408 cond_result.key_res_1_set = 0;
409 cond_result.f3_tokens = tokens;
410 }
411
setCondRF4(const uint8_t token)412 inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token)
413 {
414 cond_result.key_res_0_set = 0;
415 cond_result.key_res_1_set = 0;
416 cond_result.f2f4_token = token;
417 }
418
setContextInfo(const bool update,const uint8_t EL,const uint8_t NS,const uint8_t SF)419 inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF)
420 {
421 pkt_valid.bits.context_valid = 1;
422 if(update)
423 {
424 context.updated = 1;
425 context.EL = EL;
426 context.NS = NS;
427 context.SF = SF;
428 }
429 }
430
setContextVMID(const uint32_t VMID)431 inline void EtmV4ITrcPacket::setContextVMID(const uint32_t VMID)
432 {
433 pkt_valid.bits.context_valid = 1;
434 context.updated = 1;
435 context.VMID = VMID;
436 context.updated_v = 1;
437 }
438
setContextCID(const uint32_t CID)439 inline void EtmV4ITrcPacket::setContextCID(const uint32_t CID)
440 {
441 pkt_valid.bits.context_valid = 1;
442 context.updated = 1;
443 context.ctxtID = CID;
444 context.updated_c = 1;
445 }
446
setExceptionInfo(const uint16_t excep_type,const uint8_t addr_interp,const uint8_t m_fault_pending,const uint8_t m_type)447 inline void EtmV4ITrcPacket::setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type)
448 {
449 exception_info.exceptionType = excep_type;
450 exception_info.addr_interp = addr_interp;
451 exception_info.m_fault_pending = m_fault_pending;
452 exception_info.m_type = m_type;
453 }
454
set64BitAddress(const uint64_t addr,const uint8_t IS)455 inline void EtmV4ITrcPacket::set64BitAddress(const uint64_t addr, const uint8_t IS)
456 {
457 v_addr.pkt_bits = 64;
458 v_addr.valid_bits = 64;
459 v_addr.size = VA_64BIT;
460 v_addr.val = addr;
461 v_addr_ISA = IS;
462 push_vaddr();
463 }
464
set32BitAddress(const uint32_t addr,const uint8_t IS)465 inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t IS)
466 {
467 uint64_t mask = OCSD_BIT_MASK(32);
468 v_addr.pkt_bits = 32;
469
470 if (pkt_valid.bits.context_valid && context.SF)
471 {
472 v_addr.size = VA_64BIT;
473 v_addr.val = (v_addr.val & ~mask) | (addr & mask);
474 }
475 else
476 {
477 v_addr.val = addr;
478 v_addr.size = VA_32BIT;
479 }
480
481 if (v_addr.valid_bits < 32) // may be updating a 64 bit address so only set 32 if currently less.
482 v_addr.valid_bits = 32;
483
484 v_addr_ISA = IS;
485 push_vaddr();
486 }
487
updateShortAddress(const uint32_t addr,const uint8_t IS,const uint8_t update_bits)488 inline void EtmV4ITrcPacket::updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits)
489 {
490 ocsd_vaddr_t update_mask = OCSD_BIT_MASK(update_bits);
491 v_addr.pkt_bits = update_bits;
492 if(v_addr.valid_bits < update_bits)
493 v_addr.valid_bits = update_bits;
494
495 v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask);
496 v_addr_ISA = IS;
497 push_vaddr();
498 }
499
setAddressExactMatch(const uint8_t idx)500 inline void EtmV4ITrcPacket::setAddressExactMatch(const uint8_t idx)
501 {
502 addr_exact_match_idx = idx;
503 pop_vaddr_idx(idx);
504 push_vaddr();
505 }
506
setDataSyncMarker(const uint8_t dsm_value)507 inline void EtmV4ITrcPacket::setDataSyncMarker(const uint8_t dsm_value)
508 {
509 dsm_val = dsm_value;
510 }
511
setEvent(const uint8_t event_value)512 inline void EtmV4ITrcPacket::setEvent(const uint8_t event_value)
513 {
514 event_val = event_value;
515 }
516
setQType(const bool has_count,const uint32_t count,const bool has_addr,const bool addr_match,const uint8_t type)517 inline void EtmV4ITrcPacket::setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type)
518 {
519 Q_pkt.q_count = count;
520 Q_pkt.q_type = type;
521 Q_pkt.count_present = has_count ? 1 : 0;
522 Q_pkt.addr_present = has_addr ? 1: 0;
523 Q_pkt.addr_match = addr_match ? 1 :0;
524 }
525
isBadPacket()526 inline const bool EtmV4ITrcPacket::isBadPacket() const
527 {
528 return (type >= ETM4_PKT_I_BAD_SEQUENCE);
529 }
530
push_vaddr()531 inline void EtmV4ITrcPacket::push_vaddr()
532 {
533 m_addr_stack.push(v_addr, v_addr_ISA);
534 }
535
pop_vaddr_idx(const uint8_t idx)536 inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx)
537 {
538 m_addr_stack.get_idx(idx, v_addr, v_addr_ISA);
539 }
540
541 /** @}*/
542
543 #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
544
545 /* End of File trc_pkt_elem_etmv4i.h */
546