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 name = packetTypeName(err_type, 0); 95 str += "[" + (std::string)name + "]"; 96 break; 97 98 case ETM4_PKT_I_ADDR_CTXT_L_32IS0: 99 case ETM4_PKT_I_ADDR_CTXT_L_32IS1: 100 contextStr(ctxtStr); 101 case ETM4_PKT_I_ADDR_L_32IS0: 102 case ETM4_PKT_I_ADDR_L_32IS1: 103 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); 104 str += "; Addr=" + valStr + "; " + ctxtStr; 105 break; 106 107 case ETM4_PKT_I_ADDR_CTXT_L_64IS0: 108 case ETM4_PKT_I_ADDR_CTXT_L_64IS1: 109 contextStr(ctxtStr); 110 case ETM4_PKT_I_ADDR_L_64IS0: 111 case ETM4_PKT_I_ADDR_L_64IS1: 112 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); 113 str += "; Addr=" + valStr + "; " + ctxtStr; 114 break; 115 116 case ETM4_PKT_I_CTXT: 117 contextStr(ctxtStr); 118 str += "; " + ctxtStr; 119 break; 120 121 case ETM4_PKT_I_ADDR_S_IS0: 122 case ETM4_PKT_I_ADDR_S_IS1: 123 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true, v_addr.pkt_bits); 124 str += "; Addr=" + valStr; 125 break; 126 127 case ETM4_PKT_I_ADDR_MATCH: 128 addrMatchIdx(valStr); 129 str += ", " + valStr; 130 trcPrintableElem::getValStr(valStr, (v_addr.size == VA_64BIT) ? 64 : 32, v_addr.valid_bits, v_addr.val, true); 131 str += "; Addr=" + valStr + "; " + ctxtStr; 132 break; 133 134 case ETM4_PKT_I_ATOM_F1: 135 case ETM4_PKT_I_ATOM_F2: 136 case ETM4_PKT_I_ATOM_F3: 137 case ETM4_PKT_I_ATOM_F4: 138 case ETM4_PKT_I_ATOM_F5: 139 case ETM4_PKT_I_ATOM_F6: 140 atomSeq(valStr); 141 str += "; " + valStr; 142 break; 143 144 case ETM4_PKT_I_EXCEPT: 145 exceptionInfo(valStr); 146 str += "; " + valStr; 147 break; 148 149 case ETM4_PKT_I_TIMESTAMP: 150 { 151 std::ostringstream oss; 152 oss << "; Updated val = " << std::hex << "0x" << ts.timestamp; 153 if (pkt_valid.bits.cc_valid) 154 oss << "; CC=" << std::hex << "0x" << cycle_count; 155 str += oss.str(); 156 } 157 break; 158 159 case ETM4_PKT_I_TRACE_INFO: 160 { 161 std::ostringstream oss; 162 oss << "; INFO=" << std::hex << "0x" << trace_info.val; 163 if (trace_info.bits.cc_enabled) 164 oss << "; CC_THRESHOLD=" << std::hex << "0x" << cc_threshold; 165 str += oss.str(); 166 } 167 break; 168 169 case ETM4_PKT_I_CCNT_F1: 170 case ETM4_PKT_I_CCNT_F2: 171 case ETM4_PKT_I_CCNT_F3: 172 { 173 std::ostringstream oss; 174 oss << "; Count=" << std::hex << "0x" << cycle_count; 175 str += oss.str(); 176 } 177 break; 178 } 179 } 180 181 void EtmV4ITrcPacket::toStringFmt(const uint32_t fmtFlags, std::string &str) const 182 { 183 toString(str); // TBD add in formatted response. 184 } 185 186 const char *EtmV4ITrcPacket::packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **ppDesc) const 187 { 188 const char *pName = "I_RESERVED"; 189 const char *pDesc = "Reserved Packet Header"; 190 191 switch(type) 192 { 193 case ETM4_PKT_I_RESERVED: break; // default; 194 195 case ETM4_PKT_I_NOTSYNC: 196 pName = "I_NOT_SYNC"; 197 pDesc = "I Stream not synchronised"; 198 break; 199 200 case ETM4_PKT_I_BAD_SEQUENCE: 201 pName = "I_BAD_SEQUENCE"; 202 pDesc = "Invalid Sequence in packet."; 203 break; 204 205 case ETM4_PKT_I_BAD_TRACEMODE: 206 pName = "I_BAD_TRACEMODE"; 207 pDesc = "Invalid Packet for trace mode."; 208 break; 209 210 case ETM4_PKT_I_INCOMPLETE_EOT: 211 pName = "I_INCOMPLETE_EOT"; 212 pDesc = "Incomplete packet at end of trace."; 213 break; 214 215 case ETM4_PKT_I_NO_ERR_TYPE: 216 pName = "I_NO_ERR_TYPE"; 217 pDesc = "No Error Type."; 218 break; 219 220 case ETM4_PKT_I_EXTENSION: 221 pName = "I_EXTENSION"; 222 pDesc = "Extention packet header."; 223 break; 224 225 case ETM4_PKT_I_ADDR_CTXT_L_32IS0: 226 pName = "I_ADDR_CTXT_L_32IS0"; 227 pDesc = "Address & Context, Long, 32 bit, IS0."; 228 break; 229 230 case ETM4_PKT_I_ADDR_CTXT_L_32IS1: 231 pName = "I_ADDR_CTXT_L_32IS1"; 232 pDesc = "Address & Context, Long, 32 bit, IS0."; 233 break; 234 235 case ETM4_PKT_I_ADDR_CTXT_L_64IS0: 236 pName = "I_ADDR_CTXT_L_64IS0"; 237 pDesc = "Address & Context, Long, 64 bit, IS0."; 238 break; 239 240 case ETM4_PKT_I_ADDR_CTXT_L_64IS1: 241 pName = "I_ADDR_CTXT_L_64IS1"; 242 pDesc = "Address & Context, Long, 64 bit, IS1."; 243 break; 244 245 case ETM4_PKT_I_CTXT: 246 pName = "I_CTXT"; 247 pDesc = "Context Packet."; 248 break; 249 250 case ETM4_PKT_I_ADDR_MATCH: 251 pName = "I_ADDR_MATCH"; 252 pDesc = "Exact Address Match."; 253 break; 254 255 case ETM4_PKT_I_ADDR_L_32IS0: 256 pName = "I_ADDR_L_32IS0"; 257 pDesc = "Address, Long, 32 bit, IS0."; 258 break; 259 260 case ETM4_PKT_I_ADDR_L_32IS1: 261 pName = "I_ADDR_L_32IS1"; 262 pDesc = "Address, Long, 32 bit, IS1."; 263 break; 264 265 case ETM4_PKT_I_ADDR_L_64IS0: 266 pName = "I_ADDR_L_64IS0"; 267 pDesc = "Address, Long, 64 bit, IS0."; 268 break; 269 270 case ETM4_PKT_I_ADDR_L_64IS1: 271 pName = "I_ADDR_L_64IS1"; 272 pDesc = "Address, Long, 64 bit, IS1."; 273 break; 274 275 case ETM4_PKT_I_ADDR_S_IS0: 276 pName = "I_ADDR_S_IS0"; 277 pDesc = "Address, Short, IS0."; 278 break; 279 280 case ETM4_PKT_I_ADDR_S_IS1: 281 pName = "I_ADDR_S_IS1"; 282 pDesc = "Address, Short, IS1."; 283 break; 284 285 case ETM4_PKT_I_Q: 286 pName = "I_Q"; 287 pDesc = "Q Packet."; 288 break; 289 290 case ETM4_PKT_I_ATOM_F1: 291 pName = "I_ATOM_F1"; 292 pDesc = "Atom format 1."; 293 break; 294 295 case ETM4_PKT_I_ATOM_F2: 296 pName = "I_ATOM_F2"; 297 pDesc = "Atom format 2."; 298 break; 299 300 case ETM4_PKT_I_ATOM_F3: 301 pName = "I_ATOM_F3"; 302 pDesc = "Atom format 3."; 303 break; 304 305 case ETM4_PKT_I_ATOM_F4: 306 pName = "I_ATOM_F4"; 307 pDesc = "Atom format 4."; 308 break; 309 310 case ETM4_PKT_I_ATOM_F5: 311 pName = "I_ATOM_F5"; 312 pDesc = "Atom format 5."; 313 break; 314 315 case ETM4_PKT_I_ATOM_F6: 316 pName = "I_ATOM_F6"; 317 pDesc = "Atom format 6."; 318 break; 319 320 case ETM4_PKT_I_COND_FLUSH: 321 pName = "I_COND_FLUSH"; 322 pDesc = "Conditional Flush."; 323 break; 324 325 case ETM4_PKT_I_COND_I_F1: 326 pName = "I_COND_I_F1"; 327 pDesc = "Conditional Instruction, format 1."; 328 break; 329 330 case ETM4_PKT_I_COND_I_F2: 331 pName = "I_COND_I_F2"; 332 pDesc = "Conditional Instruction, format 2."; 333 break; 334 335 case ETM4_PKT_I_COND_I_F3: 336 pName = "I_COND_I_F3"; 337 pDesc = "Conditional Instruction, format 3."; 338 break; 339 340 case ETM4_PKT_I_COND_RES_F1: 341 pName = "I_COND_RES_F1"; 342 pDesc = "Conditional Result, format 1."; 343 break; 344 345 case ETM4_PKT_I_COND_RES_F2: 346 pName = "I_COND_RES_F2"; 347 pDesc = "Conditional Result, format 2."; 348 break; 349 350 case ETM4_PKT_I_COND_RES_F3: 351 pName = "I_COND_RES_F3"; 352 pDesc = "Conditional Result, format 3."; 353 break; 354 355 case ETM4_PKT_I_COND_RES_F4: 356 pName = "I_COND_RES_F4"; 357 pDesc = "Conditional Result, format 4."; 358 break; 359 360 case ETM4_PKT_I_CCNT_F1: 361 pName = "I_CCNT_F1"; 362 pDesc = "Cycle Count format 1."; 363 break; 364 365 case ETM4_PKT_I_CCNT_F2: 366 pName = "I_CCNT_F2"; 367 pDesc = "Cycle Count format 2."; 368 break; 369 370 case ETM4_PKT_I_CCNT_F3: 371 pName = "I_CCNT_F3"; 372 pDesc = "Cycle Count format 3."; 373 break; 374 375 case ETM4_PKT_I_NUM_DS_MKR: 376 pName = "I_NUM_DS_MKR"; 377 pDesc = "Data Synchronisation Marker - Numbered."; 378 break; 379 380 case ETM4_PKT_I_UNNUM_DS_MKR: 381 pName = "I_UNNUM_DS_MKR"; 382 pDesc = "Data Synchronisation Marker - Unnumbered."; 383 break; 384 385 case ETM4_PKT_I_EVENT: 386 pName = "I_EVENT"; 387 pDesc = "Trace Event."; 388 break; 389 390 case ETM4_PKT_I_EXCEPT: 391 pName = "I_EXCEPT"; 392 pDesc = "Exception."; 393 break; 394 395 case ETM4_PKT_I_EXCEPT_RTN: 396 pName = "I_EXCEPT_RTN"; 397 pDesc = "Exception Return."; 398 break; 399 400 case ETM4_PKT_I_TIMESTAMP: 401 pName = "I_TIMESTAMP"; 402 pDesc = "Timestamp."; 403 break; 404 405 case ETM4_PKT_I_CANCEL_F1: 406 pName = "I_CANCEL_F1"; 407 pDesc = "Cancel Format 1."; 408 break; 409 case ETM4_PKT_I_CANCEL_F2: 410 pName = "I_CANCEL_F2"; 411 pDesc = "Cancel Format 2."; 412 break; 413 414 case ETM4_PKT_I_CANCEL_F3: 415 pName = "I_CANCEL_F3"; 416 pDesc = "Cancel Format 3."; 417 break; 418 419 case ETM4_PKT_I_COMMIT: 420 pName = "I_COMMIT"; 421 pDesc = "Commit"; 422 break; 423 424 case ETM4_PKT_I_MISPREDICT: 425 pName = "I_MISPREDICT"; 426 pDesc = "Mispredict."; 427 break; 428 429 case ETM4_PKT_I_TRACE_INFO: 430 pName = "I_TRACE_INFO"; 431 pDesc = "Trace Info."; 432 break; 433 434 case ETM4_PKT_I_TRACE_ON: 435 pName = "I_TRACE_ON"; 436 pDesc = "Trace On."; 437 break; 438 439 case ETM4_PKT_I_ASYNC: 440 pName = "I_ASYNC"; 441 pDesc = "Alignment Synchronisation."; 442 break; 443 444 case ETM4_PKT_I_DISCARD: 445 pName = "I_DISCARD"; 446 pDesc = "Discard."; 447 break; 448 449 case ETM4_PKT_I_OVERFLOW: 450 pName = "I_OVERFLOW"; 451 pDesc = "Overflow."; 452 break; 453 } 454 455 if(ppDesc) *ppDesc = pDesc; 456 return pName; 457 } 458 459 void EtmV4ITrcPacket::contextStr(std::string &ctxtStr) const 460 { 461 ctxtStr = ""; 462 if(pkt_valid.bits.context_valid) 463 { 464 std::ostringstream oss; 465 if(context.updated) 466 { 467 oss << "Ctxt: " << (context.SF ? "AArch64," : "AArch32, ") << "EL" << context.EL << ", " << (context.NS ? "NS; " : "S; "); 468 if(context.updated_c) 469 { 470 oss << "CID=0x" << std::hex << std::setfill('0') << std::setw(8) << context.ctxtID << "; "; 471 } 472 if(context.updated_v) 473 { 474 oss << "VMID=0x" << std::hex << std::setfill('0') << std::setw(4) << context.VMID << "; "; 475 } 476 } 477 else 478 { 479 oss << "Ctxt: Same"; 480 } 481 ctxtStr = oss.str(); 482 } 483 } 484 485 void EtmV4ITrcPacket::atomSeq(std::string &valStr) const 486 { 487 std::ostringstream oss; 488 uint32_t bitpattern = atom.En_bits; 489 for(int i = 0; i < atom.num; i++) 490 { 491 oss << ((bitpattern & 0x1) ? "E" : "N"); 492 bitpattern >>= 1; 493 } 494 valStr = oss.str(); 495 } 496 497 void EtmV4ITrcPacket::addrMatchIdx(std::string &valStr) const 498 { 499 std::ostringstream oss; 500 oss << "[" << (uint16_t)addr_exact_match_idx << "]"; 501 valStr = oss.str(); 502 } 503 504 void EtmV4ITrcPacket::exceptionInfo(std::string &valStr) const 505 { 506 std::ostringstream oss; 507 508 static const char *ARv8Excep[] = { 509 "PE Reset", "Debug Halt", "Call", "Trap", 510 "System Error", "Reserved", "Inst Debug", "Data Debug", 511 "Reserved", "Reserved", "Alignment", "Inst Fault", 512 "Data Fault", "Reserved", "IRQ", "FIQ" 513 }; 514 515 static const char *MExcep[] = { 516 "Reserved", "PE Reset", "NMI", "HardFault", 517 "MemManage", "BusFault", "UsageFault", "Reserved", 518 "Reserved","Reserved","Reserved","SVC", 519 "DebugMonitor", "Reserved","PendSV","SysTick", 520 "IRQ0","IRQ1","IRQ2","IRQ3", 521 "IRQ4","IRQ5","IRQ6","IRQ7", 522 "DebugHalt", "LazyFP Push", "Lockup", "Reserved", 523 "Reserved","Reserved","Reserved","Reserved" 524 }; 525 526 if(exception_info.m_type == 0) 527 { 528 if(exception_info.exceptionType < 0x10) 529 oss << " " << ARv8Excep[exception_info.exceptionType] << ";"; 530 else 531 oss << " Reserved;"; 532 533 } 534 else 535 { 536 if(exception_info.exceptionType < 0x20) 537 oss << " " << MExcep[exception_info.exceptionType] << ";"; 538 else if((exception_info.exceptionType >= 0x208) && (exception_info.exceptionType <= 0x3EF)) 539 oss << " IRQ" << (int)(exception_info.exceptionType - 0x200) << ";"; 540 else 541 oss << " Reserved;"; 542 if(exception_info.m_fault_pending) 543 oss << " Fault Pending;"; 544 } 545 546 if(exception_info.addr_interp == 0x1) 547 oss << " Ret Addr Follows;"; 548 else if(exception_info.addr_interp == 0x2) 549 oss << " Ret Addr Follows, Match Prev;"; 550 551 valStr = oss.str(); 552 } 553 554 EtmV4ITrcPacket &EtmV4ITrcPacket::operator =(const ocsd_etmv4_i_pkt* p_pkt) 555 { 556 *dynamic_cast<ocsd_etmv4_i_pkt *>(this) = *p_pkt; 557 return *this; 558 } 559 560 /* End of File trc_pkt_elem_etmv4i.cpp */ 561