1 /*
2  * \file       trc_pkt_elem_etmv4i.cpp
3  * \brief      OpenCSD :
4  *
5  * \copyright  Copyright (c) 2015, ARM Limited. All Rights Reserved.
6  */
7 
8 /*
9  * Redistribution and use in source and binary forms, with or without modification,
10  * are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include <sstream>
35 #include <iomanip>
36 
37 #include "opencsd/etmv4/trc_pkt_elem_etmv4i.h"
38 
39 EtmV4ITrcPacket::EtmV4ITrcPacket()
40 {
41 }
42 
43 EtmV4ITrcPacket::~EtmV4ITrcPacket()
44 {
45 }
46 
47 void EtmV4ITrcPacket::initStartState()
48 {
49     // clear packet state to start of trace (first sync or post discontinuity)
50 
51     // clear all valid bits
52     pkt_valid.val = 0;
53 
54     // virtual address
55     v_addr.pkt_bits = 0;
56     v_addr.valid_bits = 0;
57     v_addr_ISA = 0;
58 
59     // timestamp
60     ts.bits_changed = 0;
61     ts.timestamp = 0;
62 
63     // per packet init
64     initNextPacket();
65 }
66 
67 void EtmV4ITrcPacket::initNextPacket()
68 {
69     // clear valid bits for elements that are only valid over a single packet.
70     pkt_valid.bits.cc_valid = 0;
71     pkt_valid.bits.commit_elem_valid = 0;
72     atom.num = 0;
73     context.updated = 0;
74     context.updated_v = 0;
75     context.updated_c = 0;
76     err_type = ETM4_PKT_I_NO_ERR_TYPE;
77 }
78 
79 // printing
80 void EtmV4ITrcPacket::toString(std::string &str) const
81 {
82     const char *name;
83     const char *desc;
84     std::string valStr, ctxtStr = "";
85 
86     name = packetTypeName(type, &desc);
87     str = name + (std::string)" : " + desc;
88 
89     // extended descriptions
90     switch (type)
91     {
92     case ETM4_PKT_I_BAD_SEQUENCE:
93     case ETM4_PKT_I_INCOMPLETE_EOT:
94     case ETM4_PKT_I_RESERVED_CFG:
95         name = packetTypeName(err_type, 0);
96         str += "[" + (std::string)name + "]";
97         break;
98 
99     case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
100     case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
101         contextStr(ctxtStr);
102     case ETM4_PKT_I_ADDR_L_32IS0:
103     case ETM4_PKT_I_ADDR_L_32IS1:
104         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 32) ? v_addr.pkt_bits : 0);
105         str += "; Addr=" + valStr + "; " + ctxtStr;
106         break;
107 
108     case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
109     case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
110         contextStr(ctxtStr);
111     case ETM4_PKT_I_ADDR_L_64IS0:
112     case ETM4_PKT_I_ADDR_L_64IS1:
113         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 64) ? v_addr.pkt_bits : 0);
114         str += "; Addr=" + valStr + "; " + ctxtStr;
115         break;
116 
117     case ETM4_PKT_I_CTXT:
118         contextStr(ctxtStr);
119         str += "; " + ctxtStr;
120         break;
121 
122     case ETM4_PKT_I_ADDR_S_IS0:
123     case ETM4_PKT_I_ADDR_S_IS1:
124         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, v_addr.pkt_bits);
125         str += "; Addr=" + valStr;
126         break;
127 
128     case ETM4_PKT_I_ADDR_MATCH:
129         addrMatchIdx(valStr);
130         str += ", " + valStr;
131         trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true);
132         str += "; Addr=" + valStr + "; " + ctxtStr;
133         break;
134 
135     case ETM4_PKT_I_ATOM_F1:
136     case ETM4_PKT_I_ATOM_F2:
137     case ETM4_PKT_I_ATOM_F3:
138     case ETM4_PKT_I_ATOM_F4:
139     case ETM4_PKT_I_ATOM_F5:
140     case ETM4_PKT_I_ATOM_F6:
141         atomSeq(valStr);
142         str += "; " + valStr;
143         break;
144 
145     case ETM4_PKT_I_EXCEPT:
146         exceptionInfo(valStr);
147         str += "; " + valStr;
148         break;
149 
150     case ETM4_PKT_I_TIMESTAMP:
151         {
152             std::ostringstream oss;
153             oss << "; Updated val = " << std::hex << "0x" << ts.timestamp;
154             if (pkt_valid.bits.cc_valid)
155                 oss << "; CC=" << std::hex << "0x" << cycle_count;
156             str += oss.str();
157         }
158         break;
159 
160     case ETM4_PKT_I_TRACE_INFO:
161         {
162             std::ostringstream oss;
163             oss << "; INFO=" << std::hex << "0x" << trace_info.val;
164             oss << " { CC." << std::dec << trace_info.bits.cc_enabled << " }";
165             if (trace_info.bits.cc_enabled)
166                 oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold;
167             str += oss.str();
168         }
169         break;
170 
171     case ETM4_PKT_I_CCNT_F1:
172     case ETM4_PKT_I_CCNT_F2:
173     case ETM4_PKT_I_CCNT_F3:
174         {
175             std::ostringstream oss;
176             oss << "; Count=" << std::hex << "0x" << cycle_count;
177             str += oss.str();
178         }
179         break;
180 
181     case ETM4_PKT_I_CANCEL_F1:
182         {
183             std::ostringstream oss;
184             oss << "; Cancel(" << std::dec << cancel_elements << ")";
185             str += oss.str();
186         }
187         break;
188 
189     case ETM4_PKT_I_CANCEL_F1_MISPRED:
190         {
191             std::ostringstream oss;
192             oss << "; Cancel(" << std::dec << cancel_elements << "), Mispredict";
193             str += oss.str();
194         }
195         break;
196 
197     case ETM4_PKT_I_MISPREDICT:
198         {
199             std::ostringstream oss;
200             oss << "; ";
201             if (atom.num) {
202                 atomSeq(valStr);
203                 oss << "Atom: " << valStr << ", ";
204             }
205             oss << "Mispredict";
206             str += oss.str();
207         }
208         break;
209 
210     case ETM4_PKT_I_CANCEL_F2:
211         {
212             std::ostringstream oss;
213             oss << "; ";
214             if (atom.num) {
215                 atomSeq(valStr);
216                 oss << "Atom: " << valStr << ", ";
217             }
218             oss << "Cancel(1), Mispredict";
219             str += oss.str();
220         }
221         break;
222 
223     case ETM4_PKT_I_CANCEL_F3:
224         {
225             std::ostringstream oss;
226             oss << "; ";
227             if (atom.num) {
228                 oss << "Atom: E, ";
229             }
230             oss << "Cancel(" << std::dec << cancel_elements << "), Mispredict";
231             str += oss.str();
232         }
233         break;
234 
235     case ETM4_PKT_I_COMMIT:
236         {
237             std::ostringstream oss;
238             oss << "; Commit(" << std::dec << commit_elements << ")";
239             str += oss.str();
240         }
241         break;
242 
243     case ETM4_PKT_I_Q:
244         {
245             std::ostringstream oss;
246             if (Q_pkt.count_present)
247             {
248                 oss << "; Count(" << std::dec << Q_pkt.q_count << ")";
249                 str += oss.str();
250             }
251             else
252                 str += "; Count(Unknown)";
253 
254             if (Q_pkt.addr_match)
255             {
256                 addrMatchIdx(valStr);
257                 str += "; " + valStr;
258             }
259 
260             if (Q_pkt.addr_present || Q_pkt.addr_match)
261             {
262                 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, (v_addr.pkt_bits < 64) ? v_addr.pkt_bits : 0);
263                 str += "; Addr=" + valStr;
264             }
265         }
266         break;
267     }
268 
269 }
270 
271 void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const
272 {
273     toString(str);  // TBD add in formatted response.
274 }
275 
276 const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **ppDesc) const
277 {
278     const char *pName = "I_UNKNOWN";
279     const char *pDesc = "Unknown Packet Header";
280 
281     switch(type)
282     {
283     case ETM4_PKT_I_NOTSYNC:
284         pName = "I_NOT_SYNC";
285         pDesc = "I Stream not synchronised";
286         break;
287 
288     case ETM4_PKT_I_INCOMPLETE_EOT:
289         pName = "I_INCOMPLETE_EOT";
290         pDesc = "Incomplete packet at end of trace.";
291         break;
292 
293     case ETM4_PKT_I_NO_ERR_TYPE:
294         pName = "I_NO_ERR_TYPE";
295         pDesc = "No Error Type.";
296         break;
297 
298     case ETM4_PKT_I_BAD_SEQUENCE:
299         pName = "I_BAD_SEQUENCE";
300         pDesc = "Invalid Sequence in packet.";
301         break;
302 
303     case ETM4_PKT_I_BAD_TRACEMODE:
304         pName = "I_BAD_TRACEMODE";
305         pDesc = "Invalid Packet for trace mode.";
306         break;
307 
308     case ETM4_PKT_I_RESERVED:
309         pName = "I_RESERVED";
310         pDesc = "Reserved Packet Header";
311         break;
312 
313     case ETM4_PKT_I_RESERVED_CFG:
314         pName = "I_RESERVED_CFG";
315         pDesc = "Reserved header for current configuration.";
316         break;
317 
318     case ETM4_PKT_I_EXTENSION:
319         pName = "I_EXTENSION";
320         pDesc = "Extension packet header.";
321         break;
322 
323     case ETM4_PKT_I_TRACE_INFO:
324         pName = "I_TRACE_INFO";
325         pDesc = "Trace Info.";
326         break;
327 
328     case ETM4_PKT_I_TIMESTAMP:
329         pName = "I_TIMESTAMP";
330         pDesc = "Timestamp.";
331         break;
332 
333     case ETM4_PKT_I_TRACE_ON:
334         pName = "I_TRACE_ON";
335         pDesc = "Trace On.";
336         break;
337 
338     case ETM4_PKT_I_FUNC_RET:
339         pName = "I_FUNC_RET";
340         pDesc = "V8M - function return.";
341         break;
342 
343     case ETM4_PKT_I_EXCEPT:
344         pName = "I_EXCEPT";
345         pDesc = "Exception.";
346         break;
347 
348     case ETM4_PKT_I_EXCEPT_RTN:
349         pName = "I_EXCEPT_RTN";
350         pDesc = "Exception Return.";
351         break;
352 
353     case ETM4_PKT_I_CCNT_F1:
354         pName = "I_CCNT_F1";
355         pDesc = "Cycle Count format 1.";
356         break;
357 
358     case ETM4_PKT_I_CCNT_F2:
359         pName = "I_CCNT_F2";
360         pDesc = "Cycle Count format 2.";
361         break;
362 
363     case ETM4_PKT_I_CCNT_F3:
364         pName = "I_CCNT_F3";
365         pDesc = "Cycle Count format 3.";
366         break;
367 
368     case ETM4_PKT_I_NUM_DS_MKR:
369         pName = "I_NUM_DS_MKR";
370         pDesc = "Data Synchronisation Marker - Numbered.";
371         break;
372 
373     case ETM4_PKT_I_UNNUM_DS_MKR:
374         pName = "I_UNNUM_DS_MKR";
375         pDesc = "Data Synchronisation Marker - Unnumbered.";
376         break;
377 
378     case ETM4_PKT_I_COMMIT:
379         pName = "I_COMMIT";
380         pDesc = "Commit";
381         break;
382 
383     case ETM4_PKT_I_CANCEL_F1:
384         pName = "I_CANCEL_F1";
385         pDesc = "Cancel Format 1.";
386         break;
387 
388     case ETM4_PKT_I_CANCEL_F1_MISPRED:
389         pName = "I_CANCEL_F1_MISPRED";
390         pDesc = "Cancel Format 1 + Mispredict.";
391         break;
392 
393 
394     case ETM4_PKT_I_MISPREDICT:
395         pName = "I_MISPREDICT";
396         pDesc = "Mispredict.";
397         break;
398 
399     case ETM4_PKT_I_CANCEL_F2:
400         pName = "I_CANCEL_F2";
401         pDesc = "Cancel Format 2.";
402         break;
403 
404     case ETM4_PKT_I_CANCEL_F3:
405         pName = "I_CANCEL_F3";
406         pDesc = "Cancel Format 3.";
407         break;
408 
409     case ETM4_PKT_I_COND_I_F2:
410         pName = "I_COND_I_F2";
411         pDesc = "Conditional Instruction, format 2.";
412         break;
413 
414     case ETM4_PKT_I_COND_FLUSH:
415         pName = "I_COND_FLUSH";
416         pDesc = "Conditional Flush.";
417         break;
418 
419     case ETM4_PKT_I_COND_RES_F4:
420         pName = "I_COND_RES_F4";
421         pDesc = "Conditional Result, format 4.";
422         break;
423 
424     case ETM4_PKT_I_COND_RES_F2:
425         pName = "I_COND_RES_F2";
426         pDesc = "Conditional Result, format 2.";
427         break;
428 
429     case ETM4_PKT_I_COND_RES_F3:
430         pName = "I_COND_RES_F3";
431         pDesc = "Conditional Result, format 3.";
432         break;
433 
434     case ETM4_PKT_I_COND_RES_F1:
435         pName = "I_COND_RES_F1";
436         pDesc = "Conditional Result, format 1.";
437         break;
438 
439     case ETM4_PKT_I_COND_I_F1:
440         pName = "I_COND_I_F1";
441         pDesc = "Conditional Instruction, format 1.";
442         break;
443 
444     case ETM4_PKT_I_COND_I_F3:
445         pName = "I_COND_I_F3";
446         pDesc = "Conditional Instruction, format 3.";
447         break;
448 
449     case ETM4_PKT_I_IGNORE:
450         pName = "I_IGNORE";
451         pDesc = "Ignore.";
452         break;
453 
454     case ETM4_PKT_I_EVENT:
455         pName = "I_EVENT";
456         pDesc = "Trace Event.";
457         break;
458 
459     case ETM4_PKT_I_CTXT:
460         pName = "I_CTXT";
461         pDesc = "Context Packet.";
462         break;
463 
464     case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
465         pName = "I_ADDR_CTXT_L_32IS0";
466         pDesc = "Address & Context, Long, 32 bit, IS0.";
467         break;
468 
469     case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
470         pName = "I_ADDR_CTXT_L_32IS1";
471         pDesc = "Address & Context, Long, 32 bit, IS0.";
472         break;
473 
474     case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
475         pName = "I_ADDR_CTXT_L_64IS0";
476         pDesc = "Address & Context, Long, 64 bit, IS0.";
477         break;
478 
479     case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
480         pName = "I_ADDR_CTXT_L_64IS1";
481         pDesc = "Address & Context, Long, 64 bit, IS1.";
482         break;
483 
484     case ETM4_PKT_I_ADDR_MATCH:
485         pName = "I_ADDR_MATCH";
486         pDesc = "Exact Address Match.";
487         break;
488 
489     case ETM4_PKT_I_ADDR_S_IS0:
490         pName = "I_ADDR_S_IS0";
491         pDesc = "Address, Short, IS0.";
492         break;
493 
494     case ETM4_PKT_I_ADDR_S_IS1:
495         pName = "I_ADDR_S_IS1";
496         pDesc = "Address, Short, IS1.";
497         break;
498 
499     case ETM4_PKT_I_ADDR_L_32IS0:
500         pName = "I_ADDR_L_32IS0";
501         pDesc = "Address, Long, 32 bit, IS0.";
502         break;
503 
504     case ETM4_PKT_I_ADDR_L_32IS1:
505         pName = "I_ADDR_L_32IS1";
506         pDesc = "Address, Long, 32 bit, IS1.";
507         break;
508 
509     case ETM4_PKT_I_ADDR_L_64IS0:
510         pName = "I_ADDR_L_64IS0";
511         pDesc = "Address, Long, 64 bit, IS0.";
512         break;
513 
514     case ETM4_PKT_I_ADDR_L_64IS1:
515         pName = "I_ADDR_L_64IS1";
516         pDesc = "Address, Long, 64 bit, IS1.";
517         break;
518 
519     case ETM4_PKT_I_Q:
520         pName = "I_Q";
521         pDesc = "Q Packet.";
522         break;
523 
524     case ETM4_PKT_I_ATOM_F6:
525         pName = "I_ATOM_F6";
526         pDesc = "Atom format 6.";
527         break;
528 
529     case ETM4_PKT_I_ATOM_F5:
530         pName = "I_ATOM_F5";
531         pDesc = "Atom format 5.";
532         break;
533 
534     case ETM4_PKT_I_ATOM_F2:
535         pName = "I_ATOM_F2";
536         pDesc = "Atom format 2.";
537         break;
538 
539     case ETM4_PKT_I_ATOM_F4:
540         pName = "I_ATOM_F4";
541         pDesc = "Atom format 4.";
542         break;
543 
544     case ETM4_PKT_I_ATOM_F1:
545         pName = "I_ATOM_F1";
546         pDesc = "Atom format 1.";
547         break;
548 
549     case ETM4_PKT_I_ATOM_F3:
550         pName = "I_ATOM_F3";
551         pDesc = "Atom format 3.";
552         break;
553 
554     case ETM4_PKT_I_ASYNC:
555         pName = "I_ASYNC";
556         pDesc = "Alignment Synchronisation.";
557         break;
558 
559     case ETM4_PKT_I_DISCARD:
560         pName = "I_DISCARD";
561         pDesc = "Discard.";
562         break;
563 
564     case ETM4_PKT_I_OVERFLOW:
565         pName = "I_OVERFLOW";
566         pDesc = "Overflow.";
567         break;
568 
569     default:
570         break;
571     }
572 
573     if(ppDesc) *ppDesc = pDesc;
574     return pName;
575 }
576 
577 void EtmV4ITrcPacket::contextStr(std::string &ctxtStr) const
578 {
579     ctxtStr = "";
580     if(pkt_valid.bits.context_valid)
581     {
582         std::ostringstream oss;
583         if(context.updated)
584         {
585             oss << "Ctxt: " << (context.SF ? "AArch64," : "AArch32, ") << "EL" << context.EL << ", " << (context.NS ? "NS; " : "S; ");
586             if(context.updated_c)
587             {
588                 oss << "CID=0x" << std::hex << std::setfill('0') << std::setw(8) << context.ctxtID << "; ";
589             }
590             if(context.updated_v)
591             {
592                 oss << "VMID=0x" << std::hex << std::setfill('0') << std::setw(4) << context.VMID << "; ";
593             }
594         }
595         else
596         {
597             oss << "Ctxt: Same";
598         }
599         ctxtStr = oss.str();
600     }
601 }
602 
603 void EtmV4ITrcPacket::atomSeq(std::string &valStr) const
604 {
605     std::ostringstream oss;
606     uint32_t bitpattern = atom.En_bits;
607     for(int i = 0; i < atom.num; i++)
608     {
609         oss << ((bitpattern & 0x1) ? "E" : "N");
610         bitpattern >>= 1;
611     }
612     valStr = oss.str();
613 }
614 
615 void EtmV4ITrcPacket::addrMatchIdx(std::string &valStr) const
616 {
617     std::ostringstream oss;
618     oss << "[" << (uint16_t)addr_exact_match_idx << "]";
619     valStr = oss.str();
620 }
621 
622 void EtmV4ITrcPacket::exceptionInfo(std::string &valStr) const
623 {
624     std::ostringstream oss;
625 
626     static const char *ARv8Excep[] = {
627         "PE Reset", "Debug Halt", "Call", "Trap",
628         "System Error", "Reserved", "Inst Debug", "Data Debug",
629         "Reserved", "Reserved", "Alignment", "Inst Fault",
630         "Data Fault", "Reserved", "IRQ", "FIQ"
631     };
632 
633     static const char *MExcep[] = {
634         "Reserved", "PE Reset", "NMI", "HardFault",
635         "MemManage", "BusFault", "UsageFault", "Reserved",
636         "Reserved","Reserved","Reserved","SVC",
637         "DebugMonitor", "Reserved","PendSV","SysTick",
638         "IRQ0","IRQ1","IRQ2","IRQ3",
639         "IRQ4","IRQ5","IRQ6","IRQ7",
640         "DebugHalt", "LazyFP Push", "Lockup", "Reserved",
641         "Reserved","Reserved","Reserved","Reserved"
642     };
643 
644     if(exception_info.m_type == 0)
645     {
646         if(exception_info.exceptionType < 0x10)
647             oss << " " << ARv8Excep[exception_info.exceptionType] << ";";
648         else
649             oss << " Reserved;";
650 
651     }
652     else
653     {
654         if(exception_info.exceptionType < 0x20)
655             oss << " " << MExcep[exception_info.exceptionType] << ";";
656         else if((exception_info.exceptionType >= 0x208) && (exception_info.exceptionType <= 0x3EF))
657             oss << " IRQ" << (int)(exception_info.exceptionType - 0x200) << ";";
658         else
659             oss << " Reserved;";
660         if(exception_info.m_fault_pending)
661             oss << " Fault Pending;";
662     }
663 
664     if(exception_info.addr_interp == 0x1)
665         oss << " Ret Addr Follows;";
666     else if(exception_info.addr_interp == 0x2)
667         oss << " Ret Addr Follows, Match Prev;";
668 
669     valStr = oss.str();
670 }
671 
672 EtmV4ITrcPacket &EtmV4ITrcPacket::operator =(const ocsd_etmv4_i_pkt* p_pkt)
673 {
674     *dynamic_cast<ocsd_etmv4_i_pkt *>(this) = *p_pkt;
675     return *this;
676 }
677 
678 /* End of File trc_pkt_elem_etmv4i.cpp */
679