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 for (int i = 0; i < 3; i++) 61 { 62 m_v_addr[i].pkt_bits = 0; 63 m_v_addr[i].size = VA_64BIT; 64 m_v_addr[i].val = 0; 65 m_v_addr[i].valid_bits = 0; 66 m_v_addr_ISA[i] = 0; 67 } 68 } 69 ~Etmv4PktAddrStack() {}; 70 71 void push(const ocsd_pkt_vaddr vaddr, const uint8_t isa) 72 { 73 m_v_addr[2] = m_v_addr[1]; 74 m_v_addr[1] = m_v_addr[0]; 75 m_v_addr[0] = vaddr; 76 m_v_addr_ISA[2] = m_v_addr_ISA[1]; 77 m_v_addr_ISA[1] = m_v_addr_ISA[0]; 78 m_v_addr_ISA[0] = isa; 79 } 80 81 void get_idx(const uint8_t idx, ocsd_pkt_vaddr &vaddr, uint8_t &isa) 82 { 83 if (idx < 3) 84 { 85 vaddr = m_v_addr[idx]; 86 isa = m_v_addr_ISA[idx]; 87 } 88 } 89 90 private: 91 ocsd_pkt_vaddr m_v_addr[3]; //!< most recently broadcast address packet 92 uint8_t m_v_addr_ISA[3]; 93 }; 94 95 /*! 96 * @class EtmV4ITrcPacket 97 * @brief ETMv4 Instuction Trace Protocol Packet. 98 * @ingroup trc_pkts 99 * 100 * This class represents a single ETMv4 data trace packet, along with intra packet state. 101 * 102 */ 103 class EtmV4ITrcPacket : public TrcPacketBase, public ocsd_etmv4_i_pkt, public trcPrintableElem 104 { 105 public: 106 EtmV4ITrcPacket(); 107 ~EtmV4ITrcPacket(); 108 109 EtmV4ITrcPacket &operator =(const ocsd_etmv4_i_pkt* p_pkt); 110 111 virtual const void *c_pkt() const { return (const ocsd_etmv4_i_pkt *)this; }; 112 113 // update interface - set packet values 114 void initStartState(); //!< Set to initial state - no intra packet state valid. Use on start of trace / discontinuities. 115 void initNextPacket(); //!< clear any single packet only flags / state. 116 117 void setType(const ocsd_etmv4_i_pkt_type pkt_type) { type = pkt_type; }; 118 void updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type); 119 120 void clearTraceInfo(); //!< clear all the trace info data prior to setting for new trace info packet. 121 void setTraceInfo(const uint32_t infoVal); 122 void setTraceInfoKey(const uint32_t keyVal); 123 void setTraceInfoSpec(const uint32_t specVal); 124 void setTraceInfoCyct(const uint32_t cyctVal); 125 126 void setTS(const uint64_t value, const uint8_t bits); 127 void setCycleCount(const uint32_t value); 128 void setCommitElements(const uint32_t commit_elem); 129 void setCancelElements(const uint32_t cancel_elem); 130 void setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num); 131 132 void setCondIF1(uint32_t const cond_key); 133 void setCondIF2(uint8_t const c_elem_idx); 134 void setCondIF3(uint8_t const num_c_elem, const bool finalElem); 135 136 void setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2], const bool set2Keys); 137 void setCondRF2(const uint8_t key_incr, const uint8_t token); 138 void setCondRF3(const uint16_t tokens); 139 void setCondRF4(const uint8_t token); 140 141 void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0); 142 void setContextVMID(const uint32_t VMID); 143 void setContextCID(const uint32_t CID); 144 145 void setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type); 146 147 void set64BitAddress(const uint64_t addr, const uint8_t IS); 148 void set32BitAddress(const uint32_t addr, const uint8_t IS); 149 void updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits); 150 void setAddressExactMatch(const uint8_t idx); 151 152 void setDataSyncMarker(const uint8_t dsm_val); 153 void setEvent(const uint8_t event_val); 154 155 void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type); 156 157 // packet status interface - get packet info. 158 const ocsd_etmv4_i_pkt_type getType() const { return type; }; 159 const ocsd_etmv4_i_pkt_type getErrType() const { return err_type; }; 160 161 //! return true if this packet has set the commit packet count. 162 const bool hasCommitElementsCount() const 163 { 164 return pkt_valid.bits.commit_elem_valid ? true : false; 165 }; 166 167 // trace info 168 const etmv4_trace_info_t &getTraceInfo() const { return trace_info; }; 169 const uint32_t getCCThreshold() const; 170 const uint32_t getP0Key() const; 171 const uint32_t getCurrSpecDepth() const; 172 173 // atom 174 const ocsd_pkt_atom &getAtom() const { return atom; }; 175 176 // context 177 const etmv4_context_t &getContext() const { return context; }; 178 179 // address 180 const uint8_t &getAddrMatch() const { return addr_exact_match_idx; }; 181 const ocsd_vaddr_t &getAddrVal() const { return v_addr.val; }; 182 const uint8_t &getAddrIS() const { return v_addr_ISA; }; 183 const bool getAddr64Bit() const { return v_addr.size == VA_64BIT; }; 184 185 // ts 186 const uint64_t getTS() const { return pkt_valid.bits.ts_valid ? ts.timestamp : 0; }; 187 188 // cc 189 const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; }; 190 191 // packet type 192 const bool isBadPacket() const; 193 194 // printing 195 virtual void toString(std::string &str) const; 196 virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const; 197 198 private: 199 const char *packetTypeName(const ocsd_etmv4_i_pkt_type type, const char **pDesc) const; 200 void contextStr(std::string &ctxtStr) const; 201 void atomSeq(std::string &valStr) const; 202 void addrMatchIdx(std::string &valStr) const; 203 void exceptionInfo(std::string &valStr) const; 204 205 void push_vaddr(); 206 void pop_vaddr_idx(const uint8_t idx); 207 208 Etmv4PktAddrStack m_addr_stack; 209 }; 210 211 inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type) 212 { 213 // set primary type to incoming error type, set packet err type to previous primary type. 214 err_type = type; 215 type = err_pkt_type; 216 } 217 218 inline void EtmV4ITrcPacket::clearTraceInfo() 219 { 220 pkt_valid.bits.ts_valid = 0; 221 pkt_valid.bits.trace_info_valid = 0; 222 pkt_valid.bits.p0_key_valid = 0; 223 pkt_valid.bits.spec_depth_valid = 0; 224 pkt_valid.bits.cc_thresh_valid = 0; 225 226 pkt_valid.bits.ts_valid = 0; // mark TS as invalid - must be re-updated after trace info. 227 } 228 229 inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal) 230 { 231 trace_info.val = infoVal; 232 pkt_valid.bits.trace_info_valid = 1; 233 } 234 235 inline void EtmV4ITrcPacket::setTraceInfoKey(const uint32_t keyVal) 236 { 237 p0_key = keyVal; 238 pkt_valid.bits.p0_key_valid = 1; 239 } 240 241 inline void EtmV4ITrcPacket::setTraceInfoSpec(const uint32_t specVal) 242 { 243 curr_spec_depth = specVal; 244 pkt_valid.bits.spec_depth_valid = 1; 245 } 246 247 inline void EtmV4ITrcPacket::setTraceInfoCyct(const uint32_t cyctVal) 248 { 249 cc_threshold = cyctVal; 250 pkt_valid.bits.cc_thresh_valid = 1; 251 } 252 253 inline void EtmV4ITrcPacket::setTS(const uint64_t value, const uint8_t bits) 254 { 255 uint64_t mask = (uint64_t)-1LL; 256 if(bits < 64) mask = (1ULL << bits) - 1; 257 ts.timestamp = (ts.timestamp & ~mask) | (value & mask); 258 ts.bits_changed = bits; 259 pkt_valid.bits.ts_valid = 1; 260 } 261 262 inline void EtmV4ITrcPacket::setCycleCount(const uint32_t value) 263 { 264 pkt_valid.bits.cc_valid = 1; 265 cycle_count = value; 266 } 267 268 inline void EtmV4ITrcPacket::setCommitElements(const uint32_t commit_elem) 269 { 270 pkt_valid.bits.commit_elem_valid = 1; 271 commit_elements = commit_elem; 272 } 273 274 inline const uint32_t EtmV4ITrcPacket::getCCThreshold() const 275 { 276 if(pkt_valid.bits.cc_thresh_valid) 277 return cc_threshold; 278 return 0; 279 } 280 281 inline const uint32_t EtmV4ITrcPacket::getP0Key() const 282 { 283 if(pkt_valid.bits.p0_key_valid) 284 return p0_key; 285 return 0; 286 } 287 288 inline const uint32_t EtmV4ITrcPacket::getCurrSpecDepth() const 289 { 290 if(pkt_valid.bits.spec_depth_valid) 291 return curr_spec_depth; 292 return 0; 293 } 294 295 inline void EtmV4ITrcPacket::setCancelElements(const uint32_t cancel_elem) 296 { 297 cancel_elements = cancel_elem; 298 } 299 300 inline void EtmV4ITrcPacket::setAtomPacket(const ocsd_pkt_atm_type type, const uint32_t En_bits, const uint8_t num) 301 { 302 if(type == ATOM_REPEAT) 303 { 304 uint32_t bit_patt = En_bits & 0x1; 305 if(bit_patt) 306 { 307 // none zero - all 1s 308 bit_patt = (bit_patt << num) - 1; 309 } 310 atom.En_bits = bit_patt; 311 } 312 else 313 atom.En_bits = En_bits; 314 atom.num = num; 315 } 316 317 inline void EtmV4ITrcPacket::setCondIF1(const uint32_t cond_key) 318 { 319 cond_instr.cond_key_set = 1; 320 cond_instr.f3_final_elem = 0; 321 cond_instr.f2_cond_incr = 0; 322 cond_instr.num_c_elem = 1; 323 cond_instr.cond_c_key = cond_key; 324 } 325 326 inline void EtmV4ITrcPacket::setCondIF2(const uint8_t c_elem_idx) 327 { 328 cond_instr.cond_key_set = 0; 329 cond_instr.f3_final_elem = 0; 330 switch(c_elem_idx & 0x3) 331 { 332 case 0: 333 cond_instr.f2_cond_incr = 1; 334 cond_instr.num_c_elem = 1; 335 break; 336 337 case 1: 338 cond_instr.f2_cond_incr = 0; 339 cond_instr.num_c_elem = 1; 340 break; 341 342 case 2: 343 cond_instr.f2_cond_incr = 1; 344 cond_instr.num_c_elem = 2; 345 break; 346 } 347 } 348 349 inline void EtmV4ITrcPacket::setCondIF3(const uint8_t num_c_elem, const bool finalElem) 350 { 351 cond_instr.cond_key_set = 0; 352 cond_instr.f3_final_elem = finalElem ? 1: 0; 353 cond_instr.f2_cond_incr = 0; 354 cond_instr.num_c_elem = num_c_elem; 355 } 356 357 inline void EtmV4ITrcPacket::setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2],const bool set2Keys) 358 { 359 cond_result.key_res_0_set = 1; 360 cond_result.cond_r_key_0 = key[0]; 361 cond_result.res_0 = res[0]; 362 cond_result.ci_0 = CI[0]; 363 364 if(set2Keys) 365 { 366 cond_result.key_res_1_set = 1; 367 cond_result.cond_r_key_1 = key[1]; 368 cond_result.res_1 = res[1]; 369 cond_result.ci_1 = CI[1]; 370 } 371 } 372 373 374 inline void EtmV4ITrcPacket::setCondRF2(const uint8_t key_incr, const uint8_t token) 375 { 376 cond_result.key_res_0_set = 0; 377 cond_result.key_res_1_set = 0; 378 cond_result.f2_key_incr = key_incr; 379 cond_result.f2f4_token = token; 380 } 381 382 inline void EtmV4ITrcPacket::setCondRF3(const uint16_t tokens) 383 { 384 cond_result.key_res_0_set = 0; 385 cond_result.key_res_1_set = 0; 386 cond_result.f3_tokens = tokens; 387 } 388 389 inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token) 390 { 391 cond_result.key_res_0_set = 0; 392 cond_result.key_res_1_set = 0; 393 cond_result.f2f4_token = token; 394 } 395 396 inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF) 397 { 398 pkt_valid.bits.context_valid = 1; 399 if(update) 400 { 401 context.updated = 1; 402 context.EL = EL; 403 context.NS = NS; 404 context.SF = SF; 405 } 406 } 407 408 inline void EtmV4ITrcPacket::setContextVMID(const uint32_t VMID) 409 { 410 pkt_valid.bits.context_valid = 1; 411 context.updated = 1; 412 context.VMID = VMID; 413 context.updated_v = 1; 414 } 415 416 inline void EtmV4ITrcPacket::setContextCID(const uint32_t CID) 417 { 418 pkt_valid.bits.context_valid = 1; 419 context.updated = 1; 420 context.ctxtID = CID; 421 context.updated_c = 1; 422 } 423 424 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) 425 { 426 exception_info.exceptionType = excep_type; 427 exception_info.addr_interp = addr_interp; 428 exception_info.m_fault_pending = m_fault_pending; 429 exception_info.m_type = m_type; 430 } 431 432 inline void EtmV4ITrcPacket::set64BitAddress(const uint64_t addr, const uint8_t IS) 433 { 434 v_addr.pkt_bits = 64; 435 v_addr.valid_bits = 64; 436 v_addr.size = VA_64BIT; 437 v_addr.val = addr; 438 v_addr_ISA = IS; 439 push_vaddr(); 440 } 441 442 inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t IS) 443 { 444 uint64_t mask = OCSD_BIT_MASK(32); 445 v_addr.pkt_bits = 32; 446 447 if (pkt_valid.bits.context_valid && context.SF) 448 v_addr.size = VA_64BIT; 449 else 450 { 451 v_addr.val &= 0xFFFFFFFF; // ensure vaddr is only 32 bits if not 64 bit 452 v_addr.size = VA_32BIT; 453 } 454 455 if (v_addr.valid_bits < 32) // may be 64 bit address so only set 32 if less 456 v_addr.valid_bits = 32; 457 458 v_addr.val = (v_addr.val & ~mask) | (addr & mask); 459 v_addr_ISA = IS; 460 push_vaddr(); 461 } 462 463 inline void EtmV4ITrcPacket::updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits) 464 { 465 ocsd_vaddr_t update_mask = OCSD_BIT_MASK(update_bits); 466 v_addr.pkt_bits = update_bits; 467 if(v_addr.valid_bits < update_bits) 468 v_addr.valid_bits = update_bits; 469 470 v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask); 471 v_addr_ISA = IS; 472 push_vaddr(); 473 } 474 475 inline void EtmV4ITrcPacket::setAddressExactMatch(const uint8_t idx) 476 { 477 addr_exact_match_idx = idx; 478 pop_vaddr_idx(idx); 479 push_vaddr(); 480 } 481 482 inline void EtmV4ITrcPacket::setDataSyncMarker(const uint8_t dsm_value) 483 { 484 dsm_val = dsm_value; 485 } 486 487 inline void EtmV4ITrcPacket::setEvent(const uint8_t event_value) 488 { 489 event_val = event_value; 490 } 491 492 inline void EtmV4ITrcPacket::setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type) 493 { 494 Q_pkt.q_count = count; 495 Q_pkt.q_type = type; 496 Q_pkt.count_present = has_count ? 1 : 0; 497 Q_pkt.addr_present = has_addr ? 1: 0; 498 Q_pkt.addr_match = addr_match ? 1 :0; 499 } 500 501 inline const bool EtmV4ITrcPacket::isBadPacket() const 502 { 503 return (type >= ETM4_PKT_I_BAD_SEQUENCE); 504 } 505 506 inline void EtmV4ITrcPacket::push_vaddr() 507 { 508 m_addr_stack.push(v_addr, v_addr_ISA); 509 } 510 511 inline void EtmV4ITrcPacket::pop_vaddr_idx(const uint8_t idx) 512 { 513 m_addr_stack.get_idx(idx, v_addr, v_addr_ISA); 514 } 515 516 /** @}*/ 517 518 #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED 519 520 /* End of File trc_pkt_elem_etmv4i.h */ 521