aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c162
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.h1
2 files changed, 159 insertions, 4 deletions
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 4a0e9fb1d173..f7119a11a4b6 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -85,7 +85,9 @@ struct intel_pt_decoder {
85 const unsigned char *buf; 85 const unsigned char *buf;
86 size_t len; 86 size_t len;
87 bool return_compression; 87 bool return_compression;
88 bool mtc_insn;
88 bool pge; 89 bool pge;
90 bool have_tma;
89 uint64_t pos; 91 uint64_t pos;
90 uint64_t last_ip; 92 uint64_t last_ip;
91 uint64_t ip; 93 uint64_t ip;
@@ -94,6 +96,15 @@ struct intel_pt_decoder {
94 uint64_t tsc_timestamp; 96 uint64_t tsc_timestamp;
95 uint64_t ref_timestamp; 97 uint64_t ref_timestamp;
96 uint64_t ret_addr; 98 uint64_t ret_addr;
99 uint64_t ctc_timestamp;
100 uint64_t ctc_delta;
101 uint32_t last_mtc;
102 uint32_t tsc_ctc_ratio_n;
103 uint32_t tsc_ctc_ratio_d;
104 uint32_t tsc_ctc_mult;
105 uint32_t tsc_slip;
106 uint32_t ctc_rem_mask;
107 int mtc_shift;
97 struct intel_pt_stack stack; 108 struct intel_pt_stack stack;
98 enum intel_pt_pkt_state pkt_state; 109 enum intel_pt_pkt_state pkt_state;
99 struct intel_pt_pkt packet; 110 struct intel_pt_pkt packet;
@@ -149,6 +160,13 @@ static void intel_pt_setup_period(struct intel_pt_decoder *decoder)
149 } 160 }
150} 161}
151 162
163static uint64_t multdiv(uint64_t t, uint32_t n, uint32_t d)
164{
165 if (!d)
166 return 0;
167 return (t / d) * n + ((t % d) * n) / d;
168}
169
152struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params) 170struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
153{ 171{
154 struct intel_pt_decoder *decoder; 172 struct intel_pt_decoder *decoder;
@@ -175,6 +193,39 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
175 193
176 intel_pt_setup_period(decoder); 194 intel_pt_setup_period(decoder);
177 195
196 decoder->mtc_shift = params->mtc_period;
197 decoder->ctc_rem_mask = (1 << decoder->mtc_shift) - 1;
198
199 decoder->tsc_ctc_ratio_n = params->tsc_ctc_ratio_n;
200 decoder->tsc_ctc_ratio_d = params->tsc_ctc_ratio_d;
201
202 if (!decoder->tsc_ctc_ratio_n)
203 decoder->tsc_ctc_ratio_d = 0;
204
205 if (decoder->tsc_ctc_ratio_d) {
206 if (!(decoder->tsc_ctc_ratio_n % decoder->tsc_ctc_ratio_d))
207 decoder->tsc_ctc_mult = decoder->tsc_ctc_ratio_n /
208 decoder->tsc_ctc_ratio_d;
209
210 /*
211 * Allow for timestamps appearing to backwards because a TSC
212 * packet has slipped past a MTC packet, so allow 2 MTC ticks
213 * or ...
214 */
215 decoder->tsc_slip = multdiv(2 << decoder->mtc_shift,
216 decoder->tsc_ctc_ratio_n,
217 decoder->tsc_ctc_ratio_d);
218 }
219 /* ... or 0x100 paranoia */
220 if (decoder->tsc_slip < 0x100)
221 decoder->tsc_slip = 0x100;
222
223 intel_pt_log("timestamp: mtc_shift %u\n", decoder->mtc_shift);
224 intel_pt_log("timestamp: tsc_ctc_ratio_n %u\n", decoder->tsc_ctc_ratio_n);
225 intel_pt_log("timestamp: tsc_ctc_ratio_d %u\n", decoder->tsc_ctc_ratio_d);
226 intel_pt_log("timestamp: tsc_ctc_mult %u\n", decoder->tsc_ctc_mult);
227 intel_pt_log("timestamp: tsc_slip %#x\n", decoder->tsc_slip);
228
178 return decoder; 229 return decoder;
179} 230}
180 231
@@ -368,6 +419,7 @@ static inline void intel_pt_update_in_tx(struct intel_pt_decoder *decoder)
368static int intel_pt_bad_packet(struct intel_pt_decoder *decoder) 419static int intel_pt_bad_packet(struct intel_pt_decoder *decoder)
369{ 420{
370 intel_pt_clear_tx_flags(decoder); 421 intel_pt_clear_tx_flags(decoder);
422 decoder->have_tma = false;
371 decoder->pkt_len = 1; 423 decoder->pkt_len = 1;
372 decoder->pkt_step = 1; 424 decoder->pkt_step = 1;
373 intel_pt_decoder_log_packet(decoder); 425 intel_pt_decoder_log_packet(decoder);
@@ -400,6 +452,7 @@ static int intel_pt_get_data(struct intel_pt_decoder *decoder)
400 decoder->pkt_state = INTEL_PT_STATE_NO_PSB; 452 decoder->pkt_state = INTEL_PT_STATE_NO_PSB;
401 decoder->ref_timestamp = buffer.ref_timestamp; 453 decoder->ref_timestamp = buffer.ref_timestamp;
402 decoder->timestamp = 0; 454 decoder->timestamp = 0;
455 decoder->have_tma = false;
403 decoder->state.trace_nr = buffer.trace_nr; 456 decoder->state.trace_nr = buffer.trace_nr;
404 intel_pt_log("Reference timestamp 0x%" PRIx64 "\n", 457 intel_pt_log("Reference timestamp 0x%" PRIx64 "\n",
405 decoder->ref_timestamp); 458 decoder->ref_timestamp);
@@ -523,6 +576,7 @@ static uint64_t intel_pt_next_sample(struct intel_pt_decoder *decoder)
523 case INTEL_PT_PERIOD_TICKS: 576 case INTEL_PT_PERIOD_TICKS:
524 return intel_pt_next_period(decoder); 577 return intel_pt_next_period(decoder);
525 case INTEL_PT_PERIOD_NONE: 578 case INTEL_PT_PERIOD_NONE:
579 case INTEL_PT_PERIOD_MTC:
526 default: 580 default:
527 return 0; 581 return 0;
528 } 582 }
@@ -542,6 +596,7 @@ static void intel_pt_sample_insn(struct intel_pt_decoder *decoder)
542 decoder->last_masked_timestamp = masked_timestamp; 596 decoder->last_masked_timestamp = masked_timestamp;
543 break; 597 break;
544 case INTEL_PT_PERIOD_NONE: 598 case INTEL_PT_PERIOD_NONE:
599 case INTEL_PT_PERIOD_MTC:
545 default: 600 default:
546 break; 601 break;
547 } 602 }
@@ -555,6 +610,9 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
555 uint64_t max_insn_cnt, insn_cnt = 0; 610 uint64_t max_insn_cnt, insn_cnt = 0;
556 int err; 611 int err;
557 612
613 if (!decoder->mtc_insn)
614 decoder->mtc_insn = true;
615
558 max_insn_cnt = intel_pt_next_sample(decoder); 616 max_insn_cnt = intel_pt_next_sample(decoder);
559 617
560 err = decoder->walk_insn(intel_pt_insn, &insn_cnt, &decoder->ip, ip, 618 err = decoder->walk_insn(intel_pt_insn, &insn_cnt, &decoder->ip, ip,
@@ -861,6 +919,8 @@ static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
861{ 919{
862 uint64_t timestamp; 920 uint64_t timestamp;
863 921
922 decoder->have_tma = false;
923
864 if (decoder->ref_timestamp) { 924 if (decoder->ref_timestamp) {
865 timestamp = decoder->packet.payload | 925 timestamp = decoder->packet.payload |
866 (decoder->ref_timestamp & (0xffULL << 56)); 926 (decoder->ref_timestamp & (0xffULL << 56));
@@ -878,17 +938,18 @@ static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
878 } else if (decoder->timestamp) { 938 } else if (decoder->timestamp) {
879 timestamp = decoder->packet.payload | 939 timestamp = decoder->packet.payload |
880 (decoder->timestamp & (0xffULL << 56)); 940 (decoder->timestamp & (0xffULL << 56));
941 decoder->tsc_timestamp = timestamp;
881 if (timestamp < decoder->timestamp && 942 if (timestamp < decoder->timestamp &&
882 decoder->timestamp - timestamp < 0x100) { 943 decoder->timestamp - timestamp < decoder->tsc_slip) {
883 intel_pt_log_to("ERROR: Suppressing backwards timestamp", 944 intel_pt_log_to("Suppressing backwards timestamp",
884 timestamp); 945 timestamp);
885 timestamp = decoder->timestamp; 946 timestamp = decoder->timestamp;
886 } 947 }
887 while (timestamp < decoder->timestamp) { 948 while (timestamp < decoder->timestamp) {
888 intel_pt_log_to("Wraparound timestamp", timestamp); 949 intel_pt_log_to("Wraparound timestamp", timestamp);
889 timestamp += (1ULL << 56); 950 timestamp += (1ULL << 56);
951 decoder->tsc_timestamp = timestamp;
890 } 952 }
891 decoder->tsc_timestamp = timestamp;
892 decoder->timestamp = timestamp; 953 decoder->timestamp = timestamp;
893 decoder->timestamp_insn_cnt = 0; 954 decoder->timestamp_insn_cnt = 0;
894 } 955 }
@@ -900,11 +961,73 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder)
900{ 961{
901 intel_pt_log("ERROR: Buffer overflow\n"); 962 intel_pt_log("ERROR: Buffer overflow\n");
902 intel_pt_clear_tx_flags(decoder); 963 intel_pt_clear_tx_flags(decoder);
964 decoder->have_tma = false;
903 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC; 965 decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
904 decoder->overflow = true; 966 decoder->overflow = true;
905 return -EOVERFLOW; 967 return -EOVERFLOW;
906} 968}
907 969
970static void intel_pt_calc_tma(struct intel_pt_decoder *decoder)
971{
972 uint32_t ctc = decoder->packet.payload;
973 uint32_t fc = decoder->packet.count;
974 uint32_t ctc_rem = ctc & decoder->ctc_rem_mask;
975
976 if (!decoder->tsc_ctc_ratio_d)
977 return;
978
979 decoder->last_mtc = (ctc >> decoder->mtc_shift) & 0xff;
980 decoder->ctc_timestamp = decoder->tsc_timestamp - fc;
981 if (decoder->tsc_ctc_mult) {
982 decoder->ctc_timestamp -= ctc_rem * decoder->tsc_ctc_mult;
983 } else {
984 decoder->ctc_timestamp -= multdiv(ctc_rem,
985 decoder->tsc_ctc_ratio_n,
986 decoder->tsc_ctc_ratio_d);
987 }
988 decoder->ctc_delta = 0;
989 decoder->have_tma = true;
990 intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n",
991 decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
992}
993
994static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
995{
996 uint64_t timestamp;
997 uint32_t mtc, mtc_delta;
998
999 if (!decoder->have_tma)
1000 return;
1001
1002 mtc = decoder->packet.payload;
1003
1004 if (mtc > decoder->last_mtc)
1005 mtc_delta = mtc - decoder->last_mtc;
1006 else
1007 mtc_delta = mtc + 256 - decoder->last_mtc;
1008
1009 decoder->ctc_delta += mtc_delta << decoder->mtc_shift;
1010
1011 if (decoder->tsc_ctc_mult) {
1012 timestamp = decoder->ctc_timestamp +
1013 decoder->ctc_delta * decoder->tsc_ctc_mult;
1014 } else {
1015 timestamp = decoder->ctc_timestamp +
1016 multdiv(decoder->ctc_delta,
1017 decoder->tsc_ctc_ratio_n,
1018 decoder->tsc_ctc_ratio_d);
1019 }
1020
1021 if (timestamp < decoder->timestamp)
1022 intel_pt_log("Suppressing MTC timestamp " x64_fmt " less than current timestamp " x64_fmt "\n",
1023 timestamp, decoder->timestamp);
1024 else
1025 decoder->timestamp = timestamp;
1026
1027 decoder->timestamp_insn_cnt = 0;
1028 decoder->last_mtc = mtc;
1029}
1030
908/* Walk PSB+ packets when already in sync. */ 1031/* Walk PSB+ packets when already in sync. */
909static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder) 1032static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
910{ 1033{
@@ -926,6 +1049,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
926 case INTEL_PT_TRACESTOP: 1049 case INTEL_PT_TRACESTOP:
927 case INTEL_PT_BAD: 1050 case INTEL_PT_BAD:
928 case INTEL_PT_PSB: 1051 case INTEL_PT_PSB:
1052 decoder->have_tma = false;
929 intel_pt_log("ERROR: Unexpected packet\n"); 1053 intel_pt_log("ERROR: Unexpected packet\n");
930 return -EAGAIN; 1054 return -EAGAIN;
931 1055
@@ -937,6 +1061,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
937 break; 1061 break;
938 1062
939 case INTEL_PT_TMA: 1063 case INTEL_PT_TMA:
1064 intel_pt_calc_tma(decoder);
940 break; 1065 break;
941 1066
942 case INTEL_PT_CBR: 1067 case INTEL_PT_CBR:
@@ -961,6 +1086,9 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
961 break; 1086 break;
962 1087
963 case INTEL_PT_MTC: 1088 case INTEL_PT_MTC:
1089 intel_pt_calc_mtc_timestamp(decoder);
1090 if (decoder->period_type == INTEL_PT_PERIOD_MTC)
1091 decoder->state.type |= INTEL_PT_INSTRUCTION;
964 break; 1092 break;
965 1093
966 case INTEL_PT_CYC: 1094 case INTEL_PT_CYC:
@@ -1048,6 +1176,9 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
1048 break; 1176 break;
1049 1177
1050 case INTEL_PT_MTC: 1178 case INTEL_PT_MTC:
1179 intel_pt_calc_mtc_timestamp(decoder);
1180 if (decoder->period_type == INTEL_PT_PERIOD_MTC)
1181 decoder->state.type |= INTEL_PT_INSTRUCTION;
1051 break; 1182 break;
1052 1183
1053 case INTEL_PT_CYC: 1184 case INTEL_PT_CYC:
@@ -1159,13 +1290,31 @@ next:
1159 break; 1290 break;
1160 1291
1161 case INTEL_PT_MTC: 1292 case INTEL_PT_MTC:
1162 break; 1293 intel_pt_calc_mtc_timestamp(decoder);
1294 if (decoder->period_type != INTEL_PT_PERIOD_MTC)
1295 break;
1296 /*
1297 * Ensure that there has been an instruction since the
1298 * last MTC.
1299 */
1300 if (!decoder->mtc_insn)
1301 break;
1302 decoder->mtc_insn = false;
1303 /* Ensure that there is a timestamp */
1304 if (!decoder->timestamp)
1305 break;
1306 decoder->state.type = INTEL_PT_INSTRUCTION;
1307 decoder->state.from_ip = decoder->ip;
1308 decoder->state.to_ip = 0;
1309 decoder->mtc_insn = false;
1310 return 0;
1163 1311
1164 case INTEL_PT_TSC: 1312 case INTEL_PT_TSC:
1165 intel_pt_calc_tsc_timestamp(decoder); 1313 intel_pt_calc_tsc_timestamp(decoder);
1166 break; 1314 break;
1167 1315
1168 case INTEL_PT_TMA: 1316 case INTEL_PT_TMA:
1317 intel_pt_calc_tma(decoder);
1169 break; 1318 break;
1170 1319
1171 case INTEL_PT_CYC: 1320 case INTEL_PT_CYC:
@@ -1237,6 +1386,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1237 break; 1386 break;
1238 1387
1239 case INTEL_PT_MTC: 1388 case INTEL_PT_MTC:
1389 intel_pt_calc_mtc_timestamp(decoder);
1240 break; 1390 break;
1241 1391
1242 case INTEL_PT_TSC: 1392 case INTEL_PT_TSC:
@@ -1244,6 +1394,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1244 break; 1394 break;
1245 1395
1246 case INTEL_PT_TMA: 1396 case INTEL_PT_TMA:
1397 intel_pt_calc_tma(decoder);
1247 break; 1398 break;
1248 1399
1249 case INTEL_PT_CYC: 1400 case INTEL_PT_CYC:
@@ -1267,6 +1418,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
1267 1418
1268 case INTEL_PT_TRACESTOP: 1419 case INTEL_PT_TRACESTOP:
1269 case INTEL_PT_TNT: 1420 case INTEL_PT_TNT:
1421 decoder->have_tma = false;
1270 intel_pt_log("ERROR: Unexpected packet\n"); 1422 intel_pt_log("ERROR: Unexpected packet\n");
1271 if (decoder->ip) 1423 if (decoder->ip)
1272 decoder->pkt_state = INTEL_PT_STATE_ERR4; 1424 decoder->pkt_state = INTEL_PT_STATE_ERR4;
@@ -1329,6 +1481,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1329 break; 1481 break;
1330 1482
1331 case INTEL_PT_MTC: 1483 case INTEL_PT_MTC:
1484 intel_pt_calc_mtc_timestamp(decoder);
1332 break; 1485 break;
1333 1486
1334 case INTEL_PT_TSC: 1487 case INTEL_PT_TSC:
@@ -1336,6 +1489,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
1336 break; 1489 break;
1337 1490
1338 case INTEL_PT_TMA: 1491 case INTEL_PT_TMA:
1492 intel_pt_calc_tma(decoder);
1339 break; 1493 break;
1340 1494
1341 case INTEL_PT_CYC: 1495 case INTEL_PT_CYC:
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
index 56cc47baca11..02c38fec1c37 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -36,6 +36,7 @@ enum intel_pt_period_type {
36 INTEL_PT_PERIOD_NONE, 36 INTEL_PT_PERIOD_NONE,
37 INTEL_PT_PERIOD_INSTRUCTIONS, 37 INTEL_PT_PERIOD_INSTRUCTIONS,
38 INTEL_PT_PERIOD_TICKS, 38 INTEL_PT_PERIOD_TICKS,
39 INTEL_PT_PERIOD_MTC,
39}; 40};
40 41
41enum { 42enum {