1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
/*
* Copyright (c) 2014-2025, Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PT_TIME_H
#define PT_TIME_H
#include <stdint.h>
struct pt_config;
struct pt_packet_tsc;
struct pt_packet_cbr;
struct pt_packet_tma;
struct pt_packet_mtc;
struct pt_packet_cyc;
/* Intel(R) Processor Trace timing. */
struct pt_time {
/* The estimated Time Stamp Count. */
uint64_t tsc;
/* The base Time Stamp Count (from TSC and MTC). */
uint64_t base;
/* The estimated Fast Counter. */
uint64_t fc;
/* The adjusted last CTC value (from MTC and TMA). */
uint32_t ctc;
/* The adjusted CTC value when @fc was cleared (from MTC and TMA). */
uint32_t ctc_cyc;
/* The number of lost MTC updates. */
uint32_t lost_mtc;
/* The number of lost CYC updates. */
uint32_t lost_cyc;
/* The core:bus ratio. */
uint8_t cbr;
/* A flag saying whether we have seen a TSC packet. */
uint32_t have_tsc:1;
/* A flag saying whether we have seen a CBR packet. */
uint32_t have_cbr:1;
/* A flag saying whether we have seen a TMA packet. */
uint32_t have_tma:1;
/* A flag saying whether we have seen a MTC packet. */
uint32_t have_mtc:1;
};
/* Initialize (or reset) the time. */
extern void pt_time_init(struct pt_time *time);
/* Query the current time.
*
* Provides the estimated Time Stamp Count value in @tsc.
*
* If @lost_mtc is not NULL, provides the number of lost MTC packets.
* If @lost_cyc is not NULL, provides the number of lost CYC packets.
*
* Returns zero on success; a negative error code, otherwise.
* Returns -pte_internal if @tsc or @time is NULL.
* Returns -pte_no_time if there has not been a TSC packet.
*/
extern int pt_time_query_tsc(uint64_t *tsc, uint32_t *lost_mtc,
uint32_t *lost_cyc, const struct pt_time *time);
/* Query the current core:bus ratio.
*
* Provides the core:bus ratio in @cbr.
*
* Returns zero on success; a negative error code, otherwise.
* Returns -pte_internal if @cbr or @time is NULL.
* Returns -pte_no_cbr if there has not been a CBR packet.
*/
extern int pt_time_query_cbr(uint32_t *cbr, const struct pt_time *time);
/* Update the time based on an Intel PT packet.
*
* Returns zero on success.
* Returns a negative error code, otherwise.
*/
extern int pt_time_update_tsc(struct pt_time *, const struct pt_packet_tsc *,
const struct pt_config *);
extern int pt_time_update_cbr(struct pt_time *, const struct pt_packet_cbr *,
const struct pt_config *);
extern int pt_time_update_tma(struct pt_time *, const struct pt_packet_tma *,
const struct pt_config *);
extern int pt_time_update_mtc(struct pt_time *, const struct pt_packet_mtc *,
const struct pt_config *);
/* @fcr is the fast-counter:cycles ratio obtained by calibration. */
extern int pt_time_update_cyc(struct pt_time *, const struct pt_packet_cyc *,
const struct pt_config *, uint64_t fcr);
/* Timing calibration.
*
* Used for estimating the Fast-Counter:Cycles ratio.
*
* Ideally, we calibrate by counting CYCs between MTCs. Lacking MTCs, we
* use TSC, instead.
*/
struct pt_time_cal {
/* The estimated fast-counter:cycles ratio. */
uint64_t fcr;
/* The minimal and maximal @fcr values. */
uint64_t min_fcr, max_fcr;
/* The last TSC value.
*
* Used for calibrating at TSC.
*/
uint64_t tsc;
/* The number of cycles since the last TSC (from CYC).
*
* Used for calibrating at TSC.
*/
uint64_t cyc_tsc;
/* The number of cycles since the last MTC (from CYC).
*
* Used for calibrating at MTC.
*/
uint64_t cyc_mtc;
/* The adjusted last CTC value (from MTC).
*
* Used for calibrating at MTC.
*/
uint32_t ctc;
/* The number of lost MTC updates since the last successful update. */
uint32_t lost_mtc;
/* A flag saying whether we have seen a MTC packet. */
uint32_t have_mtc:1;
/* A flag saying whether we need to check for erratum SKL168. */
uint32_t check_skl168:1;
};
enum {
/* The amount by which the fcr value is right-shifted.
*
* Do not shift the value obtained by pt_tcal_fcr() when passing it to
* pt_time_update_cyc().
* Do shift the value passed to pt_tcal_set_fcr().
*/
pt_tcal_fcr_shr = 8
};
/* Initialize of reset timing calibration. */
extern void pt_tcal_init(struct pt_time_cal *tcal);
/* Query the estimated fast-counter:cycles ratio.
*
* Provides the estimated ratio in @fcr unless -pte_internal or
* -pte_no_time is returned.
*
* Returns zero on success, a negative error code otherwise.
* Returns -pte_internal if @fcr or @tcal is NULL.
* Returns -pte_no_time if no information is available.
*/
extern int pt_tcal_fcr(uint64_t *fcr, const struct pt_time_cal *tcal);
/* Set the fast-counter:cycles ratio.
*
* Timing calibration takes one CBR or two MTC packets before it can provide
* first estimations. Use this to supply an initial value to be used in the
* meantime.
*
* Returns zero on success, a negative error code otherwise.
* Returns -pte_internal if @cal is NULL.
*/
extern int pt_tcal_set_fcr(struct pt_time_cal *tcal, uint64_t fcr);
/* Update calibration based on an Intel PT packet.
*
* Returns zero on success, a negative error code otherwise.
*/
extern int pt_tcal_update_tsc(struct pt_time_cal *,
const struct pt_packet_tsc *,
const struct pt_config *);
extern int pt_tcal_header_tsc(struct pt_time_cal *,
const struct pt_packet_tsc *,
const struct pt_config *);
extern int pt_tcal_update_cbr(struct pt_time_cal *,
const struct pt_packet_cbr *,
const struct pt_config *);
extern int pt_tcal_header_cbr(struct pt_time_cal *,
const struct pt_packet_cbr *,
const struct pt_config *);
extern int pt_tcal_update_tma(struct pt_time_cal *,
const struct pt_packet_tma *,
const struct pt_config *);
extern int pt_tcal_update_mtc(struct pt_time_cal *,
const struct pt_packet_mtc *,
const struct pt_config *);
extern int pt_tcal_update_cyc(struct pt_time_cal *,
const struct pt_packet_cyc *,
const struct pt_config *);
extern int pt_tcal_update_psb(struct pt_time_cal *,
const struct pt_config *);
extern int pt_tcal_update_ovf(struct pt_time_cal *,
const struct pt_config *);
#endif /* PT_TIME_H */
|