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