174fe6c29SRuslan Bukin /*
285f87cf4SRuslan Bukin  * Copyright (c) 2013-2019, Intel Corporation
374fe6c29SRuslan Bukin  *
474fe6c29SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
574fe6c29SRuslan Bukin  * modification, are permitted provided that the following conditions are met:
674fe6c29SRuslan Bukin  *
774fe6c29SRuslan Bukin  *  * Redistributions of source code must retain the above copyright notice,
874fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer.
974fe6c29SRuslan Bukin  *  * Redistributions in binary form must reproduce the above copyright notice,
1074fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer in the documentation
1174fe6c29SRuslan Bukin  *    and/or other materials provided with the distribution.
1274fe6c29SRuslan Bukin  *  * Neither the name of Intel Corporation nor the names of its contributors
1374fe6c29SRuslan Bukin  *    may be used to endorse or promote products derived from this software
1474fe6c29SRuslan Bukin  *    without specific prior written permission.
1574fe6c29SRuslan Bukin  *
1674fe6c29SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1774fe6c29SRuslan Bukin  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1874fe6c29SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1974fe6c29SRuslan Bukin  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2074fe6c29SRuslan Bukin  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2174fe6c29SRuslan Bukin  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2274fe6c29SRuslan Bukin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2374fe6c29SRuslan Bukin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2474fe6c29SRuslan Bukin  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2574fe6c29SRuslan Bukin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2674fe6c29SRuslan Bukin  * POSSIBILITY OF SUCH DAMAGE.
2774fe6c29SRuslan Bukin  */
2874fe6c29SRuslan Bukin 
2974fe6c29SRuslan Bukin #ifndef INTEL_PT_H
3074fe6c29SRuslan Bukin #define INTEL_PT_H
3174fe6c29SRuslan Bukin 
3274fe6c29SRuslan Bukin #include <stdint.h>
3374fe6c29SRuslan Bukin #include <string.h>
3474fe6c29SRuslan Bukin 
3574fe6c29SRuslan Bukin #ifdef __cplusplus
3674fe6c29SRuslan Bukin extern "C" {
3774fe6c29SRuslan Bukin #endif
3874fe6c29SRuslan Bukin 
3974fe6c29SRuslan Bukin 
4074fe6c29SRuslan Bukin /* Intel(R) Processor Trace (Intel PT) decoder library.
4174fe6c29SRuslan Bukin  *
4274fe6c29SRuslan Bukin  * This file is logically structured into the following sections:
4374fe6c29SRuslan Bukin  *
4474fe6c29SRuslan Bukin  * - Version
4574fe6c29SRuslan Bukin  * - Errors
4674fe6c29SRuslan Bukin  * - Configuration
4774fe6c29SRuslan Bukin  * - Packet encoder / decoder
4874fe6c29SRuslan Bukin  * - Query decoder
4974fe6c29SRuslan Bukin  * - Traced image
5074fe6c29SRuslan Bukin  * - Instruction flow decoder
5174fe6c29SRuslan Bukin  * - Block decoder
5274fe6c29SRuslan Bukin  */
5374fe6c29SRuslan Bukin 
5474fe6c29SRuslan Bukin 
5574fe6c29SRuslan Bukin 
5674fe6c29SRuslan Bukin struct pt_encoder;
5774fe6c29SRuslan Bukin struct pt_packet_decoder;
5874fe6c29SRuslan Bukin struct pt_query_decoder;
5974fe6c29SRuslan Bukin struct pt_insn_decoder;
6074fe6c29SRuslan Bukin struct pt_block_decoder;
6174fe6c29SRuslan Bukin 
6274fe6c29SRuslan Bukin 
6374fe6c29SRuslan Bukin 
6474fe6c29SRuslan Bukin /* A macro to mark functions as exported. */
6574fe6c29SRuslan Bukin #ifndef pt_export
6674fe6c29SRuslan Bukin #  if defined(__GNUC__)
6774fe6c29SRuslan Bukin #    define pt_export __attribute__((visibility("default")))
6874fe6c29SRuslan Bukin #  elif defined(_MSC_VER)
6974fe6c29SRuslan Bukin #    define pt_export __declspec(dllimport)
7074fe6c29SRuslan Bukin #  else
7174fe6c29SRuslan Bukin #    error "unknown compiler"
7274fe6c29SRuslan Bukin #  endif
7374fe6c29SRuslan Bukin #endif
7474fe6c29SRuslan Bukin 
7574fe6c29SRuslan Bukin 
7674fe6c29SRuslan Bukin 
7774fe6c29SRuslan Bukin /* Version. */
7874fe6c29SRuslan Bukin 
7974fe6c29SRuslan Bukin 
8074fe6c29SRuslan Bukin /** The header version. */
8174fe6c29SRuslan Bukin #define LIBIPT_VERSION_MAJOR ${PT_VERSION_MAJOR}
8274fe6c29SRuslan Bukin #define LIBIPT_VERSION_MINOR ${PT_VERSION_MINOR}
8385f87cf4SRuslan Bukin #define LIBIPT_VERSION_PATCH ${PT_VERSION_PATCH}
8474fe6c29SRuslan Bukin 
8574fe6c29SRuslan Bukin #define LIBIPT_VERSION ((LIBIPT_VERSION_MAJOR << 8) + LIBIPT_VERSION_MINOR)
8674fe6c29SRuslan Bukin 
8774fe6c29SRuslan Bukin 
8874fe6c29SRuslan Bukin /** The library version. */
8974fe6c29SRuslan Bukin struct pt_version {
9074fe6c29SRuslan Bukin 	/** Major version number. */
9174fe6c29SRuslan Bukin 	uint8_t major;
9274fe6c29SRuslan Bukin 
9374fe6c29SRuslan Bukin 	/** Minor version number. */
9474fe6c29SRuslan Bukin 	uint8_t minor;
9574fe6c29SRuslan Bukin 
9685f87cf4SRuslan Bukin 	/** Patch level. */
9785f87cf4SRuslan Bukin 	uint16_t patch;
9874fe6c29SRuslan Bukin 
9974fe6c29SRuslan Bukin 	/** Build number. */
10074fe6c29SRuslan Bukin 	uint32_t build;
10174fe6c29SRuslan Bukin 
10274fe6c29SRuslan Bukin 	/** Version extension. */
10374fe6c29SRuslan Bukin 	const char *ext;
10474fe6c29SRuslan Bukin };
10574fe6c29SRuslan Bukin 
10674fe6c29SRuslan Bukin 
10774fe6c29SRuslan Bukin /** Return the library version. */
10874fe6c29SRuslan Bukin extern pt_export struct pt_version pt_library_version(void);
10974fe6c29SRuslan Bukin 
11074fe6c29SRuslan Bukin 
11174fe6c29SRuslan Bukin 
11274fe6c29SRuslan Bukin /* Errors. */
11374fe6c29SRuslan Bukin 
11474fe6c29SRuslan Bukin 
11574fe6c29SRuslan Bukin 
11674fe6c29SRuslan Bukin /** Error codes. */
11774fe6c29SRuslan Bukin enum pt_error_code {
11874fe6c29SRuslan Bukin 	/* No error. Everything is OK. */
11974fe6c29SRuslan Bukin 	pte_ok,
12074fe6c29SRuslan Bukin 
12174fe6c29SRuslan Bukin 	/* Internal decoder error. */
12274fe6c29SRuslan Bukin 	pte_internal,
12374fe6c29SRuslan Bukin 
12474fe6c29SRuslan Bukin 	/* Invalid argument. */
12574fe6c29SRuslan Bukin 	pte_invalid,
12674fe6c29SRuslan Bukin 
12774fe6c29SRuslan Bukin 	/* Decoder out of sync. */
12874fe6c29SRuslan Bukin 	pte_nosync,
12974fe6c29SRuslan Bukin 
13074fe6c29SRuslan Bukin 	/* Unknown opcode. */
13174fe6c29SRuslan Bukin 	pte_bad_opc,
13274fe6c29SRuslan Bukin 
13374fe6c29SRuslan Bukin 	/* Unknown payload. */
13474fe6c29SRuslan Bukin 	pte_bad_packet,
13574fe6c29SRuslan Bukin 
13674fe6c29SRuslan Bukin 	/* Unexpected packet context. */
13774fe6c29SRuslan Bukin 	pte_bad_context,
13874fe6c29SRuslan Bukin 
13974fe6c29SRuslan Bukin 	/* Decoder reached end of trace stream. */
14074fe6c29SRuslan Bukin 	pte_eos,
14174fe6c29SRuslan Bukin 
14274fe6c29SRuslan Bukin 	/* No packet matching the query to be found. */
14374fe6c29SRuslan Bukin 	pte_bad_query,
14474fe6c29SRuslan Bukin 
14574fe6c29SRuslan Bukin 	/* Decoder out of memory. */
14674fe6c29SRuslan Bukin 	pte_nomem,
14774fe6c29SRuslan Bukin 
14874fe6c29SRuslan Bukin 	/* Bad configuration. */
14974fe6c29SRuslan Bukin 	pte_bad_config,
15074fe6c29SRuslan Bukin 
15174fe6c29SRuslan Bukin 	/* There is no IP. */
15274fe6c29SRuslan Bukin 	pte_noip,
15374fe6c29SRuslan Bukin 
15474fe6c29SRuslan Bukin 	/* The IP has been suppressed. */
15574fe6c29SRuslan Bukin 	pte_ip_suppressed,
15674fe6c29SRuslan Bukin 
15774fe6c29SRuslan Bukin 	/* There is no memory mapped at the requested address. */
15874fe6c29SRuslan Bukin 	pte_nomap,
15974fe6c29SRuslan Bukin 
16074fe6c29SRuslan Bukin 	/* An instruction could not be decoded. */
16174fe6c29SRuslan Bukin 	pte_bad_insn,
16274fe6c29SRuslan Bukin 
16374fe6c29SRuslan Bukin 	/* No wall-clock time is available. */
16474fe6c29SRuslan Bukin 	pte_no_time,
16574fe6c29SRuslan Bukin 
16674fe6c29SRuslan Bukin 	/* No core:bus ratio available. */
16774fe6c29SRuslan Bukin 	pte_no_cbr,
16874fe6c29SRuslan Bukin 
16974fe6c29SRuslan Bukin 	/* Bad traced image. */
17074fe6c29SRuslan Bukin 	pte_bad_image,
17174fe6c29SRuslan Bukin 
17274fe6c29SRuslan Bukin 	/* A locking error. */
17374fe6c29SRuslan Bukin 	pte_bad_lock,
17474fe6c29SRuslan Bukin 
17574fe6c29SRuslan Bukin 	/* The requested feature is not supported. */
17674fe6c29SRuslan Bukin 	pte_not_supported,
17774fe6c29SRuslan Bukin 
17874fe6c29SRuslan Bukin 	/* The return address stack is empty. */
17974fe6c29SRuslan Bukin 	pte_retstack_empty,
18074fe6c29SRuslan Bukin 
18174fe6c29SRuslan Bukin 	/* A compressed return is not indicated correctly by a taken branch. */
18274fe6c29SRuslan Bukin 	pte_bad_retcomp,
18374fe6c29SRuslan Bukin 
18474fe6c29SRuslan Bukin 	/* The current decoder state does not match the state in the trace. */
18574fe6c29SRuslan Bukin 	pte_bad_status_update,
18674fe6c29SRuslan Bukin 
18774fe6c29SRuslan Bukin 	/* The trace did not contain an expected enabled event. */
18874fe6c29SRuslan Bukin 	pte_no_enable,
18974fe6c29SRuslan Bukin 
19074fe6c29SRuslan Bukin 	/* An event was ignored. */
19174fe6c29SRuslan Bukin 	pte_event_ignored,
19274fe6c29SRuslan Bukin 
19374fe6c29SRuslan Bukin 	/* Something overflowed. */
19474fe6c29SRuslan Bukin 	pte_overflow,
19574fe6c29SRuslan Bukin 
19674fe6c29SRuslan Bukin 	/* A file handling error. */
19774fe6c29SRuslan Bukin 	pte_bad_file,
19874fe6c29SRuslan Bukin 
19974fe6c29SRuslan Bukin 	/* Unknown cpu. */
20074fe6c29SRuslan Bukin 	pte_bad_cpu
20174fe6c29SRuslan Bukin };
20274fe6c29SRuslan Bukin 
20374fe6c29SRuslan Bukin 
20474fe6c29SRuslan Bukin /** Decode a function return value into an pt_error_code. */
pt_errcode(int status)20574fe6c29SRuslan Bukin static inline enum pt_error_code pt_errcode(int status)
20674fe6c29SRuslan Bukin {
20774fe6c29SRuslan Bukin 	return (status >= 0) ? pte_ok : (enum pt_error_code) -status;
20874fe6c29SRuslan Bukin }
20974fe6c29SRuslan Bukin 
21074fe6c29SRuslan Bukin /** Return a human readable error string. */
21174fe6c29SRuslan Bukin extern pt_export const char *pt_errstr(enum pt_error_code);
21274fe6c29SRuslan Bukin 
21374fe6c29SRuslan Bukin 
21474fe6c29SRuslan Bukin 
21574fe6c29SRuslan Bukin /* Configuration. */
21674fe6c29SRuslan Bukin 
21774fe6c29SRuslan Bukin 
21874fe6c29SRuslan Bukin 
21974fe6c29SRuslan Bukin /** A cpu vendor. */
22074fe6c29SRuslan Bukin enum pt_cpu_vendor {
22174fe6c29SRuslan Bukin 	pcv_unknown,
22274fe6c29SRuslan Bukin 	pcv_intel
22374fe6c29SRuslan Bukin };
22474fe6c29SRuslan Bukin 
22574fe6c29SRuslan Bukin /** A cpu identifier. */
22674fe6c29SRuslan Bukin struct pt_cpu {
22774fe6c29SRuslan Bukin 	/** The cpu vendor. */
22874fe6c29SRuslan Bukin 	enum pt_cpu_vendor vendor;
22974fe6c29SRuslan Bukin 
23074fe6c29SRuslan Bukin 	/** The cpu family. */
23174fe6c29SRuslan Bukin 	uint16_t family;
23274fe6c29SRuslan Bukin 
23374fe6c29SRuslan Bukin 	/** The cpu model. */
23474fe6c29SRuslan Bukin 	uint8_t model;
23574fe6c29SRuslan Bukin 
23674fe6c29SRuslan Bukin 	/** The stepping. */
23774fe6c29SRuslan Bukin 	uint8_t stepping;
23874fe6c29SRuslan Bukin };
23974fe6c29SRuslan Bukin 
24074fe6c29SRuslan Bukin /** A collection of Intel PT errata. */
24174fe6c29SRuslan Bukin struct pt_errata {
24274fe6c29SRuslan Bukin 	/** BDM70: Intel(R) Processor Trace PSB+ Packets May Contain
24374fe6c29SRuslan Bukin 	 *         Unexpected Packets.
24474fe6c29SRuslan Bukin 	 *
24574fe6c29SRuslan Bukin 	 * Same as: SKD024, SKL021, KBL021.
24674fe6c29SRuslan Bukin 	 *
24774fe6c29SRuslan Bukin 	 * Some Intel Processor Trace packets should be issued only between
24874fe6c29SRuslan Bukin 	 * TIP.PGE and TIP.PGD packets.  Due to this erratum, when a TIP.PGE
24974fe6c29SRuslan Bukin 	 * packet is generated it may be preceded by a PSB+ that incorrectly
25074fe6c29SRuslan Bukin 	 * includes FUP and MODE.Exec packets.
25174fe6c29SRuslan Bukin 	 */
25274fe6c29SRuslan Bukin 	uint32_t bdm70:1;
25374fe6c29SRuslan Bukin 
25474fe6c29SRuslan Bukin 	/** BDM64: An Incorrect LBR or Intel(R) Processor Trace Packet May Be
25574fe6c29SRuslan Bukin 	 *         Recorded Following a Transactional Abort.
25674fe6c29SRuslan Bukin 	 *
25774fe6c29SRuslan Bukin 	 * Use of Intel(R) Transactional Synchronization Extensions (Intel(R)
25874fe6c29SRuslan Bukin 	 * TSX) may result in a transactional abort.  If an abort occurs
25974fe6c29SRuslan Bukin 	 * immediately following a branch instruction, an incorrect branch
26074fe6c29SRuslan Bukin 	 * target may be logged in an LBR (Last Branch Record) or in an Intel(R)
26174fe6c29SRuslan Bukin 	 * Processor Trace (Intel(R) PT) packet before the LBR or Intel PT
26274fe6c29SRuslan Bukin 	 * packet produced by the abort.
26374fe6c29SRuslan Bukin 	 */
26474fe6c29SRuslan Bukin 	uint32_t bdm64:1;
26574fe6c29SRuslan Bukin 
26674fe6c29SRuslan Bukin 	/** SKD007: Intel(R) PT Buffer Overflow May Result in Incorrect Packets.
26774fe6c29SRuslan Bukin 	 *
26874fe6c29SRuslan Bukin 	 * Same as: SKL049, KBL041.
26974fe6c29SRuslan Bukin 	 *
27074fe6c29SRuslan Bukin 	 * Under complex micro-architectural conditions, an Intel PT (Processor
27174fe6c29SRuslan Bukin 	 * Trace) OVF (Overflow) packet may be issued after the first byte of a
27274fe6c29SRuslan Bukin 	 * multi-byte CYC (Cycle Count) packet, instead of any remaining bytes
27374fe6c29SRuslan Bukin 	 * of the CYC.
27474fe6c29SRuslan Bukin 	 */
27574fe6c29SRuslan Bukin 	uint32_t skd007:1;
27674fe6c29SRuslan Bukin 
27774fe6c29SRuslan Bukin 	/** SKD022: VM Entry That Clears TraceEn May Generate a FUP.
27874fe6c29SRuslan Bukin 	 *
27974fe6c29SRuslan Bukin 	 * Same as: SKL024, KBL023.
28074fe6c29SRuslan Bukin 	 *
28174fe6c29SRuslan Bukin 	 * If VM entry clears Intel(R) PT (Intel Processor Trace)
28274fe6c29SRuslan Bukin 	 * IA32_RTIT_CTL.TraceEn (MSR 570H, bit 0) while PacketEn is 1 then a
28374fe6c29SRuslan Bukin 	 * FUP (Flow Update Packet) will precede the TIP.PGD (Target IP Packet,
28474fe6c29SRuslan Bukin 	 * Packet Generation Disable).  VM entry can clear TraceEn if the
28574fe6c29SRuslan Bukin 	 * VM-entry MSR-load area includes an entry for the IA32_RTIT_CTL MSR.
28674fe6c29SRuslan Bukin 	 */
28774fe6c29SRuslan Bukin 	uint32_t skd022:1;
28874fe6c29SRuslan Bukin 
28974fe6c29SRuslan Bukin 	/** SKD010: Intel(R) PT FUP May be Dropped After OVF.
29074fe6c29SRuslan Bukin 	 *
29174fe6c29SRuslan Bukin 	 * Same as: SKD014, SKL033, KBL030.
29274fe6c29SRuslan Bukin 	 *
29374fe6c29SRuslan Bukin 	 * Some Intel PT (Intel Processor Trace) OVF (Overflow) packets may not
29474fe6c29SRuslan Bukin 	 * be followed by a FUP (Flow Update Packet) or TIP.PGE (Target IP
29574fe6c29SRuslan Bukin 	 * Packet, Packet Generation Enable).
29674fe6c29SRuslan Bukin 	 */
29774fe6c29SRuslan Bukin 	uint32_t skd010:1;
29874fe6c29SRuslan Bukin 
29974fe6c29SRuslan Bukin 	/** SKL014: Intel(R) PT TIP.PGD May Not Have Target IP Payload.
30074fe6c29SRuslan Bukin 	 *
30174fe6c29SRuslan Bukin 	 * Same as: KBL014.
30274fe6c29SRuslan Bukin 	 *
30374fe6c29SRuslan Bukin 	 * When Intel PT (Intel Processor Trace) is enabled and a direct
30474fe6c29SRuslan Bukin 	 * unconditional branch clears IA32_RTIT_STATUS.FilterEn (MSR 571H, bit
30574fe6c29SRuslan Bukin 	 * 0), due to this erratum, the resulting TIP.PGD (Target IP Packet,
30674fe6c29SRuslan Bukin 	 * Packet Generation Disable) may not have an IP payload with the target
30774fe6c29SRuslan Bukin 	 * IP.
30874fe6c29SRuslan Bukin 	 */
30974fe6c29SRuslan Bukin 	uint32_t skl014:1;
31074fe6c29SRuslan Bukin 
31174fe6c29SRuslan Bukin 	/** APL12: Intel(R) PT OVF May Be Followed By An Unexpected FUP Packet.
31274fe6c29SRuslan Bukin 	 *
31374fe6c29SRuslan Bukin 	 * Certain Intel PT (Processor Trace) packets including FUPs (Flow
31474fe6c29SRuslan Bukin 	 * Update Packets), should be issued only between TIP.PGE (Target IP
31574fe6c29SRuslan Bukin 	 * Packet - Packet Generaton Enable) and TIP.PGD (Target IP Packet -
31674fe6c29SRuslan Bukin 	 * Packet Generation Disable) packets.  When outside a TIP.PGE/TIP.PGD
31774fe6c29SRuslan Bukin 	 * pair, as a result of IA32_RTIT_STATUS.FilterEn[0] (MSR 571H) being
31874fe6c29SRuslan Bukin 	 * cleared, an OVF (Overflow) packet may be unexpectedly followed by a
31974fe6c29SRuslan Bukin 	 * FUP.
32074fe6c29SRuslan Bukin 	 */
32174fe6c29SRuslan Bukin 	uint32_t apl12:1;
32274fe6c29SRuslan Bukin 
32374fe6c29SRuslan Bukin 	/** APL11: Intel(R) PT OVF Pakcet May Be Followed by TIP.PGD Packet
32474fe6c29SRuslan Bukin 	 *
32574fe6c29SRuslan Bukin 	 * If Intel PT (Processor Trace) encounters an internal buffer overflow
32674fe6c29SRuslan Bukin 	 * and generates an OVF (Overflow) packet just as IA32_RTIT_CTL (MSR
32774fe6c29SRuslan Bukin 	 * 570H) bit 0 (TraceEn) is cleared, or during a far transfer that
32874fe6c29SRuslan Bukin 	 * causes IA32_RTIT_STATUS.ContextEn[1] (MSR 571H) to be cleared, the
32974fe6c29SRuslan Bukin 	 * OVF may be followed by a TIP.PGD (Target Instruction Pointer - Packet
33074fe6c29SRuslan Bukin 	 * Generation Disable) packet.
33174fe6c29SRuslan Bukin 	 */
33274fe6c29SRuslan Bukin 	uint32_t apl11:1;
33374fe6c29SRuslan Bukin 
33485f87cf4SRuslan Bukin 	/** SKL168: Intel(R) PT CYC Packets Can be Dropped When Immediately
33585f87cf4SRuslan Bukin 	 *          Preceding PSB
33685f87cf4SRuslan Bukin 	 *
33785f87cf4SRuslan Bukin 	 * Due to a rare microarchitectural condition, generation of an Intel
33885f87cf4SRuslan Bukin 	 * PT (Processor Trace) PSB (Packet Stream Boundary) packet can cause a
33985f87cf4SRuslan Bukin 	 * single CYC (Cycle Count) packet, possibly along with an associated
34085f87cf4SRuslan Bukin 	 * MTC (Mini Time Counter) packet, to be dropped.
34185f87cf4SRuslan Bukin 	 */
34285f87cf4SRuslan Bukin 	uint32_t skl168:1;
34385f87cf4SRuslan Bukin 
34474fe6c29SRuslan Bukin 	/* Reserve a few bytes for the future. */
34574fe6c29SRuslan Bukin 	uint32_t reserved[15];
34674fe6c29SRuslan Bukin };
34774fe6c29SRuslan Bukin 
34874fe6c29SRuslan Bukin /** A collection of decoder-specific configuration flags. */
34974fe6c29SRuslan Bukin struct pt_conf_flags {
35074fe6c29SRuslan Bukin 	/** The decoder variant. */
35174fe6c29SRuslan Bukin 	union {
35274fe6c29SRuslan Bukin 		/** Flags for the block decoder. */
35374fe6c29SRuslan Bukin 		struct {
35474fe6c29SRuslan Bukin 			/** End a block after a call instruction. */
35574fe6c29SRuslan Bukin 			uint32_t end_on_call:1;
35674fe6c29SRuslan Bukin 
35774fe6c29SRuslan Bukin 			/** Enable tick events for timing updates. */
35874fe6c29SRuslan Bukin 			uint32_t enable_tick_events:1;
35974fe6c29SRuslan Bukin 
36074fe6c29SRuslan Bukin 			/** End a block after a jump instruction. */
36174fe6c29SRuslan Bukin 			uint32_t end_on_jump:1;
36285f87cf4SRuslan Bukin 
36385f87cf4SRuslan Bukin 			/** Preserve timing calibration on overflow. */
36485f87cf4SRuslan Bukin 			uint32_t keep_tcal_on_ovf:1;
36574fe6c29SRuslan Bukin 		} block;
36674fe6c29SRuslan Bukin 
36774fe6c29SRuslan Bukin 		/** Flags for the instruction flow decoder. */
36874fe6c29SRuslan Bukin 		struct {
36974fe6c29SRuslan Bukin 			/** Enable tick events for timing updates. */
37074fe6c29SRuslan Bukin 			uint32_t enable_tick_events:1;
37185f87cf4SRuslan Bukin 
37285f87cf4SRuslan Bukin 			/** Preserve timing calibration on overflow. */
37385f87cf4SRuslan Bukin 			uint32_t keep_tcal_on_ovf:1;
37474fe6c29SRuslan Bukin 		} insn;
37574fe6c29SRuslan Bukin 
37685f87cf4SRuslan Bukin 		/** Flags for the query decoder. */
37785f87cf4SRuslan Bukin 		struct {
37885f87cf4SRuslan Bukin 			/** Preserve timing calibration on overflow. */
37985f87cf4SRuslan Bukin 			uint32_t keep_tcal_on_ovf:1;
38085f87cf4SRuslan Bukin 		} query;
38185f87cf4SRuslan Bukin 
38274fe6c29SRuslan Bukin 		/* Reserve a few bytes for future extensions. */
38374fe6c29SRuslan Bukin 		uint32_t reserved[4];
38474fe6c29SRuslan Bukin 	} variant;
38574fe6c29SRuslan Bukin };
38674fe6c29SRuslan Bukin 
38774fe6c29SRuslan Bukin /** The address filter configuration. */
38874fe6c29SRuslan Bukin struct pt_conf_addr_filter {
38974fe6c29SRuslan Bukin 	/** The address filter configuration.
39074fe6c29SRuslan Bukin 	 *
39174fe6c29SRuslan Bukin 	 * This corresponds to the respective fields in IA32_RTIT_CTL MSR.
39274fe6c29SRuslan Bukin 	 */
39374fe6c29SRuslan Bukin 	union {
39474fe6c29SRuslan Bukin 		uint64_t addr_cfg;
39574fe6c29SRuslan Bukin 
39674fe6c29SRuslan Bukin 		struct {
39774fe6c29SRuslan Bukin 			uint32_t addr0_cfg:4;
39874fe6c29SRuslan Bukin 			uint32_t addr1_cfg:4;
39974fe6c29SRuslan Bukin 			uint32_t addr2_cfg:4;
40074fe6c29SRuslan Bukin 			uint32_t addr3_cfg:4;
40174fe6c29SRuslan Bukin 		} ctl;
40274fe6c29SRuslan Bukin 	} config;
40374fe6c29SRuslan Bukin 
40474fe6c29SRuslan Bukin 	/** The address ranges configuration.
40574fe6c29SRuslan Bukin 	 *
40674fe6c29SRuslan Bukin 	 * This corresponds to the IA32_RTIT_ADDRn_A/B MSRs.
40774fe6c29SRuslan Bukin 	 */
40874fe6c29SRuslan Bukin 	uint64_t addr0_a;
40974fe6c29SRuslan Bukin 	uint64_t addr0_b;
41074fe6c29SRuslan Bukin 	uint64_t addr1_a;
41174fe6c29SRuslan Bukin 	uint64_t addr1_b;
41274fe6c29SRuslan Bukin 	uint64_t addr2_a;
41374fe6c29SRuslan Bukin 	uint64_t addr2_b;
41474fe6c29SRuslan Bukin 	uint64_t addr3_a;
41574fe6c29SRuslan Bukin 	uint64_t addr3_b;
41674fe6c29SRuslan Bukin 
41774fe6c29SRuslan Bukin 	/* Reserve some space. */
41874fe6c29SRuslan Bukin 	uint64_t reserved[8];
41974fe6c29SRuslan Bukin };
42074fe6c29SRuslan Bukin 
42174fe6c29SRuslan Bukin /** An unknown packet. */
42274fe6c29SRuslan Bukin struct pt_packet_unknown;
42374fe6c29SRuslan Bukin 
42474fe6c29SRuslan Bukin /** An Intel PT decoder configuration.
42574fe6c29SRuslan Bukin  */
42674fe6c29SRuslan Bukin struct pt_config {
42774fe6c29SRuslan Bukin 	/** The size of the config structure in bytes. */
42874fe6c29SRuslan Bukin 	size_t size;
42974fe6c29SRuslan Bukin 
43074fe6c29SRuslan Bukin 	/** The trace buffer begin address. */
43174fe6c29SRuslan Bukin 	uint8_t *begin;
43274fe6c29SRuslan Bukin 
43374fe6c29SRuslan Bukin 	/** The trace buffer end address. */
43474fe6c29SRuslan Bukin 	uint8_t *end;
43574fe6c29SRuslan Bukin 
43674fe6c29SRuslan Bukin 	/** An optional callback for handling unknown packets.
43774fe6c29SRuslan Bukin 	 *
43874fe6c29SRuslan Bukin 	 * If \@callback is not NULL, it is called for any unknown opcode.
43974fe6c29SRuslan Bukin 	 */
44074fe6c29SRuslan Bukin 	struct {
44174fe6c29SRuslan Bukin 		/** The callback function.
44274fe6c29SRuslan Bukin 		 *
44374fe6c29SRuslan Bukin 		 * It shall decode the packet at \@pos into \@unknown.
44474fe6c29SRuslan Bukin 		 * It shall return the number of bytes read upon success.
44574fe6c29SRuslan Bukin 		 * It shall return a negative pt_error_code otherwise.
44674fe6c29SRuslan Bukin 		 * The below context is passed as \@context.
44774fe6c29SRuslan Bukin 		 */
44874fe6c29SRuslan Bukin 		int (*callback)(struct pt_packet_unknown *unknown,
44974fe6c29SRuslan Bukin 				const struct pt_config *config,
45074fe6c29SRuslan Bukin 				const uint8_t *pos, void *context);
45174fe6c29SRuslan Bukin 
45274fe6c29SRuslan Bukin 		/** The user-defined context for this configuration. */
45374fe6c29SRuslan Bukin 		void *context;
45474fe6c29SRuslan Bukin 	} decode;
45574fe6c29SRuslan Bukin 
45674fe6c29SRuslan Bukin 	/** The cpu on which Intel PT has been recorded. */
45774fe6c29SRuslan Bukin 	struct pt_cpu cpu;
45874fe6c29SRuslan Bukin 
45974fe6c29SRuslan Bukin 	/** The errata to apply when encoding or decoding Intel PT. */
46074fe6c29SRuslan Bukin 	struct pt_errata errata;
46174fe6c29SRuslan Bukin 
46274fe6c29SRuslan Bukin 	/* The CTC frequency.
46374fe6c29SRuslan Bukin 	 *
46474fe6c29SRuslan Bukin 	 * This is only required if MTC packets have been enabled in
46574fe6c29SRuslan Bukin 	 * IA32_RTIT_CTRL.MTCEn.
46674fe6c29SRuslan Bukin 	 */
46774fe6c29SRuslan Bukin 	uint32_t cpuid_0x15_eax, cpuid_0x15_ebx;
46874fe6c29SRuslan Bukin 
46974fe6c29SRuslan Bukin 	/* The MTC frequency as defined in IA32_RTIT_CTL.MTCFreq.
47074fe6c29SRuslan Bukin 	 *
47174fe6c29SRuslan Bukin 	 * This is only required if MTC packets have been enabled in
47274fe6c29SRuslan Bukin 	 * IA32_RTIT_CTRL.MTCEn.
47374fe6c29SRuslan Bukin 	 */
47474fe6c29SRuslan Bukin 	uint8_t mtc_freq;
47574fe6c29SRuslan Bukin 
47674fe6c29SRuslan Bukin 	/* The nominal frequency as defined in MSR_PLATFORM_INFO[15:8].
47774fe6c29SRuslan Bukin 	 *
47874fe6c29SRuslan Bukin 	 * This is only required if CYC packets have been enabled in
47974fe6c29SRuslan Bukin 	 * IA32_RTIT_CTRL.CYCEn.
48074fe6c29SRuslan Bukin 	 *
48174fe6c29SRuslan Bukin 	 * If zero, timing calibration will only be able to use MTC and CYC
48274fe6c29SRuslan Bukin 	 * packets.
48374fe6c29SRuslan Bukin 	 *
48474fe6c29SRuslan Bukin 	 * If not zero, timing calibration will also be able to use CBR
48574fe6c29SRuslan Bukin 	 * packets.
48674fe6c29SRuslan Bukin 	 */
48774fe6c29SRuslan Bukin 	uint8_t nom_freq;
48874fe6c29SRuslan Bukin 
48974fe6c29SRuslan Bukin 	/** A collection of decoder-specific flags. */
49074fe6c29SRuslan Bukin 	struct pt_conf_flags flags;
49174fe6c29SRuslan Bukin 
49274fe6c29SRuslan Bukin 	/** The address filter configuration. */
49374fe6c29SRuslan Bukin 	struct pt_conf_addr_filter addr_filter;
49474fe6c29SRuslan Bukin };
49574fe6c29SRuslan Bukin 
49674fe6c29SRuslan Bukin 
49774fe6c29SRuslan Bukin /** Zero-initialize an Intel PT configuration. */
pt_config_init(struct pt_config * config)49874fe6c29SRuslan Bukin static inline void pt_config_init(struct pt_config *config)
49974fe6c29SRuslan Bukin {
50074fe6c29SRuslan Bukin 	memset(config, 0, sizeof(*config));
50174fe6c29SRuslan Bukin 
50274fe6c29SRuslan Bukin 	config->size = sizeof(*config);
50374fe6c29SRuslan Bukin }
50474fe6c29SRuslan Bukin 
50574fe6c29SRuslan Bukin /** Determine errata for a given cpu.
50674fe6c29SRuslan Bukin  *
50774fe6c29SRuslan Bukin  * Updates \@errata based on \@cpu.
50874fe6c29SRuslan Bukin  *
50974fe6c29SRuslan Bukin  * Returns 0 on success, a negative error code otherwise.
51074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@errata or \@cpu is NULL.
51174fe6c29SRuslan Bukin  * Returns -pte_bad_cpu if \@cpu is not known.
51274fe6c29SRuslan Bukin  */
51374fe6c29SRuslan Bukin extern pt_export int pt_cpu_errata(struct pt_errata *errata,
51474fe6c29SRuslan Bukin 				   const struct pt_cpu *cpu);
51574fe6c29SRuslan Bukin 
51674fe6c29SRuslan Bukin 
51774fe6c29SRuslan Bukin 
51874fe6c29SRuslan Bukin /* Packet encoder / decoder. */
51974fe6c29SRuslan Bukin 
52074fe6c29SRuslan Bukin 
52174fe6c29SRuslan Bukin 
52274fe6c29SRuslan Bukin /** Intel PT packet types. */
52374fe6c29SRuslan Bukin enum pt_packet_type {
52474fe6c29SRuslan Bukin 	/* An invalid packet. */
52574fe6c29SRuslan Bukin 	ppt_invalid,
52674fe6c29SRuslan Bukin 
52774fe6c29SRuslan Bukin 	/* A packet decodable by the optional decoder callback. */
52874fe6c29SRuslan Bukin 	ppt_unknown,
52974fe6c29SRuslan Bukin 
53074fe6c29SRuslan Bukin 	/* Actual packets supported by this library. */
53174fe6c29SRuslan Bukin 	ppt_pad,
53274fe6c29SRuslan Bukin 	ppt_psb,
53374fe6c29SRuslan Bukin 	ppt_psbend,
53474fe6c29SRuslan Bukin 	ppt_fup,
53574fe6c29SRuslan Bukin 	ppt_tip,
53674fe6c29SRuslan Bukin 	ppt_tip_pge,
53774fe6c29SRuslan Bukin 	ppt_tip_pgd,
53874fe6c29SRuslan Bukin 	ppt_tnt_8,
53974fe6c29SRuslan Bukin 	ppt_tnt_64,
54074fe6c29SRuslan Bukin 	ppt_mode,
54174fe6c29SRuslan Bukin 	ppt_pip,
54274fe6c29SRuslan Bukin 	ppt_vmcs,
54374fe6c29SRuslan Bukin 	ppt_cbr,
54474fe6c29SRuslan Bukin 	ppt_tsc,
54574fe6c29SRuslan Bukin 	ppt_tma,
54674fe6c29SRuslan Bukin 	ppt_mtc,
54774fe6c29SRuslan Bukin 	ppt_cyc,
54874fe6c29SRuslan Bukin 	ppt_stop,
54974fe6c29SRuslan Bukin 	ppt_ovf,
55074fe6c29SRuslan Bukin 	ppt_mnt,
55174fe6c29SRuslan Bukin 	ppt_exstop,
55274fe6c29SRuslan Bukin 	ppt_mwait,
55374fe6c29SRuslan Bukin 	ppt_pwre,
55474fe6c29SRuslan Bukin 	ppt_pwrx,
55574fe6c29SRuslan Bukin 	ppt_ptw
55674fe6c29SRuslan Bukin };
55774fe6c29SRuslan Bukin 
55874fe6c29SRuslan Bukin /** The IP compression. */
55974fe6c29SRuslan Bukin enum pt_ip_compression {
56074fe6c29SRuslan Bukin 	/* The bits encode the payload size and the encoding scheme.
56174fe6c29SRuslan Bukin 	 *
56274fe6c29SRuslan Bukin 	 * No payload.  The IP has been suppressed.
56374fe6c29SRuslan Bukin 	 */
56474fe6c29SRuslan Bukin 	pt_ipc_suppressed	= 0x0,
56574fe6c29SRuslan Bukin 
56674fe6c29SRuslan Bukin 	/* Payload: 16 bits.  Update last IP. */
56774fe6c29SRuslan Bukin 	pt_ipc_update_16	= 0x01,
56874fe6c29SRuslan Bukin 
56974fe6c29SRuslan Bukin 	/* Payload: 32 bits.  Update last IP. */
57074fe6c29SRuslan Bukin 	pt_ipc_update_32	= 0x02,
57174fe6c29SRuslan Bukin 
57274fe6c29SRuslan Bukin 	/* Payload: 48 bits.  Sign extend to full address. */
57374fe6c29SRuslan Bukin 	pt_ipc_sext_48		= 0x03,
57474fe6c29SRuslan Bukin 
57574fe6c29SRuslan Bukin 	/* Payload: 48 bits.  Update last IP. */
57674fe6c29SRuslan Bukin 	pt_ipc_update_48	= 0x04,
57774fe6c29SRuslan Bukin 
57874fe6c29SRuslan Bukin 	/* Payload: 64 bits.  Full address. */
57974fe6c29SRuslan Bukin 	pt_ipc_full		= 0x06
58074fe6c29SRuslan Bukin };
58174fe6c29SRuslan Bukin 
58274fe6c29SRuslan Bukin /** An execution mode. */
58374fe6c29SRuslan Bukin enum pt_exec_mode {
58474fe6c29SRuslan Bukin 	ptem_unknown,
58574fe6c29SRuslan Bukin 	ptem_16bit,
58674fe6c29SRuslan Bukin 	ptem_32bit,
58774fe6c29SRuslan Bukin 	ptem_64bit
58874fe6c29SRuslan Bukin };
58974fe6c29SRuslan Bukin 
59074fe6c29SRuslan Bukin /** Mode packet leaves. */
59174fe6c29SRuslan Bukin enum pt_mode_leaf {
59274fe6c29SRuslan Bukin 	pt_mol_exec		= 0x00,
59374fe6c29SRuslan Bukin 	pt_mol_tsx		= 0x20
59474fe6c29SRuslan Bukin };
59574fe6c29SRuslan Bukin 
59674fe6c29SRuslan Bukin /** A TNT-8 or TNT-64 packet. */
59774fe6c29SRuslan Bukin struct pt_packet_tnt {
59874fe6c29SRuslan Bukin 	/** TNT payload bit size. */
59974fe6c29SRuslan Bukin 	uint8_t bit_size;
60074fe6c29SRuslan Bukin 
60174fe6c29SRuslan Bukin 	/** TNT payload excluding stop bit. */
60274fe6c29SRuslan Bukin 	uint64_t payload;
60374fe6c29SRuslan Bukin };
60474fe6c29SRuslan Bukin 
60574fe6c29SRuslan Bukin /** A packet with IP payload. */
60674fe6c29SRuslan Bukin struct pt_packet_ip {
60774fe6c29SRuslan Bukin 	/** IP compression. */
60874fe6c29SRuslan Bukin 	enum pt_ip_compression ipc;
60974fe6c29SRuslan Bukin 
61074fe6c29SRuslan Bukin 	/** Zero-extended payload ip. */
61174fe6c29SRuslan Bukin 	uint64_t ip;
61274fe6c29SRuslan Bukin };
61374fe6c29SRuslan Bukin 
61474fe6c29SRuslan Bukin /** A mode.exec packet. */
61574fe6c29SRuslan Bukin struct pt_packet_mode_exec {
61674fe6c29SRuslan Bukin 	/** The mode.exec csl bit. */
61774fe6c29SRuslan Bukin 	uint32_t csl:1;
61874fe6c29SRuslan Bukin 
61974fe6c29SRuslan Bukin 	/** The mode.exec csd bit. */
62074fe6c29SRuslan Bukin 	uint32_t csd:1;
62174fe6c29SRuslan Bukin };
62274fe6c29SRuslan Bukin 
62374fe6c29SRuslan Bukin static inline enum pt_exec_mode
pt_get_exec_mode(const struct pt_packet_mode_exec * packet)62474fe6c29SRuslan Bukin pt_get_exec_mode(const struct pt_packet_mode_exec *packet)
62574fe6c29SRuslan Bukin {
62674fe6c29SRuslan Bukin 	if (packet->csl)
62774fe6c29SRuslan Bukin 		return packet->csd ? ptem_unknown : ptem_64bit;
62874fe6c29SRuslan Bukin 	else
62974fe6c29SRuslan Bukin 		return packet->csd ? ptem_32bit : ptem_16bit;
63074fe6c29SRuslan Bukin }
63174fe6c29SRuslan Bukin 
63274fe6c29SRuslan Bukin static inline struct pt_packet_mode_exec
pt_set_exec_mode(enum pt_exec_mode mode)63374fe6c29SRuslan Bukin pt_set_exec_mode(enum pt_exec_mode mode)
63474fe6c29SRuslan Bukin {
63574fe6c29SRuslan Bukin 	struct pt_packet_mode_exec packet;
63674fe6c29SRuslan Bukin 
63774fe6c29SRuslan Bukin 	switch (mode) {
63874fe6c29SRuslan Bukin 	default:
63974fe6c29SRuslan Bukin 		packet.csl = 1;
64074fe6c29SRuslan Bukin 		packet.csd = 1;
64174fe6c29SRuslan Bukin 		break;
64274fe6c29SRuslan Bukin 
64374fe6c29SRuslan Bukin 	case ptem_64bit:
64474fe6c29SRuslan Bukin 		packet.csl = 1;
64574fe6c29SRuslan Bukin 		packet.csd = 0;
64674fe6c29SRuslan Bukin 		break;
64774fe6c29SRuslan Bukin 
64874fe6c29SRuslan Bukin 	case ptem_32bit:
64974fe6c29SRuslan Bukin 		packet.csl = 0;
65074fe6c29SRuslan Bukin 		packet.csd = 1;
65174fe6c29SRuslan Bukin 		break;
65274fe6c29SRuslan Bukin 
65374fe6c29SRuslan Bukin 	case ptem_16bit:
65474fe6c29SRuslan Bukin 		packet.csl = 0;
65574fe6c29SRuslan Bukin 		packet.csd = 0;
65674fe6c29SRuslan Bukin 		break;
65774fe6c29SRuslan Bukin 	}
65874fe6c29SRuslan Bukin 
65974fe6c29SRuslan Bukin 	return packet;
66074fe6c29SRuslan Bukin }
66174fe6c29SRuslan Bukin 
66274fe6c29SRuslan Bukin /** A mode.tsx packet. */
66374fe6c29SRuslan Bukin struct pt_packet_mode_tsx {
66474fe6c29SRuslan Bukin 	/** The mode.tsx intx bit. */
66574fe6c29SRuslan Bukin 	uint32_t intx:1;
66674fe6c29SRuslan Bukin 
66774fe6c29SRuslan Bukin 	/** The mode.tsx abrt bit. */
66874fe6c29SRuslan Bukin 	uint32_t abrt:1;
66974fe6c29SRuslan Bukin };
67074fe6c29SRuslan Bukin 
67174fe6c29SRuslan Bukin /** A mode packet. */
67274fe6c29SRuslan Bukin struct pt_packet_mode {
67374fe6c29SRuslan Bukin 	/** Mode leaf. */
67474fe6c29SRuslan Bukin 	enum pt_mode_leaf leaf;
67574fe6c29SRuslan Bukin 
67674fe6c29SRuslan Bukin 	/** Mode bits. */
67774fe6c29SRuslan Bukin 	union {
67874fe6c29SRuslan Bukin 		/** Packet: mode.exec. */
67974fe6c29SRuslan Bukin 		struct pt_packet_mode_exec exec;
68074fe6c29SRuslan Bukin 
68174fe6c29SRuslan Bukin 		/** Packet: mode.tsx. */
68274fe6c29SRuslan Bukin 		struct pt_packet_mode_tsx tsx;
68374fe6c29SRuslan Bukin 	} bits;
68474fe6c29SRuslan Bukin };
68574fe6c29SRuslan Bukin 
68674fe6c29SRuslan Bukin /** A PIP packet. */
68774fe6c29SRuslan Bukin struct pt_packet_pip {
68874fe6c29SRuslan Bukin 	/** The CR3 value. */
68974fe6c29SRuslan Bukin 	uint64_t cr3;
69074fe6c29SRuslan Bukin 
69174fe6c29SRuslan Bukin 	/** The non-root bit. */
69274fe6c29SRuslan Bukin 	uint32_t nr:1;
69374fe6c29SRuslan Bukin };
69474fe6c29SRuslan Bukin 
69574fe6c29SRuslan Bukin /** A TSC packet. */
69674fe6c29SRuslan Bukin struct pt_packet_tsc {
69774fe6c29SRuslan Bukin 	/** The TSC value. */
69874fe6c29SRuslan Bukin 	uint64_t tsc;
69974fe6c29SRuslan Bukin };
70074fe6c29SRuslan Bukin 
70174fe6c29SRuslan Bukin /** A CBR packet. */
70274fe6c29SRuslan Bukin struct pt_packet_cbr {
70374fe6c29SRuslan Bukin 	/** The core/bus cycle ratio. */
70474fe6c29SRuslan Bukin 	uint8_t ratio;
70574fe6c29SRuslan Bukin };
70674fe6c29SRuslan Bukin 
70774fe6c29SRuslan Bukin /** A TMA packet. */
70874fe6c29SRuslan Bukin struct pt_packet_tma {
70974fe6c29SRuslan Bukin 	/** The crystal clock tick counter value. */
71074fe6c29SRuslan Bukin 	uint16_t ctc;
71174fe6c29SRuslan Bukin 
71274fe6c29SRuslan Bukin 	/** The fast counter value. */
71374fe6c29SRuslan Bukin 	uint16_t fc;
71474fe6c29SRuslan Bukin };
71574fe6c29SRuslan Bukin 
71674fe6c29SRuslan Bukin /** A MTC packet. */
71774fe6c29SRuslan Bukin struct pt_packet_mtc {
71874fe6c29SRuslan Bukin 	/** The crystal clock tick counter value. */
71974fe6c29SRuslan Bukin 	uint8_t ctc;
72074fe6c29SRuslan Bukin };
72174fe6c29SRuslan Bukin 
72274fe6c29SRuslan Bukin /** A CYC packet. */
72374fe6c29SRuslan Bukin struct pt_packet_cyc {
72474fe6c29SRuslan Bukin 	/** The cycle counter value. */
72574fe6c29SRuslan Bukin 	uint64_t value;
72674fe6c29SRuslan Bukin };
72774fe6c29SRuslan Bukin 
72874fe6c29SRuslan Bukin /** A VMCS packet. */
72974fe6c29SRuslan Bukin struct pt_packet_vmcs {
73074fe6c29SRuslan Bukin        /* The VMCS Base Address (i.e. the shifted payload). */
73174fe6c29SRuslan Bukin 	uint64_t base;
73274fe6c29SRuslan Bukin };
73374fe6c29SRuslan Bukin 
73474fe6c29SRuslan Bukin /** A MNT packet. */
73574fe6c29SRuslan Bukin struct pt_packet_mnt {
73674fe6c29SRuslan Bukin 	/** The raw payload. */
73774fe6c29SRuslan Bukin 	uint64_t payload;
73874fe6c29SRuslan Bukin };
73974fe6c29SRuslan Bukin 
74074fe6c29SRuslan Bukin /** A EXSTOP packet. */
74174fe6c29SRuslan Bukin struct pt_packet_exstop {
74274fe6c29SRuslan Bukin 	/** A flag specifying the binding of the packet:
74374fe6c29SRuslan Bukin 	 *
74474fe6c29SRuslan Bukin 	 *   set:    binds to the next FUP.
74574fe6c29SRuslan Bukin 	 *   clear:  standalone.
74674fe6c29SRuslan Bukin 	 */
74774fe6c29SRuslan Bukin 	uint32_t ip:1;
74874fe6c29SRuslan Bukin };
74974fe6c29SRuslan Bukin 
75074fe6c29SRuslan Bukin /** A MWAIT packet. */
75174fe6c29SRuslan Bukin struct pt_packet_mwait {
75274fe6c29SRuslan Bukin 	/** The MWAIT hints (EAX). */
75374fe6c29SRuslan Bukin 	uint32_t hints;
75474fe6c29SRuslan Bukin 
75574fe6c29SRuslan Bukin 	/** The MWAIT extensions (ECX). */
75674fe6c29SRuslan Bukin 	uint32_t ext;
75774fe6c29SRuslan Bukin };
75874fe6c29SRuslan Bukin 
75974fe6c29SRuslan Bukin /** A PWRE packet. */
76074fe6c29SRuslan Bukin struct pt_packet_pwre {
76174fe6c29SRuslan Bukin 	/** The resolved thread C-state. */
76274fe6c29SRuslan Bukin 	uint8_t state;
76374fe6c29SRuslan Bukin 
76474fe6c29SRuslan Bukin 	/** The resolved thread sub C-state. */
76574fe6c29SRuslan Bukin 	uint8_t sub_state;
76674fe6c29SRuslan Bukin 
76774fe6c29SRuslan Bukin 	/** A flag indicating whether the C-state entry was initiated by h/w. */
76874fe6c29SRuslan Bukin 	uint32_t hw:1;
76974fe6c29SRuslan Bukin };
77074fe6c29SRuslan Bukin 
77174fe6c29SRuslan Bukin /** A PWRX packet. */
77274fe6c29SRuslan Bukin struct pt_packet_pwrx {
77374fe6c29SRuslan Bukin 	/** The core C-state at the time of the wake. */
77474fe6c29SRuslan Bukin 	uint8_t last;
77574fe6c29SRuslan Bukin 
77674fe6c29SRuslan Bukin 	/** The deepest core C-state achieved during sleep. */
77774fe6c29SRuslan Bukin 	uint8_t deepest;
77874fe6c29SRuslan Bukin 
77974fe6c29SRuslan Bukin 	/** The wake reason:
78074fe6c29SRuslan Bukin 	 *
78174fe6c29SRuslan Bukin 	 * - due to external interrupt received.
78274fe6c29SRuslan Bukin 	 */
78374fe6c29SRuslan Bukin 	uint32_t interrupt:1;
78474fe6c29SRuslan Bukin 
78574fe6c29SRuslan Bukin 	/** - due to store to monitored address. */
78674fe6c29SRuslan Bukin 	uint32_t store:1;
78774fe6c29SRuslan Bukin 
78874fe6c29SRuslan Bukin 	/** - due to h/w autonomous condition such as HDC. */
78974fe6c29SRuslan Bukin 	uint32_t autonomous:1;
79074fe6c29SRuslan Bukin };
79174fe6c29SRuslan Bukin 
79274fe6c29SRuslan Bukin /** A PTW packet. */
79374fe6c29SRuslan Bukin struct pt_packet_ptw {
79474fe6c29SRuslan Bukin 	/** The raw payload. */
79574fe6c29SRuslan Bukin 	uint64_t payload;
79674fe6c29SRuslan Bukin 
79774fe6c29SRuslan Bukin 	/** The payload size as encoded in the packet. */
79874fe6c29SRuslan Bukin 	uint8_t plc;
79974fe6c29SRuslan Bukin 
80074fe6c29SRuslan Bukin 	/** A flag saying whether a FUP is following PTW that provides
80174fe6c29SRuslan Bukin 	 * the IP of the corresponding PTWRITE instruction.
80274fe6c29SRuslan Bukin 	 */
80374fe6c29SRuslan Bukin 	uint32_t ip:1;
80474fe6c29SRuslan Bukin };
80574fe6c29SRuslan Bukin 
pt_ptw_size(uint8_t plc)80674fe6c29SRuslan Bukin static inline int pt_ptw_size(uint8_t plc)
80774fe6c29SRuslan Bukin {
80874fe6c29SRuslan Bukin 	switch (plc) {
80974fe6c29SRuslan Bukin 	case 0:
81074fe6c29SRuslan Bukin 		return 4;
81174fe6c29SRuslan Bukin 
81274fe6c29SRuslan Bukin 	case 1:
81374fe6c29SRuslan Bukin 		return 8;
81474fe6c29SRuslan Bukin 
81574fe6c29SRuslan Bukin 	case 2:
81674fe6c29SRuslan Bukin 	case 3:
81774fe6c29SRuslan Bukin 		return -pte_bad_packet;
81874fe6c29SRuslan Bukin 	}
81974fe6c29SRuslan Bukin 
82074fe6c29SRuslan Bukin 	return -pte_internal;
82174fe6c29SRuslan Bukin }
82274fe6c29SRuslan Bukin 
82374fe6c29SRuslan Bukin /** An unknown packet decodable by the optional decoder callback. */
82474fe6c29SRuslan Bukin struct pt_packet_unknown {
82574fe6c29SRuslan Bukin 	/** Pointer to the raw packet bytes. */
82674fe6c29SRuslan Bukin 	const uint8_t *packet;
82774fe6c29SRuslan Bukin 
82874fe6c29SRuslan Bukin 	/** Optional pointer to a user-defined structure. */
82974fe6c29SRuslan Bukin 	void *priv;
83074fe6c29SRuslan Bukin };
83174fe6c29SRuslan Bukin 
83274fe6c29SRuslan Bukin /** An Intel PT packet. */
83374fe6c29SRuslan Bukin struct pt_packet {
83474fe6c29SRuslan Bukin 	/** The type of the packet.
83574fe6c29SRuslan Bukin 	 *
83674fe6c29SRuslan Bukin 	 * This also determines the \@payload field.
83774fe6c29SRuslan Bukin 	 */
83874fe6c29SRuslan Bukin 	enum pt_packet_type type;
83974fe6c29SRuslan Bukin 
84074fe6c29SRuslan Bukin 	/** The size of the packet including opcode and payload. */
84174fe6c29SRuslan Bukin 	uint8_t size;
84274fe6c29SRuslan Bukin 
84374fe6c29SRuslan Bukin 	/** Packet specific data. */
84474fe6c29SRuslan Bukin 	union {
84574fe6c29SRuslan Bukin 		/** Packets: pad, ovf, psb, psbend, stop - no payload. */
84674fe6c29SRuslan Bukin 
84774fe6c29SRuslan Bukin 		/** Packet: tnt-8, tnt-64. */
84874fe6c29SRuslan Bukin 		struct pt_packet_tnt tnt;
84974fe6c29SRuslan Bukin 
85074fe6c29SRuslan Bukin 		/** Packet: tip, fup, tip.pge, tip.pgd. */
85174fe6c29SRuslan Bukin 		struct pt_packet_ip ip;
85274fe6c29SRuslan Bukin 
85374fe6c29SRuslan Bukin 		/** Packet: mode. */
85474fe6c29SRuslan Bukin 		struct pt_packet_mode mode;
85574fe6c29SRuslan Bukin 
85674fe6c29SRuslan Bukin 		/** Packet: pip. */
85774fe6c29SRuslan Bukin 		struct pt_packet_pip pip;
85874fe6c29SRuslan Bukin 
85974fe6c29SRuslan Bukin 		/** Packet: tsc. */
86074fe6c29SRuslan Bukin 		struct pt_packet_tsc tsc;
86174fe6c29SRuslan Bukin 
86274fe6c29SRuslan Bukin 		/** Packet: cbr. */
86374fe6c29SRuslan Bukin 		struct pt_packet_cbr cbr;
86474fe6c29SRuslan Bukin 
86574fe6c29SRuslan Bukin 		/** Packet: tma. */
86674fe6c29SRuslan Bukin 		struct pt_packet_tma tma;
86774fe6c29SRuslan Bukin 
86874fe6c29SRuslan Bukin 		/** Packet: mtc. */
86974fe6c29SRuslan Bukin 		struct pt_packet_mtc mtc;
87074fe6c29SRuslan Bukin 
87174fe6c29SRuslan Bukin 		/** Packet: cyc. */
87274fe6c29SRuslan Bukin 		struct pt_packet_cyc cyc;
87374fe6c29SRuslan Bukin 
87474fe6c29SRuslan Bukin 		/** Packet: vmcs. */
87574fe6c29SRuslan Bukin 		struct pt_packet_vmcs vmcs;
87674fe6c29SRuslan Bukin 
87774fe6c29SRuslan Bukin 		/** Packet: mnt. */
87874fe6c29SRuslan Bukin 		struct pt_packet_mnt mnt;
87974fe6c29SRuslan Bukin 
88074fe6c29SRuslan Bukin 		/** Packet: exstop. */
88174fe6c29SRuslan Bukin 		struct pt_packet_exstop exstop;
88274fe6c29SRuslan Bukin 
88374fe6c29SRuslan Bukin 		/** Packet: mwait. */
88474fe6c29SRuslan Bukin 		struct pt_packet_mwait mwait;
88574fe6c29SRuslan Bukin 
88674fe6c29SRuslan Bukin 		/** Packet: pwre. */
88774fe6c29SRuslan Bukin 		struct pt_packet_pwre pwre;
88874fe6c29SRuslan Bukin 
88974fe6c29SRuslan Bukin 		/** Packet: pwrx. */
89074fe6c29SRuslan Bukin 		struct pt_packet_pwrx pwrx;
89174fe6c29SRuslan Bukin 
89274fe6c29SRuslan Bukin 		/** Packet: ptw. */
89374fe6c29SRuslan Bukin 		struct pt_packet_ptw ptw;
89474fe6c29SRuslan Bukin 
89574fe6c29SRuslan Bukin 		/** Packet: unknown. */
89674fe6c29SRuslan Bukin 		struct pt_packet_unknown unknown;
89774fe6c29SRuslan Bukin 	} payload;
89874fe6c29SRuslan Bukin };
89974fe6c29SRuslan Bukin 
90074fe6c29SRuslan Bukin 
90174fe6c29SRuslan Bukin 
90274fe6c29SRuslan Bukin /* Packet encoder. */
90374fe6c29SRuslan Bukin 
90474fe6c29SRuslan Bukin 
90574fe6c29SRuslan Bukin 
90674fe6c29SRuslan Bukin /** Allocate an Intel PT packet encoder.
90774fe6c29SRuslan Bukin  *
90874fe6c29SRuslan Bukin  * The encoder will work on the buffer defined in \@config, it shall contain
90974fe6c29SRuslan Bukin  * raw trace data and remain valid for the lifetime of the encoder.
91074fe6c29SRuslan Bukin  *
91174fe6c29SRuslan Bukin  * The encoder starts at the beginning of the trace buffer.
91274fe6c29SRuslan Bukin  */
91374fe6c29SRuslan Bukin extern pt_export struct pt_encoder *
91474fe6c29SRuslan Bukin pt_alloc_encoder(const struct pt_config *config);
91574fe6c29SRuslan Bukin 
91674fe6c29SRuslan Bukin /** Free an Intel PT packet encoder.
91774fe6c29SRuslan Bukin  *
91874fe6c29SRuslan Bukin  * The \@encoder must not be used after a successful return.
91974fe6c29SRuslan Bukin  */
92074fe6c29SRuslan Bukin extern pt_export void pt_free_encoder(struct pt_encoder *encoder);
92174fe6c29SRuslan Bukin 
92274fe6c29SRuslan Bukin /** Hard set synchronization point of an Intel PT packet encoder.
92374fe6c29SRuslan Bukin  *
92474fe6c29SRuslan Bukin  * Synchronize \@encoder to \@offset within the trace buffer.
92574fe6c29SRuslan Bukin  *
92674fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
92774fe6c29SRuslan Bukin  *
92874fe6c29SRuslan Bukin  * Returns -pte_eos if the given offset is behind the end of the trace buffer.
92974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@encoder is NULL.
93074fe6c29SRuslan Bukin  */
93174fe6c29SRuslan Bukin extern pt_export int pt_enc_sync_set(struct pt_encoder *encoder,
93274fe6c29SRuslan Bukin 				     uint64_t offset);
93374fe6c29SRuslan Bukin 
93474fe6c29SRuslan Bukin /** Get the current packet encoder position.
93574fe6c29SRuslan Bukin  *
93674fe6c29SRuslan Bukin  * Fills the current \@encoder position into \@offset.
93774fe6c29SRuslan Bukin  *
93874fe6c29SRuslan Bukin  * This is useful for reporting errors.
93974fe6c29SRuslan Bukin  *
94074fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
94174fe6c29SRuslan Bukin  *
94274fe6c29SRuslan Bukin  * Returns -pte_invalid if \@encoder or \@offset is NULL.
94374fe6c29SRuslan Bukin  */
94474fe6c29SRuslan Bukin extern pt_export int pt_enc_get_offset(const struct pt_encoder *encoder,
94574fe6c29SRuslan Bukin 				       uint64_t *offset);
94674fe6c29SRuslan Bukin 
94774fe6c29SRuslan Bukin /* Return a pointer to \@encoder's configuration.
94874fe6c29SRuslan Bukin  *
94974fe6c29SRuslan Bukin  * Returns a non-null pointer on success, NULL if \@encoder is NULL.
95074fe6c29SRuslan Bukin  */
95174fe6c29SRuslan Bukin extern pt_export const struct pt_config *
95274fe6c29SRuslan Bukin pt_enc_get_config(const struct pt_encoder *encoder);
95374fe6c29SRuslan Bukin 
95474fe6c29SRuslan Bukin /** Encode an Intel PT packet.
95574fe6c29SRuslan Bukin  *
95674fe6c29SRuslan Bukin  * Writes \@packet at \@encoder's current position in the Intel PT buffer and
95774fe6c29SRuslan Bukin  * advances the \@encoder beyond the written packet.
95874fe6c29SRuslan Bukin  *
95974fe6c29SRuslan Bukin  * The \@packet.size field is ignored.
96074fe6c29SRuslan Bukin  *
96174fe6c29SRuslan Bukin  * In case of errors, the \@encoder is not advanced and nothing is written
96274fe6c29SRuslan Bukin  * into the Intel PT buffer.
96374fe6c29SRuslan Bukin  *
96474fe6c29SRuslan Bukin  * Returns the number of bytes written on success, a negative error code
96574fe6c29SRuslan Bukin  * otherwise.
96674fe6c29SRuslan Bukin  *
96774fe6c29SRuslan Bukin  * Returns -pte_bad_opc if \@packet.type is not known.
96874fe6c29SRuslan Bukin  * Returns -pte_bad_packet if \@packet's payload is invalid.
96974fe6c29SRuslan Bukin  * Returns -pte_eos if \@encoder reached the end of the Intel PT buffer.
97074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@encoder or \@packet is NULL.
97174fe6c29SRuslan Bukin  */
97274fe6c29SRuslan Bukin extern pt_export int pt_enc_next(struct pt_encoder *encoder,
97374fe6c29SRuslan Bukin 				 const struct pt_packet *packet);
97474fe6c29SRuslan Bukin 
97574fe6c29SRuslan Bukin 
97674fe6c29SRuslan Bukin 
97774fe6c29SRuslan Bukin /* Packet decoder. */
97874fe6c29SRuslan Bukin 
97974fe6c29SRuslan Bukin 
98074fe6c29SRuslan Bukin 
98174fe6c29SRuslan Bukin /** Allocate an Intel PT packet decoder.
98274fe6c29SRuslan Bukin  *
98374fe6c29SRuslan Bukin  * The decoder will work on the buffer defined in \@config, it shall contain
98474fe6c29SRuslan Bukin  * raw trace data and remain valid for the lifetime of the decoder.
98574fe6c29SRuslan Bukin  *
98674fe6c29SRuslan Bukin  * The decoder needs to be synchronized before it can be used.
98774fe6c29SRuslan Bukin  */
98874fe6c29SRuslan Bukin extern pt_export struct pt_packet_decoder *
98974fe6c29SRuslan Bukin pt_pkt_alloc_decoder(const struct pt_config *config);
99074fe6c29SRuslan Bukin 
99174fe6c29SRuslan Bukin /** Free an Intel PT packet decoder.
99274fe6c29SRuslan Bukin  *
99374fe6c29SRuslan Bukin  * The \@decoder must not be used after a successful return.
99474fe6c29SRuslan Bukin  */
99574fe6c29SRuslan Bukin extern pt_export void pt_pkt_free_decoder(struct pt_packet_decoder *decoder);
99674fe6c29SRuslan Bukin 
99774fe6c29SRuslan Bukin /** Synchronize an Intel PT packet decoder.
99874fe6c29SRuslan Bukin  *
99974fe6c29SRuslan Bukin  * Search for the next synchronization point in forward or backward direction.
100074fe6c29SRuslan Bukin  *
100174fe6c29SRuslan Bukin  * If \@decoder has not been synchronized, yet, the search is started at the
100274fe6c29SRuslan Bukin  * beginning of the trace buffer in case of forward synchronization and at the
100374fe6c29SRuslan Bukin  * end of the trace buffer in case of backward synchronization.
100474fe6c29SRuslan Bukin  *
100574fe6c29SRuslan Bukin  * Returns zero or a positive value on success, a negative error code otherwise.
100674fe6c29SRuslan Bukin  *
100774fe6c29SRuslan Bukin  * Returns -pte_eos if no further synchronization point is found.
100874fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
100974fe6c29SRuslan Bukin  */
101074fe6c29SRuslan Bukin extern pt_export int pt_pkt_sync_forward(struct pt_packet_decoder *decoder);
101174fe6c29SRuslan Bukin extern pt_export int pt_pkt_sync_backward(struct pt_packet_decoder *decoder);
101274fe6c29SRuslan Bukin 
101374fe6c29SRuslan Bukin /** Hard set synchronization point of an Intel PT decoder.
101474fe6c29SRuslan Bukin  *
101574fe6c29SRuslan Bukin  * Synchronize \@decoder to \@offset within the trace buffer.
101674fe6c29SRuslan Bukin  *
101774fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
101874fe6c29SRuslan Bukin  *
101974fe6c29SRuslan Bukin  * Returns -pte_eos if the given offset is behind the end of the trace buffer.
102074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
102174fe6c29SRuslan Bukin  */
102274fe6c29SRuslan Bukin extern pt_export int pt_pkt_sync_set(struct pt_packet_decoder *decoder,
102374fe6c29SRuslan Bukin 				     uint64_t offset);
102474fe6c29SRuslan Bukin 
102574fe6c29SRuslan Bukin /** Get the current decoder position.
102674fe6c29SRuslan Bukin  *
102774fe6c29SRuslan Bukin  * Fills the current \@decoder position into \@offset.
102874fe6c29SRuslan Bukin  *
102974fe6c29SRuslan Bukin  * This is useful for reporting errors.
103074fe6c29SRuslan Bukin  *
103174fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
103274fe6c29SRuslan Bukin  *
103374fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
103474fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
103574fe6c29SRuslan Bukin  */
103674fe6c29SRuslan Bukin extern pt_export int pt_pkt_get_offset(const struct pt_packet_decoder *decoder,
103774fe6c29SRuslan Bukin 				       uint64_t *offset);
103874fe6c29SRuslan Bukin 
103974fe6c29SRuslan Bukin /** Get the position of the last synchronization point.
104074fe6c29SRuslan Bukin  *
104174fe6c29SRuslan Bukin  * Fills the last synchronization position into \@offset.
104274fe6c29SRuslan Bukin  *
104374fe6c29SRuslan Bukin  * This is useful when splitting a trace stream for parallel decoding.
104474fe6c29SRuslan Bukin  *
104574fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
104674fe6c29SRuslan Bukin  *
104774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
104874fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
104974fe6c29SRuslan Bukin  */
105074fe6c29SRuslan Bukin extern pt_export int
105174fe6c29SRuslan Bukin pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
105274fe6c29SRuslan Bukin 		       uint64_t *offset);
105374fe6c29SRuslan Bukin 
105474fe6c29SRuslan Bukin /* Return a pointer to \@decoder's configuration.
105574fe6c29SRuslan Bukin  *
105674fe6c29SRuslan Bukin  * Returns a non-null pointer on success, NULL if \@decoder is NULL.
105774fe6c29SRuslan Bukin  */
105874fe6c29SRuslan Bukin extern pt_export const struct pt_config *
105974fe6c29SRuslan Bukin pt_pkt_get_config(const struct pt_packet_decoder *decoder);
106074fe6c29SRuslan Bukin 
106174fe6c29SRuslan Bukin /** Decode the next packet and advance the decoder.
106274fe6c29SRuslan Bukin  *
106374fe6c29SRuslan Bukin  * Decodes the packet at \@decoder's current position into \@packet and
106474fe6c29SRuslan Bukin  * adjusts the \@decoder's position by the number of bytes the packet had
106574fe6c29SRuslan Bukin  * consumed.
106674fe6c29SRuslan Bukin  *
106774fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_packet).
106874fe6c29SRuslan Bukin  *
106974fe6c29SRuslan Bukin  * Returns the number of bytes consumed on success, a negative error code
107074fe6c29SRuslan Bukin  * otherwise.
107174fe6c29SRuslan Bukin  *
107274fe6c29SRuslan Bukin  * Returns -pte_bad_opc if the packet is unknown.
107374fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
107474fe6c29SRuslan Bukin  * Returns -pte_eos if \@decoder reached the end of the Intel PT buffer.
107574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@packet is NULL.
107674fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
107774fe6c29SRuslan Bukin  */
107874fe6c29SRuslan Bukin extern pt_export int pt_pkt_next(struct pt_packet_decoder *decoder,
107974fe6c29SRuslan Bukin 				 struct pt_packet *packet, size_t size);
108074fe6c29SRuslan Bukin 
108174fe6c29SRuslan Bukin 
108274fe6c29SRuslan Bukin 
108374fe6c29SRuslan Bukin /* Query decoder. */
108474fe6c29SRuslan Bukin 
108574fe6c29SRuslan Bukin 
108674fe6c29SRuslan Bukin 
108774fe6c29SRuslan Bukin /** Decoder status flags. */
108874fe6c29SRuslan Bukin enum pt_status_flag {
108974fe6c29SRuslan Bukin 	/** There is an event pending. */
109074fe6c29SRuslan Bukin 	pts_event_pending	= 1 << 0,
109174fe6c29SRuslan Bukin 
109274fe6c29SRuslan Bukin 	/** The address has been suppressed. */
109374fe6c29SRuslan Bukin 	pts_ip_suppressed	= 1 << 1,
109474fe6c29SRuslan Bukin 
109574fe6c29SRuslan Bukin 	/** There is no more trace data available. */
109674fe6c29SRuslan Bukin 	pts_eos			= 1 << 2
109774fe6c29SRuslan Bukin };
109874fe6c29SRuslan Bukin 
109974fe6c29SRuslan Bukin /** Event types. */
110074fe6c29SRuslan Bukin enum pt_event_type {
110174fe6c29SRuslan Bukin 	/* Tracing has been enabled/disabled. */
110274fe6c29SRuslan Bukin 	ptev_enabled,
110374fe6c29SRuslan Bukin 	ptev_disabled,
110474fe6c29SRuslan Bukin 
110574fe6c29SRuslan Bukin 	/* Tracing has been disabled asynchronously. */
110674fe6c29SRuslan Bukin 	ptev_async_disabled,
110774fe6c29SRuslan Bukin 
110874fe6c29SRuslan Bukin 	/* An asynchronous branch, e.g. interrupt. */
110974fe6c29SRuslan Bukin 	ptev_async_branch,
111074fe6c29SRuslan Bukin 
111174fe6c29SRuslan Bukin 	/* A synchronous paging event. */
111274fe6c29SRuslan Bukin 	ptev_paging,
111374fe6c29SRuslan Bukin 
111474fe6c29SRuslan Bukin 	/* An asynchronous paging event. */
111574fe6c29SRuslan Bukin 	ptev_async_paging,
111674fe6c29SRuslan Bukin 
111774fe6c29SRuslan Bukin 	/* Trace overflow. */
111874fe6c29SRuslan Bukin 	ptev_overflow,
111974fe6c29SRuslan Bukin 
112074fe6c29SRuslan Bukin 	/* An execution mode change. */
112174fe6c29SRuslan Bukin 	ptev_exec_mode,
112274fe6c29SRuslan Bukin 
112374fe6c29SRuslan Bukin 	/* A transactional execution state change. */
112474fe6c29SRuslan Bukin 	ptev_tsx,
112574fe6c29SRuslan Bukin 
112674fe6c29SRuslan Bukin 	/* Trace Stop. */
112774fe6c29SRuslan Bukin 	ptev_stop,
112874fe6c29SRuslan Bukin 
112974fe6c29SRuslan Bukin 	/* A synchronous vmcs event. */
113074fe6c29SRuslan Bukin 	ptev_vmcs,
113174fe6c29SRuslan Bukin 
113274fe6c29SRuslan Bukin 	/* An asynchronous vmcs event. */
113374fe6c29SRuslan Bukin 	ptev_async_vmcs,
113474fe6c29SRuslan Bukin 
113574fe6c29SRuslan Bukin 	/* Execution has stopped. */
113674fe6c29SRuslan Bukin 	ptev_exstop,
113774fe6c29SRuslan Bukin 
113874fe6c29SRuslan Bukin 	/* An MWAIT operation completed. */
113974fe6c29SRuslan Bukin 	ptev_mwait,
114074fe6c29SRuslan Bukin 
114174fe6c29SRuslan Bukin 	/* A power state was entered. */
114274fe6c29SRuslan Bukin 	ptev_pwre,
114374fe6c29SRuslan Bukin 
114474fe6c29SRuslan Bukin 	/* A power state was exited. */
114574fe6c29SRuslan Bukin 	ptev_pwrx,
114674fe6c29SRuslan Bukin 
114774fe6c29SRuslan Bukin 	/* A PTWRITE event. */
114874fe6c29SRuslan Bukin 	ptev_ptwrite,
114974fe6c29SRuslan Bukin 
115074fe6c29SRuslan Bukin 	/* A timing event. */
115174fe6c29SRuslan Bukin 	ptev_tick,
115274fe6c29SRuslan Bukin 
115374fe6c29SRuslan Bukin 	/* A core:bus ratio event. */
115474fe6c29SRuslan Bukin 	ptev_cbr,
115574fe6c29SRuslan Bukin 
115674fe6c29SRuslan Bukin 	/* A maintenance event. */
115774fe6c29SRuslan Bukin 	ptev_mnt
115874fe6c29SRuslan Bukin };
115974fe6c29SRuslan Bukin 
116074fe6c29SRuslan Bukin /** An event. */
116174fe6c29SRuslan Bukin struct pt_event {
116274fe6c29SRuslan Bukin 	/** The type of the event. */
116374fe6c29SRuslan Bukin 	enum pt_event_type type;
116474fe6c29SRuslan Bukin 
116574fe6c29SRuslan Bukin 	/** A flag indicating that the event IP has been suppressed. */
116674fe6c29SRuslan Bukin 	uint32_t ip_suppressed:1;
116774fe6c29SRuslan Bukin 
116874fe6c29SRuslan Bukin 	/** A flag indicating that the event is for status update. */
116974fe6c29SRuslan Bukin 	uint32_t status_update:1;
117074fe6c29SRuslan Bukin 
117174fe6c29SRuslan Bukin 	/** A flag indicating that the event has timing information. */
117274fe6c29SRuslan Bukin 	uint32_t has_tsc:1;
117374fe6c29SRuslan Bukin 
117474fe6c29SRuslan Bukin 	/** The time stamp count of the event.
117574fe6c29SRuslan Bukin 	 *
117674fe6c29SRuslan Bukin 	 * This field is only valid if \@has_tsc is set.
117774fe6c29SRuslan Bukin 	 */
117874fe6c29SRuslan Bukin 	uint64_t tsc;
117974fe6c29SRuslan Bukin 
118074fe6c29SRuslan Bukin 	/** The number of lost mtc and cyc packets.
118174fe6c29SRuslan Bukin 	 *
118274fe6c29SRuslan Bukin 	 * This gives an idea about the quality of the \@tsc.  The more packets
118374fe6c29SRuslan Bukin 	 * were dropped, the less precise timing is.
118474fe6c29SRuslan Bukin 	 */
118574fe6c29SRuslan Bukin 	uint32_t lost_mtc;
118674fe6c29SRuslan Bukin 	uint32_t lost_cyc;
118774fe6c29SRuslan Bukin 
118874fe6c29SRuslan Bukin 	/* Reserved space for future extensions. */
118974fe6c29SRuslan Bukin 	uint64_t reserved[2];
119074fe6c29SRuslan Bukin 
119174fe6c29SRuslan Bukin 	/** Event specific data. */
119274fe6c29SRuslan Bukin 	union {
119374fe6c29SRuslan Bukin 		/** Event: enabled. */
119474fe6c29SRuslan Bukin 		struct {
119574fe6c29SRuslan Bukin 			/** The address at which tracing resumes. */
119674fe6c29SRuslan Bukin 			uint64_t ip;
119774fe6c29SRuslan Bukin 
119874fe6c29SRuslan Bukin 			/** A flag indicating that tracing resumes from the IP
119974fe6c29SRuslan Bukin 			 * at which tracing had been disabled before.
120074fe6c29SRuslan Bukin 			 */
120174fe6c29SRuslan Bukin 			uint32_t resumed:1;
120274fe6c29SRuslan Bukin 		} enabled;
120374fe6c29SRuslan Bukin 
120474fe6c29SRuslan Bukin 		/** Event: disabled. */
120574fe6c29SRuslan Bukin 		struct {
120674fe6c29SRuslan Bukin 			/** The destination of the first branch inside a
120774fe6c29SRuslan Bukin 			 * filtered area.
120874fe6c29SRuslan Bukin 			 *
120974fe6c29SRuslan Bukin 			 * This field is not valid if \@ip_suppressed is set.
121074fe6c29SRuslan Bukin 			 */
121174fe6c29SRuslan Bukin 			uint64_t ip;
121274fe6c29SRuslan Bukin 
121374fe6c29SRuslan Bukin 			/* The exact source ip needs to be determined using
121474fe6c29SRuslan Bukin 			 * disassembly and the filter configuration.
121574fe6c29SRuslan Bukin 			 */
121674fe6c29SRuslan Bukin 		} disabled;
121774fe6c29SRuslan Bukin 
121874fe6c29SRuslan Bukin 		/** Event: async disabled. */
121974fe6c29SRuslan Bukin 		struct {
122074fe6c29SRuslan Bukin 			/** The source address of the asynchronous branch that
122174fe6c29SRuslan Bukin 			 * disabled tracing.
122274fe6c29SRuslan Bukin 			 */
122374fe6c29SRuslan Bukin 			uint64_t at;
122474fe6c29SRuslan Bukin 
122574fe6c29SRuslan Bukin 			/** The destination of the first branch inside a
122674fe6c29SRuslan Bukin 			 * filtered area.
122774fe6c29SRuslan Bukin 			 *
122874fe6c29SRuslan Bukin 			 * This field is not valid if \@ip_suppressed is set.
122974fe6c29SRuslan Bukin 			 */
123074fe6c29SRuslan Bukin 			uint64_t ip;
123174fe6c29SRuslan Bukin 		} async_disabled;
123274fe6c29SRuslan Bukin 
123374fe6c29SRuslan Bukin 		/** Event: async branch. */
123474fe6c29SRuslan Bukin 		struct {
123574fe6c29SRuslan Bukin 			/** The branch source address. */
123674fe6c29SRuslan Bukin 			uint64_t from;
123774fe6c29SRuslan Bukin 
123874fe6c29SRuslan Bukin 			/** The branch destination address.
123974fe6c29SRuslan Bukin 			 *
124074fe6c29SRuslan Bukin 			 * This field is not valid if \@ip_suppressed is set.
124174fe6c29SRuslan Bukin 			 */
124274fe6c29SRuslan Bukin 			uint64_t to;
124374fe6c29SRuslan Bukin 		} async_branch;
124474fe6c29SRuslan Bukin 
124574fe6c29SRuslan Bukin 		/** Event: paging. */
124674fe6c29SRuslan Bukin 		struct {
124774fe6c29SRuslan Bukin 			/** The updated CR3 value.
124874fe6c29SRuslan Bukin 			 *
124974fe6c29SRuslan Bukin 			 * The lower 5 bit have been zeroed out.
125074fe6c29SRuslan Bukin 			 * The upper bits have been zeroed out depending on the
125174fe6c29SRuslan Bukin 			 * maximum possible address.
125274fe6c29SRuslan Bukin 			 */
125374fe6c29SRuslan Bukin 			uint64_t cr3;
125474fe6c29SRuslan Bukin 
125574fe6c29SRuslan Bukin 			/** A flag indicating whether the cpu is operating in
125674fe6c29SRuslan Bukin 			 * vmx non-root (guest) mode.
125774fe6c29SRuslan Bukin 			 */
125874fe6c29SRuslan Bukin 			uint32_t non_root:1;
125974fe6c29SRuslan Bukin 
126074fe6c29SRuslan Bukin 			/* The address at which the event is effective is
126174fe6c29SRuslan Bukin 			 * obvious from the disassembly.
126274fe6c29SRuslan Bukin 			 */
126374fe6c29SRuslan Bukin 		} paging;
126474fe6c29SRuslan Bukin 
126574fe6c29SRuslan Bukin 		/** Event: async paging. */
126674fe6c29SRuslan Bukin 		struct {
126774fe6c29SRuslan Bukin 			/** The updated CR3 value.
126874fe6c29SRuslan Bukin 			 *
126974fe6c29SRuslan Bukin 			 * The lower 5 bit have been zeroed out.
127074fe6c29SRuslan Bukin 			 * The upper bits have been zeroed out depending on the
127174fe6c29SRuslan Bukin 			 * maximum possible address.
127274fe6c29SRuslan Bukin 			 */
127374fe6c29SRuslan Bukin 			uint64_t cr3;
127474fe6c29SRuslan Bukin 
127574fe6c29SRuslan Bukin 			/** A flag indicating whether the cpu is operating in
127674fe6c29SRuslan Bukin 			 * vmx non-root (guest) mode.
127774fe6c29SRuslan Bukin 			 */
127874fe6c29SRuslan Bukin 			uint32_t non_root:1;
127974fe6c29SRuslan Bukin 
128074fe6c29SRuslan Bukin 			/** The address at which the event is effective. */
128174fe6c29SRuslan Bukin 			uint64_t ip;
128274fe6c29SRuslan Bukin 		} async_paging;
128374fe6c29SRuslan Bukin 
128474fe6c29SRuslan Bukin 		/** Event: overflow. */
128574fe6c29SRuslan Bukin 		struct {
128674fe6c29SRuslan Bukin 			/** The address at which tracing resumes after overflow.
128774fe6c29SRuslan Bukin 			 *
128874fe6c29SRuslan Bukin 			 * This field is not valid, if ip_suppressed is set.
128974fe6c29SRuslan Bukin 			 * In this case, the overflow resolved while tracing
129074fe6c29SRuslan Bukin 			 * was disabled.
129174fe6c29SRuslan Bukin 			 */
129274fe6c29SRuslan Bukin 			uint64_t ip;
129374fe6c29SRuslan Bukin 		} overflow;
129474fe6c29SRuslan Bukin 
129574fe6c29SRuslan Bukin 		/** Event: exec mode. */
129674fe6c29SRuslan Bukin 		struct {
129774fe6c29SRuslan Bukin 			/** The execution mode. */
129874fe6c29SRuslan Bukin 			enum pt_exec_mode mode;
129974fe6c29SRuslan Bukin 
130074fe6c29SRuslan Bukin 			/** The address at which the event is effective. */
130174fe6c29SRuslan Bukin 			uint64_t ip;
130274fe6c29SRuslan Bukin 		} exec_mode;
130374fe6c29SRuslan Bukin 
130474fe6c29SRuslan Bukin 		/** Event: tsx. */
130574fe6c29SRuslan Bukin 		struct {
130674fe6c29SRuslan Bukin 			/** The address at which the event is effective.
130774fe6c29SRuslan Bukin 			 *
130874fe6c29SRuslan Bukin 			 * This field is not valid if \@ip_suppressed is set.
130974fe6c29SRuslan Bukin 			 */
131074fe6c29SRuslan Bukin 			uint64_t ip;
131174fe6c29SRuslan Bukin 
131274fe6c29SRuslan Bukin 			/** A flag indicating speculative execution mode. */
131374fe6c29SRuslan Bukin 			uint32_t speculative:1;
131474fe6c29SRuslan Bukin 
131574fe6c29SRuslan Bukin 			/** A flag indicating speculative execution aborts. */
131674fe6c29SRuslan Bukin 			uint32_t aborted:1;
131774fe6c29SRuslan Bukin 		} tsx;
131874fe6c29SRuslan Bukin 
131974fe6c29SRuslan Bukin 		/** Event: vmcs. */
132074fe6c29SRuslan Bukin 		struct {
132174fe6c29SRuslan Bukin 			/** The VMCS base address.
132274fe6c29SRuslan Bukin 			 *
132374fe6c29SRuslan Bukin 			 * The address is zero-extended with the lower 12 bits
132474fe6c29SRuslan Bukin 			 * all zero.
132574fe6c29SRuslan Bukin 			 */
132674fe6c29SRuslan Bukin 			uint64_t base;
132774fe6c29SRuslan Bukin 
132874fe6c29SRuslan Bukin 			/* The new VMCS base address should be stored and
132974fe6c29SRuslan Bukin 			 * applied on subsequent VM entries.
133074fe6c29SRuslan Bukin 			 */
133174fe6c29SRuslan Bukin 		} vmcs;
133274fe6c29SRuslan Bukin 
133374fe6c29SRuslan Bukin 		/** Event: async vmcs. */
133474fe6c29SRuslan Bukin 		struct {
133574fe6c29SRuslan Bukin 			/** The VMCS base address.
133674fe6c29SRuslan Bukin 			 *
133774fe6c29SRuslan Bukin 			 * The address is zero-extended with the lower 12 bits
133874fe6c29SRuslan Bukin 			 * all zero.
133974fe6c29SRuslan Bukin 			 */
134074fe6c29SRuslan Bukin 			uint64_t base;
134174fe6c29SRuslan Bukin 
134274fe6c29SRuslan Bukin 			/** The address at which the event is effective. */
134374fe6c29SRuslan Bukin 			uint64_t ip;
134474fe6c29SRuslan Bukin 
134574fe6c29SRuslan Bukin 			/* An async paging event that binds to the same IP
134674fe6c29SRuslan Bukin 			 * will always succeed this async vmcs event.
134774fe6c29SRuslan Bukin 			 */
134874fe6c29SRuslan Bukin 		} async_vmcs;
134974fe6c29SRuslan Bukin 
135074fe6c29SRuslan Bukin 		/** Event: execution stopped. */
135174fe6c29SRuslan Bukin 		struct {
135274fe6c29SRuslan Bukin 			/** The address at which execution has stopped.  This is
135374fe6c29SRuslan Bukin 			 * the last instruction that did not complete.
135474fe6c29SRuslan Bukin 			 *
135574fe6c29SRuslan Bukin 			 * This field is not valid, if \@ip_suppressed is set.
135674fe6c29SRuslan Bukin 			 */
135774fe6c29SRuslan Bukin 			uint64_t ip;
135874fe6c29SRuslan Bukin 		} exstop;
135974fe6c29SRuslan Bukin 
136074fe6c29SRuslan Bukin 		/** Event: mwait. */
136174fe6c29SRuslan Bukin 		struct {
136274fe6c29SRuslan Bukin 			/** The address of the instruction causing the mwait.
136374fe6c29SRuslan Bukin 			 *
136474fe6c29SRuslan Bukin 			 * This field is not valid, if \@ip_suppressed is set.
136574fe6c29SRuslan Bukin 			 */
136674fe6c29SRuslan Bukin 			uint64_t ip;
136774fe6c29SRuslan Bukin 
136874fe6c29SRuslan Bukin 			/** The mwait hints (eax).
136974fe6c29SRuslan Bukin 			 *
137074fe6c29SRuslan Bukin 			 * Reserved bits are undefined.
137174fe6c29SRuslan Bukin 			 */
137274fe6c29SRuslan Bukin 			uint32_t hints;
137374fe6c29SRuslan Bukin 
137474fe6c29SRuslan Bukin 			/** The mwait extensions (ecx).
137574fe6c29SRuslan Bukin 			 *
137674fe6c29SRuslan Bukin 			 * Reserved bits are undefined.
137774fe6c29SRuslan Bukin 			 */
137874fe6c29SRuslan Bukin 			uint32_t ext;
137974fe6c29SRuslan Bukin 		} mwait;
138074fe6c29SRuslan Bukin 
138174fe6c29SRuslan Bukin 		/** Event: power state entry. */
138274fe6c29SRuslan Bukin 		struct {
138374fe6c29SRuslan Bukin 			/** The resolved thread C-state. */
138474fe6c29SRuslan Bukin 			uint8_t state;
138574fe6c29SRuslan Bukin 
138674fe6c29SRuslan Bukin 			/** The resolved thread sub C-state. */
138774fe6c29SRuslan Bukin 			uint8_t sub_state;
138874fe6c29SRuslan Bukin 
138974fe6c29SRuslan Bukin 			/** A flag indicating whether the C-state entry was
139074fe6c29SRuslan Bukin 			 * initiated by h/w.
139174fe6c29SRuslan Bukin 			 */
139274fe6c29SRuslan Bukin 			uint32_t hw:1;
139374fe6c29SRuslan Bukin 		} pwre;
139474fe6c29SRuslan Bukin 
139574fe6c29SRuslan Bukin 		/** Event: power state exit. */
139674fe6c29SRuslan Bukin 		struct {
139774fe6c29SRuslan Bukin 			/** The core C-state at the time of the wake. */
139874fe6c29SRuslan Bukin 			uint8_t last;
139974fe6c29SRuslan Bukin 
140074fe6c29SRuslan Bukin 			/** The deepest core C-state achieved during sleep. */
140174fe6c29SRuslan Bukin 			uint8_t deepest;
140274fe6c29SRuslan Bukin 
140374fe6c29SRuslan Bukin 			/** The wake reason:
140474fe6c29SRuslan Bukin 			 *
140574fe6c29SRuslan Bukin 			 * - due to external interrupt received.
140674fe6c29SRuslan Bukin 			 */
140774fe6c29SRuslan Bukin 			uint32_t interrupt:1;
140874fe6c29SRuslan Bukin 
140974fe6c29SRuslan Bukin 			/** - due to store to monitored address. */
141074fe6c29SRuslan Bukin 			uint32_t store:1;
141174fe6c29SRuslan Bukin 
141274fe6c29SRuslan Bukin 			/** - due to h/w autonomous condition such as HDC. */
141374fe6c29SRuslan Bukin 			uint32_t autonomous:1;
141474fe6c29SRuslan Bukin 		} pwrx;
141574fe6c29SRuslan Bukin 
141674fe6c29SRuslan Bukin 		/** Event: ptwrite. */
141774fe6c29SRuslan Bukin 		struct {
141874fe6c29SRuslan Bukin 			/** The address of the ptwrite instruction.
141974fe6c29SRuslan Bukin 			 *
142074fe6c29SRuslan Bukin 			 * This field is not valid, if \@ip_suppressed is set.
142174fe6c29SRuslan Bukin 			 *
142274fe6c29SRuslan Bukin 			 * In this case, the address is obvious from the
142374fe6c29SRuslan Bukin 			 * disassembly.
142474fe6c29SRuslan Bukin 			 */
142574fe6c29SRuslan Bukin 			uint64_t ip;
142674fe6c29SRuslan Bukin 
142774fe6c29SRuslan Bukin 			/** The size of the below \@payload in bytes. */
142874fe6c29SRuslan Bukin 			uint8_t size;
142974fe6c29SRuslan Bukin 
143074fe6c29SRuslan Bukin 			/** The ptwrite payload. */
143174fe6c29SRuslan Bukin 			uint64_t payload;
143274fe6c29SRuslan Bukin 		} ptwrite;
143374fe6c29SRuslan Bukin 
143474fe6c29SRuslan Bukin 		/** Event: tick. */
143574fe6c29SRuslan Bukin 		struct {
143674fe6c29SRuslan Bukin 			/** The instruction address near which the tick occured.
143774fe6c29SRuslan Bukin 			 *
143874fe6c29SRuslan Bukin 			 * A timestamp can sometimes be attributed directly to
143974fe6c29SRuslan Bukin 			 * an instruction (e.g. to an indirect branch that
144074fe6c29SRuslan Bukin 			 * receives CYC + TIP) and sometimes not (e.g. MTC).
144174fe6c29SRuslan Bukin 			 *
144274fe6c29SRuslan Bukin 			 * This field is not valid, if \@ip_suppressed is set.
144374fe6c29SRuslan Bukin 			 */
144474fe6c29SRuslan Bukin 			uint64_t ip;
144574fe6c29SRuslan Bukin 		} tick;
144674fe6c29SRuslan Bukin 
144774fe6c29SRuslan Bukin 		/** Event: cbr. */
144874fe6c29SRuslan Bukin 		struct {
144974fe6c29SRuslan Bukin 			/** The core:bus ratio. */
145074fe6c29SRuslan Bukin 			uint16_t ratio;
145174fe6c29SRuslan Bukin 		} cbr;
145274fe6c29SRuslan Bukin 
145374fe6c29SRuslan Bukin 		/** Event: mnt. */
145474fe6c29SRuslan Bukin 		struct {
145574fe6c29SRuslan Bukin 			/** The raw payload. */
145674fe6c29SRuslan Bukin 			uint64_t payload;
145774fe6c29SRuslan Bukin 		} mnt;
145874fe6c29SRuslan Bukin 	} variant;
145974fe6c29SRuslan Bukin };
146074fe6c29SRuslan Bukin 
146174fe6c29SRuslan Bukin 
146274fe6c29SRuslan Bukin /** Allocate an Intel PT query decoder.
146374fe6c29SRuslan Bukin  *
146474fe6c29SRuslan Bukin  * The decoder will work on the buffer defined in \@config, it shall contain
146574fe6c29SRuslan Bukin  * raw trace data and remain valid for the lifetime of the decoder.
146674fe6c29SRuslan Bukin  *
146774fe6c29SRuslan Bukin  * The decoder needs to be synchronized before it can be used.
146874fe6c29SRuslan Bukin  */
146974fe6c29SRuslan Bukin extern pt_export struct pt_query_decoder *
147074fe6c29SRuslan Bukin pt_qry_alloc_decoder(const struct pt_config *config);
147174fe6c29SRuslan Bukin 
147274fe6c29SRuslan Bukin /** Free an Intel PT query decoder.
147374fe6c29SRuslan Bukin  *
147474fe6c29SRuslan Bukin  * The \@decoder must not be used after a successful return.
147574fe6c29SRuslan Bukin  */
147674fe6c29SRuslan Bukin extern pt_export void pt_qry_free_decoder(struct pt_query_decoder *decoder);
147774fe6c29SRuslan Bukin 
147874fe6c29SRuslan Bukin /** Synchronize an Intel PT query decoder.
147974fe6c29SRuslan Bukin  *
148074fe6c29SRuslan Bukin  * Search for the next synchronization point in forward or backward direction.
148174fe6c29SRuslan Bukin  *
148274fe6c29SRuslan Bukin  * If \@decoder has not been synchronized, yet, the search is started at the
148374fe6c29SRuslan Bukin  * beginning of the trace buffer in case of forward synchronization and at the
148474fe6c29SRuslan Bukin  * end of the trace buffer in case of backward synchronization.
148574fe6c29SRuslan Bukin  *
148674fe6c29SRuslan Bukin  * If \@ip is not NULL, set it to last ip.
148774fe6c29SRuslan Bukin  *
148874fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
148974fe6c29SRuslan Bukin  * code otherwise.
149074fe6c29SRuslan Bukin  *
149174fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
149274fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
149374fe6c29SRuslan Bukin  * Returns -pte_eos if no further synchronization point is found.
149474fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
149574fe6c29SRuslan Bukin  */
149674fe6c29SRuslan Bukin extern pt_export int pt_qry_sync_forward(struct pt_query_decoder *decoder,
149774fe6c29SRuslan Bukin 					 uint64_t *ip);
149874fe6c29SRuslan Bukin extern pt_export int pt_qry_sync_backward(struct pt_query_decoder *decoder,
149974fe6c29SRuslan Bukin 					 uint64_t *ip);
150074fe6c29SRuslan Bukin 
150174fe6c29SRuslan Bukin /** Manually synchronize an Intel PT query decoder.
150274fe6c29SRuslan Bukin  *
150374fe6c29SRuslan Bukin  * Synchronize \@decoder on the syncpoint at \@offset.  There must be a PSB
150474fe6c29SRuslan Bukin  * packet at \@offset.
150574fe6c29SRuslan Bukin  *
150674fe6c29SRuslan Bukin  * If \@ip is not NULL, set it to last ip.
150774fe6c29SRuslan Bukin  *
150874fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
150974fe6c29SRuslan Bukin  * code otherwise.
151074fe6c29SRuslan Bukin  *
151174fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
151274fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
151374fe6c29SRuslan Bukin  * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
151474fe6c29SRuslan Bukin  * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
151574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
151674fe6c29SRuslan Bukin  * Returns -pte_nosync if there is no syncpoint at \@offset.
151774fe6c29SRuslan Bukin  */
151874fe6c29SRuslan Bukin extern pt_export int pt_qry_sync_set(struct pt_query_decoder *decoder,
151974fe6c29SRuslan Bukin 				     uint64_t *ip, uint64_t offset);
152074fe6c29SRuslan Bukin 
152174fe6c29SRuslan Bukin /** Get the current decoder position.
152274fe6c29SRuslan Bukin  *
152374fe6c29SRuslan Bukin  * Fills the current \@decoder position into \@offset.
152474fe6c29SRuslan Bukin  *
152574fe6c29SRuslan Bukin  * This is useful for reporting errors.
152674fe6c29SRuslan Bukin  *
152774fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
152874fe6c29SRuslan Bukin  *
152974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
153074fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
153174fe6c29SRuslan Bukin  */
153274fe6c29SRuslan Bukin extern pt_export int pt_qry_get_offset(const struct pt_query_decoder *decoder,
153374fe6c29SRuslan Bukin 				       uint64_t *offset);
153474fe6c29SRuslan Bukin 
153574fe6c29SRuslan Bukin /** Get the position of the last synchronization point.
153674fe6c29SRuslan Bukin  *
153774fe6c29SRuslan Bukin  * Fills the last synchronization position into \@offset.
153874fe6c29SRuslan Bukin  *
153974fe6c29SRuslan Bukin  * This is useful for splitting a trace stream for parallel decoding.
154074fe6c29SRuslan Bukin  *
154174fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
154274fe6c29SRuslan Bukin  *
154374fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
154474fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
154574fe6c29SRuslan Bukin  */
154674fe6c29SRuslan Bukin extern pt_export int
154774fe6c29SRuslan Bukin pt_qry_get_sync_offset(const struct pt_query_decoder *decoder,
154874fe6c29SRuslan Bukin 		       uint64_t *offset);
154974fe6c29SRuslan Bukin 
155074fe6c29SRuslan Bukin /* Return a pointer to \@decoder's configuration.
155174fe6c29SRuslan Bukin  *
155274fe6c29SRuslan Bukin  * Returns a non-null pointer on success, NULL if \@decoder is NULL.
155374fe6c29SRuslan Bukin  */
155474fe6c29SRuslan Bukin extern pt_export const struct pt_config *
155574fe6c29SRuslan Bukin pt_qry_get_config(const struct pt_query_decoder *decoder);
155674fe6c29SRuslan Bukin 
155774fe6c29SRuslan Bukin /** Query whether the next unconditional branch has been taken.
155874fe6c29SRuslan Bukin  *
155974fe6c29SRuslan Bukin  * On success, provides 1 (taken) or 0 (not taken) in \@taken for the next
156074fe6c29SRuslan Bukin  * conditional branch and updates \@decoder.
156174fe6c29SRuslan Bukin  *
156274fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
156374fe6c29SRuslan Bukin  * code otherwise.
156474fe6c29SRuslan Bukin  *
156574fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
156674fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
156774fe6c29SRuslan Bukin  * Returns -pte_bad_query if no conditional branch is found.
156874fe6c29SRuslan Bukin  * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
156974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@taken is NULL.
157074fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
157174fe6c29SRuslan Bukin  */
157274fe6c29SRuslan Bukin extern pt_export int pt_qry_cond_branch(struct pt_query_decoder *decoder,
157374fe6c29SRuslan Bukin 					int *taken);
157474fe6c29SRuslan Bukin 
157574fe6c29SRuslan Bukin /** Get the next indirect branch destination.
157674fe6c29SRuslan Bukin  *
157774fe6c29SRuslan Bukin  * On success, provides the linear destination address of the next indirect
157874fe6c29SRuslan Bukin  * branch in \@ip and updates \@decoder.
157974fe6c29SRuslan Bukin  *
158074fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
158174fe6c29SRuslan Bukin  * code otherwise.
158274fe6c29SRuslan Bukin  *
158374fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
158474fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
158574fe6c29SRuslan Bukin  * Returns -pte_bad_query if no indirect branch is found.
158674fe6c29SRuslan Bukin  * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
158774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@ip is NULL.
158874fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
158974fe6c29SRuslan Bukin  */
159074fe6c29SRuslan Bukin extern pt_export int pt_qry_indirect_branch(struct pt_query_decoder *decoder,
159174fe6c29SRuslan Bukin 					    uint64_t *ip);
159274fe6c29SRuslan Bukin 
159374fe6c29SRuslan Bukin /** Query the next pending event.
159474fe6c29SRuslan Bukin  *
159574fe6c29SRuslan Bukin  * On success, provides the next event \@event and updates \@decoder.
159674fe6c29SRuslan Bukin  *
159774fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_event).
159874fe6c29SRuslan Bukin  *
159974fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
160074fe6c29SRuslan Bukin  * code otherwise.
160174fe6c29SRuslan Bukin  *
160274fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
160374fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
160474fe6c29SRuslan Bukin  * Returns -pte_bad_query if no event is found.
160574fe6c29SRuslan Bukin  * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
160674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@event is NULL.
160774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@size is too small.
160874fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
160974fe6c29SRuslan Bukin  */
161074fe6c29SRuslan Bukin extern pt_export int pt_qry_event(struct pt_query_decoder *decoder,
161174fe6c29SRuslan Bukin 				  struct pt_event *event, size_t size);
161274fe6c29SRuslan Bukin 
161374fe6c29SRuslan Bukin /** Query the current time.
161474fe6c29SRuslan Bukin  *
161574fe6c29SRuslan Bukin  * On success, provides the time at the last query in \@time.
161674fe6c29SRuslan Bukin  *
161774fe6c29SRuslan Bukin  * The time is similar to what a rdtsc instruction would return.  Depending
161874fe6c29SRuslan Bukin  * on the configuration, the time may not be fully accurate.  If TSC is not
161974fe6c29SRuslan Bukin  * enabled, the time is relative to the last synchronization and can't be used
162074fe6c29SRuslan Bukin  * to correlate with other TSC-based time sources.  In this case, -pte_no_time
162174fe6c29SRuslan Bukin  * is returned and the relative time is provided in \@time.
162274fe6c29SRuslan Bukin  *
162374fe6c29SRuslan Bukin  * Some timing-related packets may need to be dropped (mostly due to missing
162474fe6c29SRuslan Bukin  * calibration or incomplete configuration).  To get an idea about the quality
162574fe6c29SRuslan Bukin  * of the estimated time, we record the number of dropped MTC and CYC packets.
162674fe6c29SRuslan Bukin  *
162774fe6c29SRuslan Bukin  * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
162874fe6c29SRuslan Bukin  * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
162974fe6c29SRuslan Bukin  *
163074fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
163174fe6c29SRuslan Bukin  *
163274fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@time is NULL.
163374fe6c29SRuslan Bukin  * Returns -pte_no_time if there has not been a TSC packet.
163474fe6c29SRuslan Bukin  */
163574fe6c29SRuslan Bukin extern pt_export int pt_qry_time(struct pt_query_decoder *decoder,
163674fe6c29SRuslan Bukin 				 uint64_t *time, uint32_t *lost_mtc,
163774fe6c29SRuslan Bukin 				 uint32_t *lost_cyc);
163874fe6c29SRuslan Bukin 
163974fe6c29SRuslan Bukin /** Return the current core bus ratio.
164074fe6c29SRuslan Bukin  *
164174fe6c29SRuslan Bukin  * On success, provides the current core:bus ratio in \@cbr.  The ratio is
164274fe6c29SRuslan Bukin  * defined as core cycles per bus clock cycle.
164374fe6c29SRuslan Bukin  *
164474fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
164574fe6c29SRuslan Bukin  *
164674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@cbr is NULL.
164774fe6c29SRuslan Bukin  * Returns -pte_no_cbr if there has not been a CBR packet.
164874fe6c29SRuslan Bukin  */
164974fe6c29SRuslan Bukin extern pt_export int pt_qry_core_bus_ratio(struct pt_query_decoder *decoder,
165074fe6c29SRuslan Bukin 					   uint32_t *cbr);
165174fe6c29SRuslan Bukin 
165274fe6c29SRuslan Bukin 
165374fe6c29SRuslan Bukin 
165474fe6c29SRuslan Bukin /* Traced image. */
165574fe6c29SRuslan Bukin 
165674fe6c29SRuslan Bukin 
165774fe6c29SRuslan Bukin 
165874fe6c29SRuslan Bukin /** An Intel PT address space identifier.
165974fe6c29SRuslan Bukin  *
166074fe6c29SRuslan Bukin  * This identifies a particular address space when adding file sections or
166174fe6c29SRuslan Bukin  * when reading memory.
166274fe6c29SRuslan Bukin  */
166374fe6c29SRuslan Bukin struct pt_asid {
166474fe6c29SRuslan Bukin 	/** The size of this object - set to sizeof(struct pt_asid). */
166574fe6c29SRuslan Bukin 	size_t size;
166674fe6c29SRuslan Bukin 
166774fe6c29SRuslan Bukin 	/** The CR3 value. */
166874fe6c29SRuslan Bukin 	uint64_t cr3;
166974fe6c29SRuslan Bukin 
167074fe6c29SRuslan Bukin 	/** The VMCS Base address. */
167174fe6c29SRuslan Bukin 	uint64_t vmcs;
167274fe6c29SRuslan Bukin };
167374fe6c29SRuslan Bukin 
167474fe6c29SRuslan Bukin /** An unknown CR3 value to be used for pt_asid objects. */
167574fe6c29SRuslan Bukin static const uint64_t pt_asid_no_cr3 = 0xffffffffffffffffull;
167674fe6c29SRuslan Bukin 
167774fe6c29SRuslan Bukin /** An unknown VMCS Base value to be used for pt_asid objects. */
167874fe6c29SRuslan Bukin static const uint64_t pt_asid_no_vmcs = 0xffffffffffffffffull;
167974fe6c29SRuslan Bukin 
168074fe6c29SRuslan Bukin /** Initialize an address space identifier. */
pt_asid_init(struct pt_asid * asid)168174fe6c29SRuslan Bukin static inline void pt_asid_init(struct pt_asid *asid)
168274fe6c29SRuslan Bukin {
168374fe6c29SRuslan Bukin 	asid->size = sizeof(*asid);
168474fe6c29SRuslan Bukin 	asid->cr3 = pt_asid_no_cr3;
168574fe6c29SRuslan Bukin 	asid->vmcs = pt_asid_no_vmcs;
168674fe6c29SRuslan Bukin }
168774fe6c29SRuslan Bukin 
168874fe6c29SRuslan Bukin 
168974fe6c29SRuslan Bukin /** A cache of traced image sections. */
169074fe6c29SRuslan Bukin struct pt_image_section_cache;
169174fe6c29SRuslan Bukin 
169274fe6c29SRuslan Bukin /** Allocate a traced memory image section cache.
169374fe6c29SRuslan Bukin  *
169474fe6c29SRuslan Bukin  * An optional \@name may be given to the cache.  The name string is copied.
169574fe6c29SRuslan Bukin  *
169674fe6c29SRuslan Bukin  * Returns a new traced memory image section cache on success, NULL otherwise.
169774fe6c29SRuslan Bukin  */
169874fe6c29SRuslan Bukin extern pt_export struct pt_image_section_cache *
169974fe6c29SRuslan Bukin pt_iscache_alloc(const char *name);
170074fe6c29SRuslan Bukin 
170174fe6c29SRuslan Bukin /** Free a traced memory image section cache.
170274fe6c29SRuslan Bukin  *
170374fe6c29SRuslan Bukin  * The \@iscache must have been allocated with pt_iscache_alloc().
170474fe6c29SRuslan Bukin  * The \@iscache must not be used after a successful return.
170574fe6c29SRuslan Bukin  */
170674fe6c29SRuslan Bukin extern pt_export void pt_iscache_free(struct pt_image_section_cache *iscache);
170774fe6c29SRuslan Bukin 
170874fe6c29SRuslan Bukin /** Set the image section cache limit.
170974fe6c29SRuslan Bukin  *
171074fe6c29SRuslan Bukin  * Set the limit for a section cache in bytes.  A non-zero limit will keep the
171174fe6c29SRuslan Bukin  * least recently used sections mapped until the limit is reached.  A limit of
171274fe6c29SRuslan Bukin  * zero disables caching.
171374fe6c29SRuslan Bukin  *
171474fe6c29SRuslan Bukin  * Returns zero on success, a negative pt_error_code otherwise.
171574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@iscache is NULL.
171674fe6c29SRuslan Bukin  */
171774fe6c29SRuslan Bukin extern pt_export int
171874fe6c29SRuslan Bukin pt_iscache_set_limit(struct pt_image_section_cache *iscache, uint64_t limit);
171974fe6c29SRuslan Bukin 
172074fe6c29SRuslan Bukin /** Get the image section cache name.
172174fe6c29SRuslan Bukin  *
172274fe6c29SRuslan Bukin  * Returns a pointer to \@iscache's name or NULL if there is no name.
172374fe6c29SRuslan Bukin  */
172474fe6c29SRuslan Bukin extern pt_export const char *
172574fe6c29SRuslan Bukin pt_iscache_name(const struct pt_image_section_cache *iscache);
172674fe6c29SRuslan Bukin 
172774fe6c29SRuslan Bukin /** Add a new file section to the traced memory image section cache.
172874fe6c29SRuslan Bukin  *
172974fe6c29SRuslan Bukin  * Adds a new section consisting of \@size bytes starting at \@offset in
173074fe6c29SRuslan Bukin  * \@filename loaded at the virtual address \@vaddr if \@iscache does not
173174fe6c29SRuslan Bukin  * already contain such a section.
173274fe6c29SRuslan Bukin  *
173374fe6c29SRuslan Bukin  * Returns an image section identifier (isid) uniquely identifying that section
173474fe6c29SRuslan Bukin  * in \@iscache.
173574fe6c29SRuslan Bukin  *
173674fe6c29SRuslan Bukin  * The section is silently truncated to match the size of \@filename.
173774fe6c29SRuslan Bukin  *
173874fe6c29SRuslan Bukin  * Returns a positive isid on success, a negative error code otherwise.
173974fe6c29SRuslan Bukin  *
174074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@iscache or \@filename is NULL.
174174fe6c29SRuslan Bukin  * Returns -pte_invalid if \@offset is too big.
174274fe6c29SRuslan Bukin  */
174374fe6c29SRuslan Bukin extern pt_export int pt_iscache_add_file(struct pt_image_section_cache *iscache,
174474fe6c29SRuslan Bukin 					 const char *filename, uint64_t offset,
174574fe6c29SRuslan Bukin 					 uint64_t size, uint64_t vaddr);
174674fe6c29SRuslan Bukin 
174774fe6c29SRuslan Bukin /** Read memory from a cached file section
174874fe6c29SRuslan Bukin  *
174974fe6c29SRuslan Bukin  * Reads \@size bytes of memory starting at virtual address \@vaddr in the
175074fe6c29SRuslan Bukin  * section identified by \@isid in \@iscache into \@buffer.
175174fe6c29SRuslan Bukin  *
175274fe6c29SRuslan Bukin  * The caller is responsible for allocating a \@buffer of at least \@size bytes.
175374fe6c29SRuslan Bukin  *
175474fe6c29SRuslan Bukin  * The read request may be truncated if it crosses section boundaries or if
175574fe6c29SRuslan Bukin  * \@size is getting too big.  We support reading at least 4Kbyte in one chunk
175674fe6c29SRuslan Bukin  * unless the read would cross a section boundary.
175774fe6c29SRuslan Bukin  *
175874fe6c29SRuslan Bukin  * Returns the number of bytes read on success, a negative error code otherwise.
175974fe6c29SRuslan Bukin  *
176074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@iscache or \@buffer is NULL.
176174fe6c29SRuslan Bukin  * Returns -pte_invalid if \@size is zero.
176274fe6c29SRuslan Bukin  * Returns -pte_nomap if \@vaddr is not contained in section \@isid.
176374fe6c29SRuslan Bukin  * Returns -pte_bad_image if \@iscache does not contain \@isid.
176474fe6c29SRuslan Bukin  */
176574fe6c29SRuslan Bukin extern pt_export int pt_iscache_read(struct pt_image_section_cache *iscache,
176674fe6c29SRuslan Bukin 				     uint8_t *buffer, uint64_t size, int isid,
176774fe6c29SRuslan Bukin 				     uint64_t vaddr);
176874fe6c29SRuslan Bukin 
176974fe6c29SRuslan Bukin /** The traced memory image. */
177074fe6c29SRuslan Bukin struct pt_image;
177174fe6c29SRuslan Bukin 
177274fe6c29SRuslan Bukin 
177374fe6c29SRuslan Bukin /** Allocate a traced memory image.
177474fe6c29SRuslan Bukin  *
177574fe6c29SRuslan Bukin  * An optional \@name may be given to the image.  The name string is copied.
177674fe6c29SRuslan Bukin  *
177774fe6c29SRuslan Bukin  * Returns a new traced memory image on success, NULL otherwise.
177874fe6c29SRuslan Bukin  */
177974fe6c29SRuslan Bukin extern pt_export struct pt_image *pt_image_alloc(const char *name);
178074fe6c29SRuslan Bukin 
178174fe6c29SRuslan Bukin /** Free a traced memory image.
178274fe6c29SRuslan Bukin  *
178374fe6c29SRuslan Bukin  * The \@image must have been allocated with pt_image_alloc().
178474fe6c29SRuslan Bukin  * The \@image must not be used after a successful return.
178574fe6c29SRuslan Bukin  */
178674fe6c29SRuslan Bukin extern pt_export void pt_image_free(struct pt_image *image);
178774fe6c29SRuslan Bukin 
178874fe6c29SRuslan Bukin /** Get the image name.
178974fe6c29SRuslan Bukin  *
179074fe6c29SRuslan Bukin  * Returns a pointer to \@image's name or NULL if there is no name.
179174fe6c29SRuslan Bukin  */
179274fe6c29SRuslan Bukin extern pt_export const char *pt_image_name(const struct pt_image *image);
179374fe6c29SRuslan Bukin 
179474fe6c29SRuslan Bukin /** Add a new file section to the traced memory image.
179574fe6c29SRuslan Bukin  *
179674fe6c29SRuslan Bukin  * Adds \@size bytes starting at \@offset in \@filename. The section is
179774fe6c29SRuslan Bukin  * loaded at the virtual address \@vaddr in the address space \@asid.
179874fe6c29SRuslan Bukin  *
179974fe6c29SRuslan Bukin  * The \@asid may be NULL or (partially) invalid.  In that case only the valid
180074fe6c29SRuslan Bukin  * fields are considered when comparing with other address-spaces.  Use this
180174fe6c29SRuslan Bukin  * when tracing a single process or when adding sections to all processes.
180274fe6c29SRuslan Bukin  *
180374fe6c29SRuslan Bukin  * The section is silently truncated to match the size of \@filename.
180474fe6c29SRuslan Bukin  *
180574fe6c29SRuslan Bukin  * Existing sections that would overlap with the new section will be shrunk
180674fe6c29SRuslan Bukin  * or split.
180774fe6c29SRuslan Bukin  *
180874fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
180974fe6c29SRuslan Bukin  *
181074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image or \@filename is NULL.
181174fe6c29SRuslan Bukin  * Returns -pte_invalid if \@offset is too big.
181274fe6c29SRuslan Bukin  */
181374fe6c29SRuslan Bukin extern pt_export int pt_image_add_file(struct pt_image *image,
181474fe6c29SRuslan Bukin 				       const char *filename, uint64_t offset,
181574fe6c29SRuslan Bukin 				       uint64_t size,
181674fe6c29SRuslan Bukin 				       const struct pt_asid *asid,
181774fe6c29SRuslan Bukin 				       uint64_t vaddr);
181874fe6c29SRuslan Bukin 
181974fe6c29SRuslan Bukin /** Add a section from an image section cache.
182074fe6c29SRuslan Bukin  *
182174fe6c29SRuslan Bukin  * Add the section from \@iscache identified by \@isid in address space \@asid.
182274fe6c29SRuslan Bukin  *
182374fe6c29SRuslan Bukin  * Existing sections that would overlap with the new section will be shrunk
182474fe6c29SRuslan Bukin  * or split.
182574fe6c29SRuslan Bukin  *
182674fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
182774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image or \@iscache is NULL.
182874fe6c29SRuslan Bukin  * Returns -pte_bad_image if \@iscache does not contain \@isid.
182974fe6c29SRuslan Bukin  */
183074fe6c29SRuslan Bukin extern pt_export int pt_image_add_cached(struct pt_image *image,
183174fe6c29SRuslan Bukin 					 struct pt_image_section_cache *iscache,
183274fe6c29SRuslan Bukin 					 int isid, const struct pt_asid *asid);
183374fe6c29SRuslan Bukin 
183474fe6c29SRuslan Bukin /** Copy an image.
183574fe6c29SRuslan Bukin  *
183674fe6c29SRuslan Bukin  * Adds all sections from \@src to \@image.  Sections that could not be added
183774fe6c29SRuslan Bukin  * will be ignored.
183874fe6c29SRuslan Bukin  *
183974fe6c29SRuslan Bukin  * Returns the number of ignored sections on success, a negative error code
184074fe6c29SRuslan Bukin  * otherwise.
184174fe6c29SRuslan Bukin  *
184274fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image or \@src is NULL.
184374fe6c29SRuslan Bukin  */
184474fe6c29SRuslan Bukin extern pt_export int pt_image_copy(struct pt_image *image,
184574fe6c29SRuslan Bukin 				   const struct pt_image *src);
184674fe6c29SRuslan Bukin 
184774fe6c29SRuslan Bukin /** Remove all sections loaded from a file.
184874fe6c29SRuslan Bukin  *
184974fe6c29SRuslan Bukin  * Removes all sections loaded from \@filename from the address space \@asid.
185074fe6c29SRuslan Bukin  * Specify the same \@asid that was used for adding sections from \@filename.
185174fe6c29SRuslan Bukin  *
185274fe6c29SRuslan Bukin  * Returns the number of removed sections on success, a negative error code
185374fe6c29SRuslan Bukin  * otherwise.
185474fe6c29SRuslan Bukin  *
185574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image or \@filename is NULL.
185674fe6c29SRuslan Bukin  */
185774fe6c29SRuslan Bukin extern pt_export int pt_image_remove_by_filename(struct pt_image *image,
185874fe6c29SRuslan Bukin 						 const char *filename,
185974fe6c29SRuslan Bukin 						 const struct pt_asid *asid);
186074fe6c29SRuslan Bukin 
186174fe6c29SRuslan Bukin /** Remove all sections loaded into an address space.
186274fe6c29SRuslan Bukin  *
186374fe6c29SRuslan Bukin  * Removes all sections loaded into \@asid.  Specify the same \@asid that was
186474fe6c29SRuslan Bukin  * used for adding sections.
186574fe6c29SRuslan Bukin  *
186674fe6c29SRuslan Bukin  * Returns the number of removed sections on success, a negative error code
186774fe6c29SRuslan Bukin  * otherwise.
186874fe6c29SRuslan Bukin  *
186974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image is NULL.
187074fe6c29SRuslan Bukin  */
187174fe6c29SRuslan Bukin extern pt_export int pt_image_remove_by_asid(struct pt_image *image,
187274fe6c29SRuslan Bukin 					     const struct pt_asid *asid);
187374fe6c29SRuslan Bukin 
187474fe6c29SRuslan Bukin /** A read memory callback function.
187574fe6c29SRuslan Bukin  *
187674fe6c29SRuslan Bukin  * It shall read \@size bytes of memory from address space \@asid starting
187774fe6c29SRuslan Bukin  * at \@ip into \@buffer.
187874fe6c29SRuslan Bukin  *
187974fe6c29SRuslan Bukin  * It shall return the number of bytes read on success.
188074fe6c29SRuslan Bukin  * It shall return a negative pt_error_code otherwise.
188174fe6c29SRuslan Bukin  */
188274fe6c29SRuslan Bukin typedef int (read_memory_callback_t)(uint8_t *buffer, size_t size,
188374fe6c29SRuslan Bukin 				     const struct pt_asid *asid,
188474fe6c29SRuslan Bukin 				     uint64_t ip, void *context);
188574fe6c29SRuslan Bukin 
188674fe6c29SRuslan Bukin /** Set the memory callback for the traced memory image.
188774fe6c29SRuslan Bukin  *
188874fe6c29SRuslan Bukin  * Sets \@callback for reading memory.  The callback is used for addresses
188974fe6c29SRuslan Bukin  * that are not found in file sections.  The \@context argument is passed
189074fe6c29SRuslan Bukin  * to \@callback on each use.
189174fe6c29SRuslan Bukin  *
189274fe6c29SRuslan Bukin  * There can only be one callback at any time.  A subsequent call will replace
189374fe6c29SRuslan Bukin  * the previous callback.  If \@callback is NULL, the callback is removed.
189474fe6c29SRuslan Bukin  *
189574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@image is NULL.
189674fe6c29SRuslan Bukin  */
189774fe6c29SRuslan Bukin extern pt_export int pt_image_set_callback(struct pt_image *image,
189874fe6c29SRuslan Bukin 					   read_memory_callback_t *callback,
189974fe6c29SRuslan Bukin 					   void *context);
190074fe6c29SRuslan Bukin 
190174fe6c29SRuslan Bukin 
190274fe6c29SRuslan Bukin 
190374fe6c29SRuslan Bukin /* Instruction flow decoder. */
190474fe6c29SRuslan Bukin 
190574fe6c29SRuslan Bukin 
190674fe6c29SRuslan Bukin 
190774fe6c29SRuslan Bukin /** The instruction class.
190874fe6c29SRuslan Bukin  *
190974fe6c29SRuslan Bukin  * We provide only a very coarse classification suitable for reconstructing
191074fe6c29SRuslan Bukin  * the execution flow.
191174fe6c29SRuslan Bukin  */
191274fe6c29SRuslan Bukin enum pt_insn_class {
191374fe6c29SRuslan Bukin 	/* The instruction could not be classified. */
191474fe6c29SRuslan Bukin 	ptic_error,
191574fe6c29SRuslan Bukin 
191674fe6c29SRuslan Bukin 	/* The instruction is something not listed below. */
191774fe6c29SRuslan Bukin 	ptic_other,
191874fe6c29SRuslan Bukin 
191974fe6c29SRuslan Bukin 	/* The instruction is a near (function) call. */
192074fe6c29SRuslan Bukin 	ptic_call,
192174fe6c29SRuslan Bukin 
192274fe6c29SRuslan Bukin 	/* The instruction is a near (function) return. */
192374fe6c29SRuslan Bukin 	ptic_return,
192474fe6c29SRuslan Bukin 
192574fe6c29SRuslan Bukin 	/* The instruction is a near unconditional jump. */
192674fe6c29SRuslan Bukin 	ptic_jump,
192774fe6c29SRuslan Bukin 
192874fe6c29SRuslan Bukin 	/* The instruction is a near conditional jump. */
192974fe6c29SRuslan Bukin 	ptic_cond_jump,
193074fe6c29SRuslan Bukin 
193174fe6c29SRuslan Bukin 	/* The instruction is a call-like far transfer.
193274fe6c29SRuslan Bukin 	 * E.g. SYSCALL, SYSENTER, or FAR CALL.
193374fe6c29SRuslan Bukin 	 */
193474fe6c29SRuslan Bukin 	ptic_far_call,
193574fe6c29SRuslan Bukin 
193674fe6c29SRuslan Bukin 	/* The instruction is a return-like far transfer.
193774fe6c29SRuslan Bukin 	 * E.g. SYSRET, SYSEXIT, IRET, or FAR RET.
193874fe6c29SRuslan Bukin 	 */
193974fe6c29SRuslan Bukin 	ptic_far_return,
194074fe6c29SRuslan Bukin 
194174fe6c29SRuslan Bukin 	/* The instruction is a jump-like far transfer.
194274fe6c29SRuslan Bukin 	 * E.g. FAR JMP.
194374fe6c29SRuslan Bukin 	 */
194474fe6c29SRuslan Bukin 	ptic_far_jump,
194574fe6c29SRuslan Bukin 
194674fe6c29SRuslan Bukin 	/* The instruction is a PTWRITE. */
194774fe6c29SRuslan Bukin 	ptic_ptwrite
194874fe6c29SRuslan Bukin };
194974fe6c29SRuslan Bukin 
195074fe6c29SRuslan Bukin /** The maximal size of an instruction. */
195174fe6c29SRuslan Bukin enum {
195274fe6c29SRuslan Bukin 	pt_max_insn_size	= 15
195374fe6c29SRuslan Bukin };
195474fe6c29SRuslan Bukin 
195574fe6c29SRuslan Bukin /** A single traced instruction. */
195674fe6c29SRuslan Bukin struct pt_insn {
195774fe6c29SRuslan Bukin 	/** The virtual address in its process. */
195874fe6c29SRuslan Bukin 	uint64_t ip;
195974fe6c29SRuslan Bukin 
196074fe6c29SRuslan Bukin 	/** The image section identifier for the section containing this
196174fe6c29SRuslan Bukin 	 * instruction.
196274fe6c29SRuslan Bukin 	 *
196374fe6c29SRuslan Bukin 	 * A value of zero means that the section did not have an identifier.
196474fe6c29SRuslan Bukin 	 * The section was not added via an image section cache or the memory
196574fe6c29SRuslan Bukin 	 * was read via the read memory callback.
196674fe6c29SRuslan Bukin 	 */
196774fe6c29SRuslan Bukin 	int isid;
196874fe6c29SRuslan Bukin 
196974fe6c29SRuslan Bukin 	/** The execution mode. */
197074fe6c29SRuslan Bukin 	enum pt_exec_mode mode;
197174fe6c29SRuslan Bukin 
197274fe6c29SRuslan Bukin 	/** A coarse classification. */
197374fe6c29SRuslan Bukin 	enum pt_insn_class iclass;
197474fe6c29SRuslan Bukin 
197574fe6c29SRuslan Bukin 	/** The raw bytes. */
197674fe6c29SRuslan Bukin 	uint8_t raw[pt_max_insn_size];
197774fe6c29SRuslan Bukin 
197874fe6c29SRuslan Bukin 	/** The size in bytes. */
197974fe6c29SRuslan Bukin 	uint8_t size;
198074fe6c29SRuslan Bukin 
198174fe6c29SRuslan Bukin 	/** A collection of flags giving additional information:
198274fe6c29SRuslan Bukin 	 *
198374fe6c29SRuslan Bukin 	 * - the instruction was executed speculatively.
198474fe6c29SRuslan Bukin 	 */
198574fe6c29SRuslan Bukin 	uint32_t speculative:1;
198674fe6c29SRuslan Bukin 
198774fe6c29SRuslan Bukin 	/** - this instruction is truncated in its image section.
198874fe6c29SRuslan Bukin 	 *
198974fe6c29SRuslan Bukin 	 *    It starts in the image section identified by \@isid and continues
199074fe6c29SRuslan Bukin 	 *    in one or more other sections.
199174fe6c29SRuslan Bukin 	 */
199274fe6c29SRuslan Bukin 	uint32_t truncated:1;
199374fe6c29SRuslan Bukin };
199474fe6c29SRuslan Bukin 
199574fe6c29SRuslan Bukin 
199674fe6c29SRuslan Bukin /** Allocate an Intel PT instruction flow decoder.
199774fe6c29SRuslan Bukin  *
199874fe6c29SRuslan Bukin  * The decoder will work on the buffer defined in \@config, it shall contain
199974fe6c29SRuslan Bukin  * raw trace data and remain valid for the lifetime of the decoder.
200074fe6c29SRuslan Bukin  *
200174fe6c29SRuslan Bukin  * The decoder needs to be synchronized before it can be used.
200274fe6c29SRuslan Bukin  */
200374fe6c29SRuslan Bukin extern pt_export struct pt_insn_decoder *
200474fe6c29SRuslan Bukin pt_insn_alloc_decoder(const struct pt_config *config);
200574fe6c29SRuslan Bukin 
200674fe6c29SRuslan Bukin /** Free an Intel PT instruction flow decoder.
200774fe6c29SRuslan Bukin  *
200874fe6c29SRuslan Bukin  * This will destroy the decoder's default image.
200974fe6c29SRuslan Bukin  *
201074fe6c29SRuslan Bukin  * The \@decoder must not be used after a successful return.
201174fe6c29SRuslan Bukin  */
201274fe6c29SRuslan Bukin extern pt_export void pt_insn_free_decoder(struct pt_insn_decoder *decoder);
201374fe6c29SRuslan Bukin 
201474fe6c29SRuslan Bukin /** Synchronize an Intel PT instruction flow decoder.
201574fe6c29SRuslan Bukin  *
201674fe6c29SRuslan Bukin  * Search for the next synchronization point in forward or backward direction.
201774fe6c29SRuslan Bukin  *
201874fe6c29SRuslan Bukin  * If \@decoder has not been synchronized, yet, the search is started at the
201974fe6c29SRuslan Bukin  * beginning of the trace buffer in case of forward synchronization and at the
202074fe6c29SRuslan Bukin  * end of the trace buffer in case of backward synchronization.
202174fe6c29SRuslan Bukin  *
202274fe6c29SRuslan Bukin  * Returns zero or a positive value on success, a negative error code otherwise.
202374fe6c29SRuslan Bukin  *
202474fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
202574fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
202674fe6c29SRuslan Bukin  * Returns -pte_eos if no further synchronization point is found.
202774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
202874fe6c29SRuslan Bukin  */
202974fe6c29SRuslan Bukin extern pt_export int pt_insn_sync_forward(struct pt_insn_decoder *decoder);
203074fe6c29SRuslan Bukin extern pt_export int pt_insn_sync_backward(struct pt_insn_decoder *decoder);
203174fe6c29SRuslan Bukin 
203274fe6c29SRuslan Bukin /** Manually synchronize an Intel PT instruction flow decoder.
203374fe6c29SRuslan Bukin  *
203474fe6c29SRuslan Bukin  * Synchronize \@decoder on the syncpoint at \@offset.  There must be a PSB
203574fe6c29SRuslan Bukin  * packet at \@offset.
203674fe6c29SRuslan Bukin  *
203774fe6c29SRuslan Bukin  * Returns zero or a positive value on success, a negative error code otherwise.
203874fe6c29SRuslan Bukin  *
203974fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
204074fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
204174fe6c29SRuslan Bukin  * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
204274fe6c29SRuslan Bukin  * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
204374fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
204474fe6c29SRuslan Bukin  * Returns -pte_nosync if there is no syncpoint at \@offset.
204574fe6c29SRuslan Bukin  */
204674fe6c29SRuslan Bukin extern pt_export int pt_insn_sync_set(struct pt_insn_decoder *decoder,
204774fe6c29SRuslan Bukin 				      uint64_t offset);
204874fe6c29SRuslan Bukin 
204974fe6c29SRuslan Bukin /** Get the current decoder position.
205074fe6c29SRuslan Bukin  *
205174fe6c29SRuslan Bukin  * Fills the current \@decoder position into \@offset.
205274fe6c29SRuslan Bukin  *
205374fe6c29SRuslan Bukin  * This is useful for reporting errors.
205474fe6c29SRuslan Bukin  *
205574fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
205674fe6c29SRuslan Bukin  *
205774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
205874fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
205974fe6c29SRuslan Bukin  */
206074fe6c29SRuslan Bukin extern pt_export int pt_insn_get_offset(const struct pt_insn_decoder *decoder,
206174fe6c29SRuslan Bukin 					uint64_t *offset);
206274fe6c29SRuslan Bukin 
206374fe6c29SRuslan Bukin /** Get the position of the last synchronization point.
206474fe6c29SRuslan Bukin  *
206574fe6c29SRuslan Bukin  * Fills the last synchronization position into \@offset.
206674fe6c29SRuslan Bukin  *
206774fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
206874fe6c29SRuslan Bukin  *
206974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
207074fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
207174fe6c29SRuslan Bukin  */
207274fe6c29SRuslan Bukin extern pt_export int
207374fe6c29SRuslan Bukin pt_insn_get_sync_offset(const struct pt_insn_decoder *decoder,
207474fe6c29SRuslan Bukin 			uint64_t *offset);
207574fe6c29SRuslan Bukin 
207674fe6c29SRuslan Bukin /** Get the traced image.
207774fe6c29SRuslan Bukin  *
207874fe6c29SRuslan Bukin  * The returned image may be modified as long as no decoder that uses this
207974fe6c29SRuslan Bukin  * image is running.
208074fe6c29SRuslan Bukin  *
208174fe6c29SRuslan Bukin  * Returns a pointer to the traced image the decoder uses for reading memory.
208274fe6c29SRuslan Bukin  * Returns NULL if \@decoder is NULL.
208374fe6c29SRuslan Bukin  */
208474fe6c29SRuslan Bukin extern pt_export struct pt_image *
208574fe6c29SRuslan Bukin pt_insn_get_image(struct pt_insn_decoder *decoder);
208674fe6c29SRuslan Bukin 
208774fe6c29SRuslan Bukin /** Set the traced image.
208874fe6c29SRuslan Bukin  *
208974fe6c29SRuslan Bukin  * Sets the image that \@decoder uses for reading memory to \@image.  If \@image
209074fe6c29SRuslan Bukin  * is NULL, sets the image to \@decoder's default image.
209174fe6c29SRuslan Bukin  *
209274fe6c29SRuslan Bukin  * Only one image can be active at any time.
209374fe6c29SRuslan Bukin  *
209474fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
209574fe6c29SRuslan Bukin  * Return -pte_invalid if \@decoder is NULL.
209674fe6c29SRuslan Bukin  */
209774fe6c29SRuslan Bukin extern pt_export int pt_insn_set_image(struct pt_insn_decoder *decoder,
209874fe6c29SRuslan Bukin 				       struct pt_image *image);
209974fe6c29SRuslan Bukin 
210074fe6c29SRuslan Bukin /* Return a pointer to \@decoder's configuration.
210174fe6c29SRuslan Bukin  *
210274fe6c29SRuslan Bukin  * Returns a non-null pointer on success, NULL if \@decoder is NULL.
210374fe6c29SRuslan Bukin  */
210474fe6c29SRuslan Bukin extern pt_export const struct pt_config *
210574fe6c29SRuslan Bukin pt_insn_get_config(const struct pt_insn_decoder *decoder);
210674fe6c29SRuslan Bukin 
210774fe6c29SRuslan Bukin /** Return the current time.
210874fe6c29SRuslan Bukin  *
210974fe6c29SRuslan Bukin  * On success, provides the time at the last preceding timing packet in \@time.
211074fe6c29SRuslan Bukin  *
211174fe6c29SRuslan Bukin  * The time is similar to what a rdtsc instruction would return.  Depending
211274fe6c29SRuslan Bukin  * on the configuration, the time may not be fully accurate.  If TSC is not
211374fe6c29SRuslan Bukin  * enabled, the time is relative to the last synchronization and can't be used
211474fe6c29SRuslan Bukin  * to correlate with other TSC-based time sources.  In this case, -pte_no_time
211574fe6c29SRuslan Bukin  * is returned and the relative time is provided in \@time.
211674fe6c29SRuslan Bukin  *
211774fe6c29SRuslan Bukin  * Some timing-related packets may need to be dropped (mostly due to missing
211874fe6c29SRuslan Bukin  * calibration or incomplete configuration).  To get an idea about the quality
211974fe6c29SRuslan Bukin  * of the estimated time, we record the number of dropped MTC and CYC packets.
212074fe6c29SRuslan Bukin  *
212174fe6c29SRuslan Bukin  * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
212274fe6c29SRuslan Bukin  * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
212374fe6c29SRuslan Bukin  *
212474fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
212574fe6c29SRuslan Bukin  *
212674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@time is NULL.
212774fe6c29SRuslan Bukin  * Returns -pte_no_time if there has not been a TSC packet.
212874fe6c29SRuslan Bukin  */
212974fe6c29SRuslan Bukin extern pt_export int pt_insn_time(struct pt_insn_decoder *decoder,
213074fe6c29SRuslan Bukin 				  uint64_t *time, uint32_t *lost_mtc,
213174fe6c29SRuslan Bukin 				  uint32_t *lost_cyc);
213274fe6c29SRuslan Bukin 
213374fe6c29SRuslan Bukin /** Return the current core bus ratio.
213474fe6c29SRuslan Bukin  *
213574fe6c29SRuslan Bukin  * On success, provides the current core:bus ratio in \@cbr.  The ratio is
213674fe6c29SRuslan Bukin  * defined as core cycles per bus clock cycle.
213774fe6c29SRuslan Bukin  *
213874fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
213974fe6c29SRuslan Bukin  *
214074fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@cbr is NULL.
214174fe6c29SRuslan Bukin  * Returns -pte_no_cbr if there has not been a CBR packet.
214274fe6c29SRuslan Bukin  */
214374fe6c29SRuslan Bukin extern pt_export int pt_insn_core_bus_ratio(struct pt_insn_decoder *decoder,
214474fe6c29SRuslan Bukin 					    uint32_t *cbr);
214574fe6c29SRuslan Bukin 
214674fe6c29SRuslan Bukin /** Return the current address space identifier.
214774fe6c29SRuslan Bukin  *
214874fe6c29SRuslan Bukin  * On success, provides the current address space identifier in \@asid.
214974fe6c29SRuslan Bukin  *
215074fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_asid).  At most \@size
215174fe6c29SRuslan Bukin  * bytes will be copied and \@asid->size will be set to the actual size of the
215274fe6c29SRuslan Bukin  * provided address space identifier.
215374fe6c29SRuslan Bukin  *
215474fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
215574fe6c29SRuslan Bukin  *
215674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@asid is NULL.
215774fe6c29SRuslan Bukin  */
215874fe6c29SRuslan Bukin extern pt_export int pt_insn_asid(const struct pt_insn_decoder *decoder,
215974fe6c29SRuslan Bukin 				  struct pt_asid *asid, size_t size);
216074fe6c29SRuslan Bukin 
216174fe6c29SRuslan Bukin /** Determine the next instruction.
216274fe6c29SRuslan Bukin  *
216374fe6c29SRuslan Bukin  * On success, provides the next instruction in execution order in \@insn.
216474fe6c29SRuslan Bukin  *
216574fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_insn).
216674fe6c29SRuslan Bukin  *
216774fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
216874fe6c29SRuslan Bukin  * code otherwise.
216974fe6c29SRuslan Bukin  *
217074fe6c29SRuslan Bukin  * Returns pts_eos to indicate the end of the trace stream.  Subsequent calls
217174fe6c29SRuslan Bukin  * to pt_insn_next() will continue to return pts_eos until trace is required
217274fe6c29SRuslan Bukin  * to determine the next instruction.
217374fe6c29SRuslan Bukin  *
217474fe6c29SRuslan Bukin  * Returns -pte_bad_context if the decoder encountered an unexpected packet.
217574fe6c29SRuslan Bukin  * Returns -pte_bad_opc if the decoder encountered unknown packets.
217674fe6c29SRuslan Bukin  * Returns -pte_bad_packet if the decoder encountered unknown packet payloads.
217774fe6c29SRuslan Bukin  * Returns -pte_bad_query if the decoder got out of sync.
217874fe6c29SRuslan Bukin  * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
217974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@insn is NULL.
218074fe6c29SRuslan Bukin  * Returns -pte_nomap if the memory at the instruction address can't be read.
218174fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
218274fe6c29SRuslan Bukin  */
218374fe6c29SRuslan Bukin extern pt_export int pt_insn_next(struct pt_insn_decoder *decoder,
218474fe6c29SRuslan Bukin 				  struct pt_insn *insn, size_t size);
218574fe6c29SRuslan Bukin 
218674fe6c29SRuslan Bukin /** Get the next pending event.
218774fe6c29SRuslan Bukin  *
218874fe6c29SRuslan Bukin  * On success, provides the next event in \@event and updates \@decoder.
218974fe6c29SRuslan Bukin  *
219074fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_event).
219174fe6c29SRuslan Bukin  *
219274fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
219374fe6c29SRuslan Bukin  * code otherwise.
219474fe6c29SRuslan Bukin  *
219574fe6c29SRuslan Bukin  * Returns -pte_bad_query if there is no event.
219674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@event is NULL.
219774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@size is too small.
219874fe6c29SRuslan Bukin  */
219974fe6c29SRuslan Bukin extern pt_export int pt_insn_event(struct pt_insn_decoder *decoder,
220074fe6c29SRuslan Bukin 				   struct pt_event *event, size_t size);
220174fe6c29SRuslan Bukin 
220274fe6c29SRuslan Bukin 
220374fe6c29SRuslan Bukin 
220474fe6c29SRuslan Bukin /* Block decoder. */
220574fe6c29SRuslan Bukin 
220674fe6c29SRuslan Bukin 
220774fe6c29SRuslan Bukin 
220874fe6c29SRuslan Bukin /** A block of instructions.
220974fe6c29SRuslan Bukin  *
221074fe6c29SRuslan Bukin  * Instructions in this block are executed sequentially but are not necessarily
221174fe6c29SRuslan Bukin  * contiguous in memory.  Users are expected to follow direct branches.
221274fe6c29SRuslan Bukin  */
221374fe6c29SRuslan Bukin struct pt_block {
221474fe6c29SRuslan Bukin 	/** The IP of the first instruction in this block. */
221574fe6c29SRuslan Bukin 	uint64_t ip;
221674fe6c29SRuslan Bukin 
221774fe6c29SRuslan Bukin 	/** The IP of the last instruction in this block.
221874fe6c29SRuslan Bukin 	 *
221974fe6c29SRuslan Bukin 	 * This can be used for error-detection.
222074fe6c29SRuslan Bukin 	 */
222174fe6c29SRuslan Bukin 	uint64_t end_ip;
222274fe6c29SRuslan Bukin 
222374fe6c29SRuslan Bukin 	/** The image section that contains the instructions in this block.
222474fe6c29SRuslan Bukin 	 *
222574fe6c29SRuslan Bukin 	 * A value of zero means that the section did not have an identifier.
222674fe6c29SRuslan Bukin 	 * The section was not added via an image section cache or the memory
222774fe6c29SRuslan Bukin 	 * was read via the read memory callback.
222874fe6c29SRuslan Bukin 	 */
222974fe6c29SRuslan Bukin 	int isid;
223074fe6c29SRuslan Bukin 
223174fe6c29SRuslan Bukin 	/** The execution mode for all instructions in this block. */
223274fe6c29SRuslan Bukin 	enum pt_exec_mode mode;
223374fe6c29SRuslan Bukin 
223474fe6c29SRuslan Bukin 	/** The instruction class for the last instruction in this block.
223574fe6c29SRuslan Bukin 	 *
223674fe6c29SRuslan Bukin 	 * This field may be set to ptic_error to indicate that the instruction
223774fe6c29SRuslan Bukin 	 * class is not available.  The block decoder may choose to not provide
223874fe6c29SRuslan Bukin 	 * the instruction class in some cases for performance reasons.
223974fe6c29SRuslan Bukin 	 */
224074fe6c29SRuslan Bukin 	enum pt_insn_class iclass;
224174fe6c29SRuslan Bukin 
224274fe6c29SRuslan Bukin 	/** The number of instructions in this block. */
224374fe6c29SRuslan Bukin 	uint16_t ninsn;
224474fe6c29SRuslan Bukin 
224574fe6c29SRuslan Bukin 	/** The raw bytes of the last instruction in this block in case the
224674fe6c29SRuslan Bukin 	 * instruction does not fit entirely into this block's section.
224774fe6c29SRuslan Bukin 	 *
224874fe6c29SRuslan Bukin 	 * This field is only valid if \@truncated is set.
224974fe6c29SRuslan Bukin 	 */
225074fe6c29SRuslan Bukin 	uint8_t raw[pt_max_insn_size];
225174fe6c29SRuslan Bukin 
225274fe6c29SRuslan Bukin 	/** The size of the last instruction in this block in bytes.
225374fe6c29SRuslan Bukin 	 *
225474fe6c29SRuslan Bukin 	 * This field is only valid if \@truncated is set.
225574fe6c29SRuslan Bukin 	 */
225674fe6c29SRuslan Bukin 	uint8_t size;
225774fe6c29SRuslan Bukin 
225874fe6c29SRuslan Bukin 	/** A collection of flags giving additional information about the
225974fe6c29SRuslan Bukin 	 * instructions in this block.
226074fe6c29SRuslan Bukin 	 *
226174fe6c29SRuslan Bukin 	 * - all instructions in this block were executed speculatively.
226274fe6c29SRuslan Bukin 	 */
226374fe6c29SRuslan Bukin 	uint32_t speculative:1;
226474fe6c29SRuslan Bukin 
226574fe6c29SRuslan Bukin 	/** - the last instruction in this block is truncated.
226674fe6c29SRuslan Bukin 	 *
226774fe6c29SRuslan Bukin 	 *    It starts in this block's section but continues in one or more
226874fe6c29SRuslan Bukin 	 *    other sections depending on how fragmented the memory image is.
226974fe6c29SRuslan Bukin 	 *
227074fe6c29SRuslan Bukin 	 *    The raw bytes for the last instruction are provided in \@raw and
227174fe6c29SRuslan Bukin 	 *    its size in \@size in this case.
227274fe6c29SRuslan Bukin 	 */
227374fe6c29SRuslan Bukin 	uint32_t truncated:1;
227474fe6c29SRuslan Bukin };
227574fe6c29SRuslan Bukin 
227674fe6c29SRuslan Bukin /** Allocate an Intel PT block decoder.
227774fe6c29SRuslan Bukin  *
227874fe6c29SRuslan Bukin  * The decoder will work on the buffer defined in \@config, it shall contain
227974fe6c29SRuslan Bukin  * raw trace data and remain valid for the lifetime of the decoder.
228074fe6c29SRuslan Bukin  *
228174fe6c29SRuslan Bukin  * The decoder needs to be synchronized before it can be used.
228274fe6c29SRuslan Bukin  */
228374fe6c29SRuslan Bukin extern pt_export struct pt_block_decoder *
228474fe6c29SRuslan Bukin pt_blk_alloc_decoder(const struct pt_config *config);
228574fe6c29SRuslan Bukin 
228674fe6c29SRuslan Bukin /** Free an Intel PT block decoder.
228774fe6c29SRuslan Bukin  *
228874fe6c29SRuslan Bukin  * This will destroy the decoder's default image.
228974fe6c29SRuslan Bukin  *
229074fe6c29SRuslan Bukin  * The \@decoder must not be used after a successful return.
229174fe6c29SRuslan Bukin  */
229274fe6c29SRuslan Bukin extern pt_export void pt_blk_free_decoder(struct pt_block_decoder *decoder);
229374fe6c29SRuslan Bukin 
229474fe6c29SRuslan Bukin /** Synchronize an Intel PT block decoder.
229574fe6c29SRuslan Bukin  *
229674fe6c29SRuslan Bukin  * Search for the next synchronization point in forward or backward direction.
229774fe6c29SRuslan Bukin  *
229874fe6c29SRuslan Bukin  * If \@decoder has not been synchronized, yet, the search is started at the
229974fe6c29SRuslan Bukin  * beginning of the trace buffer in case of forward synchronization and at the
230074fe6c29SRuslan Bukin  * end of the trace buffer in case of backward synchronization.
230174fe6c29SRuslan Bukin  *
230274fe6c29SRuslan Bukin  * Returns zero or a positive value on success, a negative error code otherwise.
230374fe6c29SRuslan Bukin  *
230474fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
230574fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
230674fe6c29SRuslan Bukin  * Returns -pte_eos if no further synchronization point is found.
230774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
230874fe6c29SRuslan Bukin  */
230974fe6c29SRuslan Bukin extern pt_export int pt_blk_sync_forward(struct pt_block_decoder *decoder);
231074fe6c29SRuslan Bukin extern pt_export int pt_blk_sync_backward(struct pt_block_decoder *decoder);
231174fe6c29SRuslan Bukin 
231274fe6c29SRuslan Bukin /** Manually synchronize an Intel PT block decoder.
231374fe6c29SRuslan Bukin  *
231474fe6c29SRuslan Bukin  * Synchronize \@decoder on the syncpoint at \@offset.  There must be a PSB
231574fe6c29SRuslan Bukin  * packet at \@offset.
231674fe6c29SRuslan Bukin  *
231774fe6c29SRuslan Bukin  * Returns zero or a positive value on success, a negative error code otherwise.
231874fe6c29SRuslan Bukin  *
231974fe6c29SRuslan Bukin  * Returns -pte_bad_opc if an unknown packet is encountered.
232074fe6c29SRuslan Bukin  * Returns -pte_bad_packet if an unknown packet payload is encountered.
232174fe6c29SRuslan Bukin  * Returns -pte_eos if \@offset lies outside of \@decoder's trace buffer.
232274fe6c29SRuslan Bukin  * Returns -pte_eos if \@decoder reaches the end of its trace buffer.
232374fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder is NULL.
232474fe6c29SRuslan Bukin  * Returns -pte_nosync if there is no syncpoint at \@offset.
232574fe6c29SRuslan Bukin  */
232674fe6c29SRuslan Bukin extern pt_export int pt_blk_sync_set(struct pt_block_decoder *decoder,
232774fe6c29SRuslan Bukin 				     uint64_t offset);
232874fe6c29SRuslan Bukin 
232974fe6c29SRuslan Bukin /** Get the current decoder position.
233074fe6c29SRuslan Bukin  *
233174fe6c29SRuslan Bukin  * Fills the current \@decoder position into \@offset.
233274fe6c29SRuslan Bukin  *
233374fe6c29SRuslan Bukin  * This is useful for reporting errors.
233474fe6c29SRuslan Bukin  *
233574fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
233674fe6c29SRuslan Bukin  *
233774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
233874fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
233974fe6c29SRuslan Bukin  */
234074fe6c29SRuslan Bukin extern pt_export int pt_blk_get_offset(const struct pt_block_decoder *decoder,
234174fe6c29SRuslan Bukin 				       uint64_t *offset);
234274fe6c29SRuslan Bukin 
234374fe6c29SRuslan Bukin /** Get the position of the last synchronization point.
234474fe6c29SRuslan Bukin  *
234574fe6c29SRuslan Bukin  * Fills the last synchronization position into \@offset.
234674fe6c29SRuslan Bukin  *
234774fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
234874fe6c29SRuslan Bukin  *
234974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@offset is NULL.
235074fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
235174fe6c29SRuslan Bukin  */
235274fe6c29SRuslan Bukin extern pt_export int
235374fe6c29SRuslan Bukin pt_blk_get_sync_offset(const struct pt_block_decoder *decoder,
235474fe6c29SRuslan Bukin 		       uint64_t *offset);
235574fe6c29SRuslan Bukin 
235674fe6c29SRuslan Bukin /** Get the traced image.
235774fe6c29SRuslan Bukin  *
235874fe6c29SRuslan Bukin  * The returned image may be modified as long as \@decoder is not running.
235974fe6c29SRuslan Bukin  *
236074fe6c29SRuslan Bukin  * Returns a pointer to the traced image \@decoder uses for reading memory.
236174fe6c29SRuslan Bukin  * Returns NULL if \@decoder is NULL.
236274fe6c29SRuslan Bukin  */
236374fe6c29SRuslan Bukin extern pt_export struct pt_image *
236474fe6c29SRuslan Bukin pt_blk_get_image(struct pt_block_decoder *decoder);
236574fe6c29SRuslan Bukin 
236674fe6c29SRuslan Bukin /** Set the traced image.
236774fe6c29SRuslan Bukin  *
236874fe6c29SRuslan Bukin  * Sets the image that \@decoder uses for reading memory to \@image.  If \@image
236974fe6c29SRuslan Bukin  * is NULL, sets the image to \@decoder's default image.
237074fe6c29SRuslan Bukin  *
237174fe6c29SRuslan Bukin  * Only one image can be active at any time.
237274fe6c29SRuslan Bukin  *
237374fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
237474fe6c29SRuslan Bukin  * Return -pte_invalid if \@decoder is NULL.
237574fe6c29SRuslan Bukin  */
237674fe6c29SRuslan Bukin extern pt_export int pt_blk_set_image(struct pt_block_decoder *decoder,
237774fe6c29SRuslan Bukin 				      struct pt_image *image);
237874fe6c29SRuslan Bukin 
237974fe6c29SRuslan Bukin /* Return a pointer to \@decoder's configuration.
238074fe6c29SRuslan Bukin  *
238174fe6c29SRuslan Bukin  * Returns a non-null pointer on success, NULL if \@decoder is NULL.
238274fe6c29SRuslan Bukin  */
238374fe6c29SRuslan Bukin extern pt_export const struct pt_config *
238474fe6c29SRuslan Bukin pt_blk_get_config(const struct pt_block_decoder *decoder);
238574fe6c29SRuslan Bukin 
238674fe6c29SRuslan Bukin /** Return the current time.
238774fe6c29SRuslan Bukin  *
238874fe6c29SRuslan Bukin  * On success, provides the time at the last preceding timing packet in \@time.
238974fe6c29SRuslan Bukin  *
239074fe6c29SRuslan Bukin  * The time is similar to what a rdtsc instruction would return.  Depending
239174fe6c29SRuslan Bukin  * on the configuration, the time may not be fully accurate.  If TSC is not
239274fe6c29SRuslan Bukin  * enabled, the time is relative to the last synchronization and can't be used
239374fe6c29SRuslan Bukin  * to correlate with other TSC-based time sources.  In this case, -pte_no_time
239474fe6c29SRuslan Bukin  * is returned and the relative time is provided in \@time.
239574fe6c29SRuslan Bukin  *
239674fe6c29SRuslan Bukin  * Some timing-related packets may need to be dropped (mostly due to missing
239774fe6c29SRuslan Bukin  * calibration or incomplete configuration).  To get an idea about the quality
239874fe6c29SRuslan Bukin  * of the estimated time, we record the number of dropped MTC and CYC packets.
239974fe6c29SRuslan Bukin  *
240074fe6c29SRuslan Bukin  * If \@lost_mtc is not NULL, set it to the number of lost MTC packets.
240174fe6c29SRuslan Bukin  * If \@lost_cyc is not NULL, set it to the number of lost CYC packets.
240274fe6c29SRuslan Bukin  *
240374fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
240474fe6c29SRuslan Bukin  *
240574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@time is NULL.
240674fe6c29SRuslan Bukin  * Returns -pte_no_time if there has not been a TSC packet.
240774fe6c29SRuslan Bukin  */
240874fe6c29SRuslan Bukin extern pt_export int pt_blk_time(struct pt_block_decoder *decoder,
240974fe6c29SRuslan Bukin 				 uint64_t *time, uint32_t *lost_mtc,
241074fe6c29SRuslan Bukin 				 uint32_t *lost_cyc);
241174fe6c29SRuslan Bukin 
241274fe6c29SRuslan Bukin /** Return the current core bus ratio.
241374fe6c29SRuslan Bukin  *
241474fe6c29SRuslan Bukin  * On success, provides the current core:bus ratio in \@cbr.  The ratio is
241574fe6c29SRuslan Bukin  * defined as core cycles per bus clock cycle.
241674fe6c29SRuslan Bukin  *
241774fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
241874fe6c29SRuslan Bukin  *
241974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@cbr is NULL.
242074fe6c29SRuslan Bukin  * Returns -pte_no_cbr if there has not been a CBR packet.
242174fe6c29SRuslan Bukin  */
242274fe6c29SRuslan Bukin extern pt_export int pt_blk_core_bus_ratio(struct pt_block_decoder *decoder,
242374fe6c29SRuslan Bukin 					   uint32_t *cbr);
242474fe6c29SRuslan Bukin 
242574fe6c29SRuslan Bukin /** Return the current address space identifier.
242674fe6c29SRuslan Bukin  *
242774fe6c29SRuslan Bukin  * On success, provides the current address space identifier in \@asid.
242874fe6c29SRuslan Bukin  *
242974fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_asid).  At most \@size
243074fe6c29SRuslan Bukin  * bytes will be copied and \@asid->size will be set to the actual size of the
243174fe6c29SRuslan Bukin  * provided address space identifier.
243274fe6c29SRuslan Bukin  *
243374fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
243474fe6c29SRuslan Bukin  *
243574fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@asid is NULL.
243674fe6c29SRuslan Bukin  */
243774fe6c29SRuslan Bukin extern pt_export int pt_blk_asid(const struct pt_block_decoder *decoder,
243874fe6c29SRuslan Bukin 				 struct pt_asid *asid, size_t size);
243974fe6c29SRuslan Bukin 
244074fe6c29SRuslan Bukin /** Determine the next block of instructions.
244174fe6c29SRuslan Bukin  *
244274fe6c29SRuslan Bukin  * On success, provides the next block of instructions in execution order in
244374fe6c29SRuslan Bukin  * \@block.
244474fe6c29SRuslan Bukin  *
244574fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_block).
244674fe6c29SRuslan Bukin  *
244774fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
244874fe6c29SRuslan Bukin  * code otherwise.
244974fe6c29SRuslan Bukin  *
245074fe6c29SRuslan Bukin  * Returns pts_eos to indicate the end of the trace stream.  Subsequent calls
245174fe6c29SRuslan Bukin  * to pt_block_next() will continue to return pts_eos until trace is required
245274fe6c29SRuslan Bukin  * to determine the next instruction.
245374fe6c29SRuslan Bukin  *
245474fe6c29SRuslan Bukin  * Returns -pte_bad_context if the decoder encountered an unexpected packet.
245574fe6c29SRuslan Bukin  * Returns -pte_bad_opc if the decoder encountered unknown packets.
245674fe6c29SRuslan Bukin  * Returns -pte_bad_packet if the decoder encountered unknown packet payloads.
245774fe6c29SRuslan Bukin  * Returns -pte_bad_query if the decoder got out of sync.
245874fe6c29SRuslan Bukin  * Returns -pte_eos if decoding reached the end of the Intel PT buffer.
245974fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@block is NULL.
246074fe6c29SRuslan Bukin  * Returns -pte_nomap if the memory at the instruction address can't be read.
246174fe6c29SRuslan Bukin  * Returns -pte_nosync if \@decoder is out of sync.
246274fe6c29SRuslan Bukin  */
246374fe6c29SRuslan Bukin extern pt_export int pt_blk_next(struct pt_block_decoder *decoder,
246474fe6c29SRuslan Bukin 				 struct pt_block *block, size_t size);
246574fe6c29SRuslan Bukin 
246674fe6c29SRuslan Bukin /** Get the next pending event.
246774fe6c29SRuslan Bukin  *
246874fe6c29SRuslan Bukin  * On success, provides the next event in \@event and updates \@decoder.
246974fe6c29SRuslan Bukin  *
247074fe6c29SRuslan Bukin  * The \@size argument must be set to sizeof(struct pt_event).
247174fe6c29SRuslan Bukin  *
247274fe6c29SRuslan Bukin  * Returns a non-negative pt_status_flag bit-vector on success, a negative error
247374fe6c29SRuslan Bukin  * code otherwise.
247474fe6c29SRuslan Bukin  *
247574fe6c29SRuslan Bukin  * Returns -pte_bad_query if there is no event.
247674fe6c29SRuslan Bukin  * Returns -pte_invalid if \@decoder or \@event is NULL.
247774fe6c29SRuslan Bukin  * Returns -pte_invalid if \@size is too small.
247874fe6c29SRuslan Bukin  */
247974fe6c29SRuslan Bukin extern pt_export int pt_blk_event(struct pt_block_decoder *decoder,
248074fe6c29SRuslan Bukin 				  struct pt_event *event, size_t size);
248174fe6c29SRuslan Bukin 
248274fe6c29SRuslan Bukin #ifdef __cplusplus
248374fe6c29SRuslan Bukin }
248474fe6c29SRuslan Bukin #endif
248574fe6c29SRuslan Bukin 
248674fe6c29SRuslan Bukin #endif /* INTEL_PT_H */
2487