]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
Import OpenCSD v0.14.2
[FreeBSD/FreeBSD.git] / decoder / include / opencsd / etmv4 / trc_pkt_elem_etmv4i.h
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:
58     Etmv4PktAddrStack()
59     {
60         reset_stack();
61     }
62     ~Etmv4PktAddrStack() {};
63
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
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.
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
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
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.
165     const ocsd_etmv4_i_pkt_type getType() const { return type; };
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.
169     const bool hasCommitElementsCount() const 
170     {
171         return pkt_valid.bits.commit_elem_valid ? true : false;
172     };
173     
174     // trace info
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
181     const ocsd_pkt_atom &getAtom() const { return atom; };
182     const int getNumAtoms() const { return atom.num; };
183
184     // context
185     const etmv4_context_t &getContext() const { return context; };
186
187     // address
188     const uint8_t &getAddrMatch() const  { return addr_exact_match_idx; };
189     const ocsd_vaddr_t &getAddrVal() const { return v_addr.val; };
190     const uint8_t &getAddrIS() const { return v_addr_ISA; };
191     const bool getAddr64Bit() const { return v_addr.size == VA_64BIT; };
192
193     // ts
194     const uint64_t getTS() const { return pkt_valid.bits.ts_valid ? ts.timestamp : 0; };
195
196     // cc
197     const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; };
198
199     // speculation
200     const int getCommitElem() const { return commit_elements; };
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
210 private:
211     const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const;
212     void contextStr(std::string &ctxtStr) const;
213     void atomSeq(std::string &valStr) const;
214     void addrMatchIdx(std::string &valStr) const;
215     void exceptionInfo(std::string &valStr) const;
216
217     void push_vaddr();
218     void pop_vaddr_idx(const uint8_t idx);
219
220     Etmv4PktAddrStack m_addr_stack;
221 };
222
223 inline void  EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t err_val /* = 0 */)
224 {
225     // set primary type to incoming error type, set packet err type to previous primary type.
226     err_type = type;
227     type = err_pkt_type;
228     err_hdr_val = err_val;
229 }
230
231 inline void EtmV4ITrcPacket::clearTraceInfo()
232 {
233     pkt_valid.bits.ts_valid = 0;
234     pkt_valid.bits.trace_info_valid = 0;
235     pkt_valid.bits.p0_key_valid = 0;
236     pkt_valid.bits.spec_depth_valid = 0;
237     pkt_valid.bits.cc_thresh_valid  = 0;
238
239     // set these as defaults - if they don't appear in TINFO this is the state.
240     setTraceInfo(0);        
241     setTraceInfoSpec(0);   
242
243     // explicitly reset the stack & zero the current address. 
244     m_addr_stack.reset_stack();
245     m_addr_stack.get_idx(0, v_addr, v_addr_ISA);
246 }
247
248 inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal)
249 {
250     trace_info.val = infoVal;
251     pkt_valid.bits.trace_info_valid = 1;
252 }
253
254 inline void EtmV4ITrcPacket::setTraceInfoKey(const uint32_t keyVal)
255 {
256     p0_key = keyVal;
257     pkt_valid.bits.p0_key_valid = 1;
258 }
259
260 inline void EtmV4ITrcPacket::setTraceInfoSpec(const uint32_t specVal)
261 {
262     curr_spec_depth = specVal;
263     pkt_valid.bits.spec_depth_valid = 1;
264 }
265
266 inline void EtmV4ITrcPacket::setTraceInfoCyct(const uint32_t cyctVal)
267 {
268     cc_threshold = cyctVal;
269     pkt_valid.bits.cc_thresh_valid  = 1;
270 }
271
272 inline void EtmV4ITrcPacket::setTS(const uint64_t value, const uint8_t bits)
273 {
274     uint64_t mask = (uint64_t)-1LL;
275     if(bits < 64) mask = (1ULL << bits) - 1;
276     ts.timestamp = (ts.timestamp & ~mask) | (value & mask);
277     ts.bits_changed = bits;
278     pkt_valid.bits.ts_valid = 1;
279 }
280
281 inline void EtmV4ITrcPacket::setCycleCount(const uint32_t value)
282 {
283     pkt_valid.bits.cc_valid = 1;
284     cycle_count = value;
285 }
286
287 inline void EtmV4ITrcPacket::setCommitElements(const uint32_t commit_elem)
288 {
289     pkt_valid.bits.commit_elem_valid = 1;
290     commit_elements = commit_elem;
291 }
292
293 inline const uint32_t EtmV4ITrcPacket::getCCThreshold() const
294 {
295     if(pkt_valid.bits.cc_thresh_valid)
296         return cc_threshold;
297     return 0;
298 }
299
300 inline const uint32_t EtmV4ITrcPacket::getP0Key() const
301 {
302     if(pkt_valid.bits.p0_key_valid)
303         return p0_key;
304     return 0;
305 }
306
307 inline const uint32_t EtmV4ITrcPacket::getCurrSpecDepth() const
308 {
309     if(pkt_valid.bits.spec_depth_valid)
310         return curr_spec_depth;
311     return 0;
312 }
313
314 inline void EtmV4ITrcPacket::setCancelElements(const uint32_t cancel_elem)
315 {
316     cancel_elements = cancel_elem;
317 }
318
319 inline void EtmV4ITrcPacket::setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num)
320 {
321     if(type == ATOM_REPEAT)
322     {
323         uint32_t bit_patt = En_bits & 0x1;
324         if(bit_patt)
325         {   
326             // none zero - all 1s
327             bit_patt = (bit_patt << num) - 1;
328         }
329         atom.En_bits = bit_patt;
330     }
331     else
332         atom.En_bits = En_bits;
333     atom.num = num;    
334 }
335
336 inline void EtmV4ITrcPacket::setCondIF1(const uint32_t cond_key)
337 {
338     cond_instr.cond_key_set = 1;
339     cond_instr.f3_final_elem = 0;
340     cond_instr.f2_cond_incr = 0;
341     cond_instr.num_c_elem = 1;
342     cond_instr.cond_c_key = cond_key;
343 }
344
345 inline void EtmV4ITrcPacket::setCondIF2(const uint8_t c_elem_idx)
346 {
347     cond_instr.cond_key_set = 0;
348     cond_instr.f3_final_elem = 0;
349     switch(c_elem_idx & 0x3)
350     {
351     case 0:
352         cond_instr.f2_cond_incr = 1;
353         cond_instr.num_c_elem = 1;
354         break;
355
356     case 1:
357         cond_instr.f2_cond_incr = 0;
358         cond_instr.num_c_elem = 1;
359         break;
360
361     case 2:
362         cond_instr.f2_cond_incr = 1;
363         cond_instr.num_c_elem = 2;
364         break;
365     }
366 }
367
368 inline void EtmV4ITrcPacket::setCondIF3(const uint8_t num_c_elem, const bool finalElem)
369 {
370     cond_instr.cond_key_set = 0;
371     cond_instr.f3_final_elem = finalElem ? 1: 0;
372     cond_instr.f2_cond_incr = 0;
373     cond_instr.num_c_elem = num_c_elem;
374 }
375
376 inline void EtmV4ITrcPacket::setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2],const bool set2Keys)
377 {
378     cond_result.key_res_0_set = 1;
379     cond_result.cond_r_key_0 = key[0];
380     cond_result.res_0 = res[0];
381     cond_result.ci_0 = CI[0];
382
383     if(set2Keys)
384     {
385         cond_result.key_res_1_set = 1;
386         cond_result.cond_r_key_1 = key[1];
387         cond_result.res_1 = res[1];
388         cond_result.ci_1 = CI[1];
389     }
390 }
391
392
393 inline void EtmV4ITrcPacket::setCondRF2(const uint8_t key_incr, const uint8_t token)
394 {
395     cond_result.key_res_0_set = 0;
396     cond_result.key_res_1_set = 0;
397     cond_result.f2_key_incr = key_incr;
398     cond_result.f2f4_token = token;
399 }
400
401 inline void EtmV4ITrcPacket::setCondRF3(const uint16_t tokens)
402 {
403     cond_result.key_res_0_set = 0;
404     cond_result.key_res_1_set = 0;
405     cond_result.f3_tokens = tokens;
406 }
407
408 inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token)
409 {
410     cond_result.key_res_0_set = 0;
411     cond_result.key_res_1_set = 0;
412     cond_result.f2f4_token = token;
413 }
414
415 inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF)
416 {
417     pkt_valid.bits.context_valid = 1;
418     if(update)
419     {
420         context.updated = 1;
421         context.EL = EL;
422         context.NS = NS;
423         context.SF = SF;
424     }
425 }
426
427 inline void EtmV4ITrcPacket::setContextVMID(const uint32_t VMID)
428 {
429     pkt_valid.bits.context_valid = 1;
430     context.updated = 1;
431     context.VMID = VMID;
432     context.updated_v = 1;
433 }
434
435 inline void EtmV4ITrcPacket::setContextCID(const uint32_t CID)
436 {
437     pkt_valid.bits.context_valid = 1;
438     context.updated = 1;
439     context.ctxtID = CID;
440     context.updated_c = 1;
441 }
442
443 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)
444 {
445     exception_info.exceptionType = excep_type;
446     exception_info.addr_interp = addr_interp;
447     exception_info.m_fault_pending = m_fault_pending;
448     exception_info.m_type = m_type;
449 }
450
451 inline void EtmV4ITrcPacket::set64BitAddress(const uint64_t addr, const uint8_t IS)
452 {
453     v_addr.pkt_bits = 64;
454     v_addr.valid_bits = 64;
455     v_addr.size = VA_64BIT;
456     v_addr.val = addr;
457     v_addr_ISA = IS;
458     push_vaddr();
459 }
460
461 inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t IS)
462 {
463     uint64_t mask = OCSD_BIT_MASK(32);
464     v_addr.pkt_bits = 32;
465
466         if (pkt_valid.bits.context_valid && context.SF)
467         {
468                 v_addr.size = VA_64BIT;
469                 v_addr.val = (v_addr.val & ~mask) | (addr & mask);
470         }
471     else
472     {
473                 v_addr.val = addr;
474         v_addr.size = VA_32BIT;
475         }
476
477     if (v_addr.valid_bits < 32) // may be updating a 64 bit address so only set 32 if currently less.
478         v_addr.valid_bits = 32;
479
480     v_addr_ISA = IS;
481     push_vaddr();
482 }
483
484 inline void EtmV4ITrcPacket::updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits)
485 {
486     ocsd_vaddr_t update_mask = OCSD_BIT_MASK(update_bits);
487     v_addr.pkt_bits = update_bits;
488     if(v_addr.valid_bits < update_bits)
489         v_addr.valid_bits = update_bits;
490
491     v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask);
492     v_addr_ISA = IS;
493     push_vaddr();
494 }
495
496 inline void EtmV4ITrcPacket::setAddressExactMatch(const uint8_t idx)
497 {
498     addr_exact_match_idx = idx;   
499     pop_vaddr_idx(idx);
500     push_vaddr();
501 }
502
503 inline void EtmV4ITrcPacket::setDataSyncMarker(const uint8_t dsm_value)
504 {
505     dsm_val = dsm_value;
506 }
507
508 inline void EtmV4ITrcPacket::setEvent(const uint8_t event_value)
509 {
510     event_val = event_value;
511 }
512
513 inline void EtmV4ITrcPacket::setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type)
514 {
515     Q_pkt.q_count = count;
516     Q_pkt.q_type = type;
517     Q_pkt.count_present = has_count ? 1 : 0;
518     Q_pkt.addr_present = has_addr ? 1: 0;
519     Q_pkt.addr_match = addr_match ? 1 :0;
520 }
521
522 inline const bool EtmV4ITrcPacket::isBadPacket() const
523 {
524     return (type >= ETM4_PKT_I_BAD_SEQUENCE);
525 }
526
527 inline void  EtmV4ITrcPacket::push_vaddr()
528 {
529     m_addr_stack.push(v_addr, v_addr_ISA);
530 }
531
532 inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx)
533 {
534     m_addr_stack.get_idx(idx, v_addr, v_addr_ISA);
535 }
536
537 /** @}*/
538
539 #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
540
541 /* End of File trc_pkt_elem_etmv4i.h */