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