1a92bf335SAdrian Hunter# SPDX-License-Identifier: GPL-2.0
2a92bf335SAdrian Hunter# intel-pt-events.py: Print Intel PT Events including Power Events and PTWRITE
3a92bf335SAdrian Hunter# Copyright (c) 2017-2021, Intel Corporation.
4cc892720SAdrian Hunter#
5cc892720SAdrian Hunter# This program is free software; you can redistribute it and/or modify it
6cc892720SAdrian Hunter# under the terms and conditions of the GNU General Public License,
7cc892720SAdrian Hunter# version 2, as published by the Free Software Foundation.
8cc892720SAdrian Hunter#
9cc892720SAdrian Hunter# This program is distributed in the hope it will be useful, but WITHOUT
10cc892720SAdrian Hunter# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11cc892720SAdrian Hunter# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12cc892720SAdrian Hunter# more details.
13cc892720SAdrian Hunter
141f64cfdeSRoman Lozkofrom __future__ import division, print_function
15fdf2460cSTony Jones
16ad7ad6b5SAdrian Hunterimport io
17cc892720SAdrian Hunterimport os
18cc892720SAdrian Hunterimport sys
19cc892720SAdrian Hunterimport struct
20a483e64cSAdrian Hunterimport argparse
21ad7ad6b5SAdrian Hunterimport contextlib
22a483e64cSAdrian Hunter
23a483e64cSAdrian Hunterfrom libxed import LibXED
24a483e64cSAdrian Hunterfrom ctypes import create_string_buffer, addressof
25cc892720SAdrian Hunter
26cc892720SAdrian Huntersys.path.append(os.environ['PERF_EXEC_PATH'] + \
27cc892720SAdrian Hunter	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
28cc892720SAdrian Hunter
29a483e64cSAdrian Hunterfrom perf_trace_context import perf_set_itrace_options, \
30a483e64cSAdrian Hunter	perf_sample_insn, perf_sample_srccode
31cc892720SAdrian Hunter
32a92bf335SAdrian Huntertry:
33a92bf335SAdrian Hunter	broken_pipe_exception = BrokenPipeError
34a92bf335SAdrian Hunterexcept:
35a92bf335SAdrian Hunter	broken_pipe_exception = IOError
36a92bf335SAdrian Hunter
370f80bfbfSAdrian Hunterglb_switch_str		= {}
38a483e64cSAdrian Hunterglb_insn		= False
39a483e64cSAdrian Hunterglb_disassembler	= None
40a483e64cSAdrian Hunterglb_src			= False
41a483e64cSAdrian Hunterglb_source_file_name	= None
42a483e64cSAdrian Hunterglb_line_number		= None
43a483e64cSAdrian Hunterglb_dso			= None
44ad7ad6b5SAdrian Hunterglb_stash_dict		= {}
45ad7ad6b5SAdrian Hunterglb_output		= None
46ad7ad6b5SAdrian Hunterglb_output_pos		= 0
47ad7ad6b5SAdrian Hunterglb_cpu			= -1
48ad7ad6b5SAdrian Hunterglb_time		= 0
49a92bf335SAdrian Hunter
50a92bf335SAdrian Hunterdef get_optional_null(perf_dict, field):
51a92bf335SAdrian Hunter	if field in perf_dict:
52a92bf335SAdrian Hunter		return perf_dict[field]
53a92bf335SAdrian Hunter	return ""
54a92bf335SAdrian Hunter
55a92bf335SAdrian Hunterdef get_optional_zero(perf_dict, field):
56a92bf335SAdrian Hunter	if field in perf_dict:
57a92bf335SAdrian Hunter		return perf_dict[field]
58a92bf335SAdrian Hunter	return 0
59a92bf335SAdrian Hunter
60a483e64cSAdrian Hunterdef get_optional_bytes(perf_dict, field):
61a483e64cSAdrian Hunter	if field in perf_dict:
62a483e64cSAdrian Hunter		return perf_dict[field]
63a483e64cSAdrian Hunter	return bytes()
64a483e64cSAdrian Hunter
65a92bf335SAdrian Hunterdef get_optional(perf_dict, field):
66a92bf335SAdrian Hunter	if field in perf_dict:
67a92bf335SAdrian Hunter		return perf_dict[field]
68a92bf335SAdrian Hunter	return "[unknown]"
69a92bf335SAdrian Hunter
70a92bf335SAdrian Hunterdef get_offset(perf_dict, field):
71a92bf335SAdrian Hunter	if field in perf_dict:
72a92bf335SAdrian Hunter		return "+%#x" % perf_dict[field]
73a92bf335SAdrian Hunter	return ""
74a92bf335SAdrian Hunter
75cc892720SAdrian Hunterdef trace_begin():
76a483e64cSAdrian Hunter	ap = argparse.ArgumentParser(usage = "", add_help = False)
77a483e64cSAdrian Hunter	ap.add_argument("--insn-trace", action='store_true')
78a483e64cSAdrian Hunter	ap.add_argument("--src-trace", action='store_true')
790f80bfbfSAdrian Hunter	ap.add_argument("--all-switch-events", action='store_true')
80ad7ad6b5SAdrian Hunter	ap.add_argument("--interleave", type=int, nargs='?', const=4, default=0)
81a483e64cSAdrian Hunter	global glb_args
82a483e64cSAdrian Hunter	global glb_insn
83a483e64cSAdrian Hunter	global glb_src
84a483e64cSAdrian Hunter	glb_args = ap.parse_args()
85a483e64cSAdrian Hunter	if glb_args.insn_trace:
86a483e64cSAdrian Hunter		print("Intel PT Instruction Trace")
8795f9bfcfSAdrian Hunter		itrace = "i0nsepwxI"
88a483e64cSAdrian Hunter		glb_insn = True
89a483e64cSAdrian Hunter	elif glb_args.src_trace:
90a483e64cSAdrian Hunter		print("Intel PT Source Trace")
9195f9bfcfSAdrian Hunter		itrace = "i0nsepwxI"
92a483e64cSAdrian Hunter		glb_insn = True
93a483e64cSAdrian Hunter		glb_src = True
94a483e64cSAdrian Hunter	else:
9595f9bfcfSAdrian Hunter		print("Intel PT Branch Trace, Power Events, Event Trace and PTWRITE")
9695f9bfcfSAdrian Hunter		itrace = "bepwxI"
97a483e64cSAdrian Hunter	global glb_disassembler
98a483e64cSAdrian Hunter	try:
99a483e64cSAdrian Hunter		glb_disassembler = LibXED()
100a483e64cSAdrian Hunter	except:
101a483e64cSAdrian Hunter		glb_disassembler = None
102a483e64cSAdrian Hunter	perf_set_itrace_options(perf_script_context, itrace)
103cc892720SAdrian Hunter
104cc892720SAdrian Hunterdef trace_end():
105ad7ad6b5SAdrian Hunter	if glb_args.interleave:
106ad7ad6b5SAdrian Hunter		flush_stashed_output()
107fdf2460cSTony Jones	print("End")
108cc892720SAdrian Hunter
109cc892720SAdrian Hunterdef trace_unhandled(event_name, context, event_fields_dict):
110fdf2460cSTony Jones		print(' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]))
111cc892720SAdrian Hunter
112ad7ad6b5SAdrian Hunterdef stash_output():
113ad7ad6b5SAdrian Hunter	global glb_stash_dict
114ad7ad6b5SAdrian Hunter	global glb_output_pos
115ad7ad6b5SAdrian Hunter	output_str = glb_output.getvalue()[glb_output_pos:]
116ad7ad6b5SAdrian Hunter	n = len(output_str)
117ad7ad6b5SAdrian Hunter	if n:
118ad7ad6b5SAdrian Hunter		glb_output_pos += n
119ad7ad6b5SAdrian Hunter		if glb_cpu not in glb_stash_dict:
120ad7ad6b5SAdrian Hunter			glb_stash_dict[glb_cpu] = []
121ad7ad6b5SAdrian Hunter		glb_stash_dict[glb_cpu].append(output_str)
122ad7ad6b5SAdrian Hunter
123ad7ad6b5SAdrian Hunterdef flush_stashed_output():
124ad7ad6b5SAdrian Hunter	global glb_stash_dict
125ad7ad6b5SAdrian Hunter	while glb_stash_dict:
126ad7ad6b5SAdrian Hunter		cpus = list(glb_stash_dict.keys())
127ad7ad6b5SAdrian Hunter		# Output at most glb_args.interleave output strings per cpu
128ad7ad6b5SAdrian Hunter		for cpu in cpus:
129ad7ad6b5SAdrian Hunter			items = glb_stash_dict[cpu]
130ad7ad6b5SAdrian Hunter			countdown = glb_args.interleave
131ad7ad6b5SAdrian Hunter			while len(items) and countdown:
132ad7ad6b5SAdrian Hunter				sys.stdout.write(items[0])
133ad7ad6b5SAdrian Hunter				del items[0]
134ad7ad6b5SAdrian Hunter				countdown -= 1
135ad7ad6b5SAdrian Hunter			if not items:
136ad7ad6b5SAdrian Hunter				del glb_stash_dict[cpu]
137ad7ad6b5SAdrian Hunter
138cc892720SAdrian Hunterdef print_ptwrite(raw_buf):
139cc892720SAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
140cc892720SAdrian Hunter	flags = data[0]
141cc892720SAdrian Hunter	payload = data[1]
142cc892720SAdrian Hunter	exact_ip = flags & 1
14375659c6fSAdrian Hunter	try:
14475659c6fSAdrian Hunter		s = payload.to_bytes(8, "little").decode("ascii").rstrip("\x00")
14575659c6fSAdrian Hunter		if not s.isprintable():
14675659c6fSAdrian Hunter			s = ""
14775659c6fSAdrian Hunter	except:
14875659c6fSAdrian Hunter		s = ""
14975659c6fSAdrian Hunter	print("IP: %u payload: %#x" % (exact_ip, payload), s, end=' ')
150cc892720SAdrian Hunter
151cc892720SAdrian Hunterdef print_cbr(raw_buf):
152cc892720SAdrian Hunter	data = struct.unpack_from("<BBBBII", raw_buf)
153cc892720SAdrian Hunter	cbr = data[0]
154cc892720SAdrian Hunter	f = (data[4] + 500) / 1000
155cc892720SAdrian Hunter	p = ((cbr * 1000 / data[2]) + 5) / 10
156fdf2460cSTony Jones	print("%3u  freq: %4u MHz  (%3u%%)" % (cbr, f, p), end=' ')
157cc892720SAdrian Hunter
158cc892720SAdrian Hunterdef print_mwait(raw_buf):
159cc892720SAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
160cc892720SAdrian Hunter	payload = data[1]
161cc892720SAdrian Hunter	hints = payload & 0xff
162cc892720SAdrian Hunter	extensions = (payload >> 32) & 0x3
163fdf2460cSTony Jones	print("hints: %#x extensions: %#x" % (hints, extensions), end=' ')
164cc892720SAdrian Hunter
165cc892720SAdrian Hunterdef print_pwre(raw_buf):
166cc892720SAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
167cc892720SAdrian Hunter	payload = data[1]
168cc892720SAdrian Hunter	hw = (payload >> 7) & 1
169cc892720SAdrian Hunter	cstate = (payload >> 12) & 0xf
170cc892720SAdrian Hunter	subcstate = (payload >> 8) & 0xf
171fdf2460cSTony Jones	print("hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate),
172fdf2460cSTony Jones		end=' ')
173cc892720SAdrian Hunter
174cc892720SAdrian Hunterdef print_exstop(raw_buf):
175cc892720SAdrian Hunter	data = struct.unpack_from("<I", raw_buf)
176cc892720SAdrian Hunter	flags = data[0]
177cc892720SAdrian Hunter	exact_ip = flags & 1
178fdf2460cSTony Jones	print("IP: %u" % (exact_ip), end=' ')
179cc892720SAdrian Hunter
180cc892720SAdrian Hunterdef print_pwrx(raw_buf):
181cc892720SAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
182cc892720SAdrian Hunter	payload = data[1]
183cc892720SAdrian Hunter	deepest_cstate = payload & 0xf
184cc892720SAdrian Hunter	last_cstate = (payload >> 4) & 0xf
185cc892720SAdrian Hunter	wake_reason = (payload >> 8) & 0xf
186fdf2460cSTony Jones	print("deepest cstate: %u last cstate: %u wake reason: %#x" %
187fdf2460cSTony Jones		(deepest_cstate, last_cstate, wake_reason), end=' ')
188cc892720SAdrian Hunter
189a92bf335SAdrian Hunterdef print_psb(raw_buf):
190a92bf335SAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
191a92bf335SAdrian Hunter	offset = data[1]
192a92bf335SAdrian Hunter	print("offset: %#x" % (offset), end=' ')
193a92bf335SAdrian Hunter
19495f9bfcfSAdrian Hunterglb_cfe = ["", "INTR", "IRET", "SMI", "RSM", "SIPI", "INIT", "VMENTRY", "VMEXIT",
19595f9bfcfSAdrian Hunter		"VMEXIT_INTR", "SHUTDOWN", "", "UINT", "UIRET"] + [""] * 18
19695f9bfcfSAdrian Hunterglb_evd = ["", "PFA", "VMXQ", "VMXR"] + [""] * 60
19795f9bfcfSAdrian Hunter
19895f9bfcfSAdrian Hunterdef print_evt(raw_buf):
19995f9bfcfSAdrian Hunter	data = struct.unpack_from("<BBH", raw_buf)
20095f9bfcfSAdrian Hunter	typ = data[0] & 0x1f
20195f9bfcfSAdrian Hunter	ip_flag = (data[0] & 0x80) >> 7
20295f9bfcfSAdrian Hunter	vector = data[1]
20395f9bfcfSAdrian Hunter	evd_cnt = data[2]
20495f9bfcfSAdrian Hunter	s = glb_cfe[typ]
20595f9bfcfSAdrian Hunter	if s:
20695f9bfcfSAdrian Hunter		print(" cfe: %s IP: %u vector: %u" % (s, ip_flag, vector), end=' ')
20795f9bfcfSAdrian Hunter	else:
20895f9bfcfSAdrian Hunter		print(" cfe: %u IP: %u vector: %u" % (typ, ip_flag, vector), end=' ')
20995f9bfcfSAdrian Hunter	pos = 4
21095f9bfcfSAdrian Hunter	for i in range(evd_cnt):
21195f9bfcfSAdrian Hunter		data = struct.unpack_from("<QQ", raw_buf)
21295f9bfcfSAdrian Hunter		et = data[0] & 0x3f
21395f9bfcfSAdrian Hunter		s = glb_evd[et]
21495f9bfcfSAdrian Hunter		if s:
21595f9bfcfSAdrian Hunter			print("%s: %#x" % (s, data[1]), end=' ')
21695f9bfcfSAdrian Hunter		else:
21795f9bfcfSAdrian Hunter			print("EVD_%u: %#x" % (et, data[1]), end=' ')
21895f9bfcfSAdrian Hunter
21995f9bfcfSAdrian Hunterdef print_iflag(raw_buf):
22095f9bfcfSAdrian Hunter	data = struct.unpack_from("<IQ", raw_buf)
22195f9bfcfSAdrian Hunter	iflag = data[0] & 1
22295f9bfcfSAdrian Hunter	old_iflag = iflag ^ 1
22395f9bfcfSAdrian Hunter	via_branch = data[0] & 2
22495f9bfcfSAdrian Hunter	branch_ip = data[1]
22595f9bfcfSAdrian Hunter	if via_branch:
22695f9bfcfSAdrian Hunter		s = "via"
22795f9bfcfSAdrian Hunter	else:
22895f9bfcfSAdrian Hunter		s = "non"
22995f9bfcfSAdrian Hunter	print("IFLAG: %u->%u %s branch" % (old_iflag, iflag, s), end=' ')
23095f9bfcfSAdrian Hunter
231a483e64cSAdrian Hunterdef common_start_str(comm, sample):
232cc892720SAdrian Hunter	ts = sample["time"]
233cc892720SAdrian Hunter	cpu = sample["cpu"]
234cc892720SAdrian Hunter	pid = sample["pid"]
235cc892720SAdrian Hunter	tid = sample["tid"]
23613a133b2SAdrian Hunter	if "machine_pid" in sample:
23713a133b2SAdrian Hunter		machine_pid = sample["machine_pid"]
23813a133b2SAdrian Hunter		vcpu = sample["vcpu"]
23913a133b2SAdrian Hunter		return "VM:%5d VCPU:%03d %16s %5u/%-5u [%03u] %9u.%09u  " % (machine_pid, vcpu, comm, pid, tid, cpu, ts / 1000000000, ts %1000000000)
24013a133b2SAdrian Hunter	else:
241a483e64cSAdrian Hunter		return "%16s %5u/%-5u [%03u] %9u.%09u  " % (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000)
242a483e64cSAdrian Hunter
243a483e64cSAdrian Hunterdef print_common_start(comm, sample, name):
244a92bf335SAdrian Hunter	flags_disp = get_optional_null(sample, "flags_disp")
245a92bf335SAdrian Hunter	# Unused fields:
246a92bf335SAdrian Hunter	# period      = sample["period"]
247a92bf335SAdrian Hunter	# phys_addr   = sample["phys_addr"]
248a92bf335SAdrian Hunter	# weight      = sample["weight"]
249a92bf335SAdrian Hunter	# transaction = sample["transaction"]
250a92bf335SAdrian Hunter	# cpumode     = get_optional_zero(sample, "cpumode")
25195f9bfcfSAdrian Hunter	print(common_start_str(comm, sample) + "%8s  %21s" % (name, flags_disp), end=' ')
252a483e64cSAdrian Hunter
253a483e64cSAdrian Hunterdef print_instructions_start(comm, sample):
254a483e64cSAdrian Hunter	if "x" in get_optional_null(sample, "flags"):
255a483e64cSAdrian Hunter		print(common_start_str(comm, sample) + "x", end=' ')
256a483e64cSAdrian Hunter	else:
257a483e64cSAdrian Hunter		print(common_start_str(comm, sample), end='  ')
258a483e64cSAdrian Hunter
259a483e64cSAdrian Hunterdef disassem(insn, ip):
260a483e64cSAdrian Hunter	inst = glb_disassembler.Instruction()
261a483e64cSAdrian Hunter	glb_disassembler.SetMode(inst, 0) # Assume 64-bit
262a483e64cSAdrian Hunter	buf = create_string_buffer(64)
263a483e64cSAdrian Hunter	buf.value = insn
264a483e64cSAdrian Hunter	return glb_disassembler.DisassembleOne(inst, addressof(buf), len(insn), ip)
265cc892720SAdrian Hunter
266a92bf335SAdrian Hunterdef print_common_ip(param_dict, sample, symbol, dso):
267cc892720SAdrian Hunter	ip   = sample["ip"]
268a92bf335SAdrian Hunter	offs = get_offset(param_dict, "symoff")
269a483e64cSAdrian Hunter	if "cyc_cnt" in sample:
270a483e64cSAdrian Hunter		cyc_cnt = sample["cyc_cnt"]
271a483e64cSAdrian Hunter		insn_cnt = get_optional_zero(sample, "insn_cnt")
272a483e64cSAdrian Hunter		ipc_str = "  IPC: %#.2f (%u/%u)" % (insn_cnt / cyc_cnt, insn_cnt, cyc_cnt)
273a483e64cSAdrian Hunter	else:
274a483e64cSAdrian Hunter		ipc_str = ""
275a483e64cSAdrian Hunter	if glb_insn and glb_disassembler is not None:
276a483e64cSAdrian Hunter		insn = perf_sample_insn(perf_script_context)
277a483e64cSAdrian Hunter		if insn and len(insn):
278a483e64cSAdrian Hunter			cnt, text = disassem(insn, ip)
279a483e64cSAdrian Hunter			byte_str = ("%x" % ip).rjust(16)
280a483e64cSAdrian Hunter			if sys.version_info.major >= 3:
281a483e64cSAdrian Hunter				for k in range(cnt):
282a483e64cSAdrian Hunter					byte_str += " %02x" % insn[k]
283a483e64cSAdrian Hunter			else:
284a483e64cSAdrian Hunter				for k in xrange(cnt):
285a483e64cSAdrian Hunter					byte_str += " %02x" % ord(insn[k])
286a483e64cSAdrian Hunter			print("%-40s  %-30s" % (byte_str, text), end=' ')
287a483e64cSAdrian Hunter		print("%s%s (%s)" % (symbol, offs, dso), end=' ')
288a483e64cSAdrian Hunter	else:
289a92bf335SAdrian Hunter		print("%16x %s%s (%s)" % (ip, symbol, offs, dso), end=' ')
290a92bf335SAdrian Hunter	if "addr_correlates_sym" in sample:
291a92bf335SAdrian Hunter		addr   = sample["addr"]
292a92bf335SAdrian Hunter		dso    = get_optional(sample, "addr_dso")
293a92bf335SAdrian Hunter		symbol = get_optional(sample, "addr_symbol")
294a92bf335SAdrian Hunter		offs   = get_offset(sample, "addr_symoff")
295a483e64cSAdrian Hunter		print("=> %x %s%s (%s)%s" % (addr, symbol, offs, dso, ipc_str))
296a92bf335SAdrian Hunter	else:
297a483e64cSAdrian Hunter		print(ipc_str)
298a483e64cSAdrian Hunter
299a483e64cSAdrian Hunterdef print_srccode(comm, param_dict, sample, symbol, dso, with_insn):
300a483e64cSAdrian Hunter	ip = sample["ip"]
301a483e64cSAdrian Hunter	if symbol == "[unknown]":
302a483e64cSAdrian Hunter		start_str = common_start_str(comm, sample) + ("%x" % ip).rjust(16).ljust(40)
303a483e64cSAdrian Hunter	else:
304a483e64cSAdrian Hunter		offs = get_offset(param_dict, "symoff")
305a483e64cSAdrian Hunter		start_str = common_start_str(comm, sample) + (symbol + offs).ljust(40)
306a483e64cSAdrian Hunter
307a483e64cSAdrian Hunter	if with_insn and glb_insn and glb_disassembler is not None:
308a483e64cSAdrian Hunter		insn = perf_sample_insn(perf_script_context)
309a483e64cSAdrian Hunter		if insn and len(insn):
310a483e64cSAdrian Hunter			cnt, text = disassem(insn, ip)
311a483e64cSAdrian Hunter		start_str += text.ljust(30)
312a483e64cSAdrian Hunter
313a483e64cSAdrian Hunter	global glb_source_file_name
314a483e64cSAdrian Hunter	global glb_line_number
315a483e64cSAdrian Hunter	global glb_dso
316a483e64cSAdrian Hunter
317a483e64cSAdrian Hunter	source_file_name, line_number, source_line = perf_sample_srccode(perf_script_context)
318a483e64cSAdrian Hunter	if source_file_name:
319a483e64cSAdrian Hunter		if glb_line_number == line_number and glb_source_file_name == source_file_name:
320a483e64cSAdrian Hunter			src_str = ""
321a483e64cSAdrian Hunter		else:
322a483e64cSAdrian Hunter			if len(source_file_name) > 40:
323a483e64cSAdrian Hunter				src_file = ("..." + source_file_name[-37:]) + " "
324a483e64cSAdrian Hunter			else:
325a483e64cSAdrian Hunter				src_file = source_file_name.ljust(41)
326a483e64cSAdrian Hunter			if source_line is None:
327a483e64cSAdrian Hunter				src_str = src_file + str(line_number).rjust(4) + " <source not found>"
328a483e64cSAdrian Hunter			else:
329a483e64cSAdrian Hunter				src_str = src_file + str(line_number).rjust(4) + " " + source_line
330a483e64cSAdrian Hunter		glb_dso = None
331a483e64cSAdrian Hunter	elif dso == glb_dso:
332a483e64cSAdrian Hunter		src_str = ""
333a483e64cSAdrian Hunter	else:
334a483e64cSAdrian Hunter		src_str = dso
335a483e64cSAdrian Hunter		glb_dso = dso
336a483e64cSAdrian Hunter
337a483e64cSAdrian Hunter	glb_line_number = line_number
338a483e64cSAdrian Hunter	glb_source_file_name = source_file_name
339a483e64cSAdrian Hunter
340a483e64cSAdrian Hunter	print(start_str, src_str)
341cc892720SAdrian Hunter
342a92bf335SAdrian Hunterdef do_process_event(param_dict):
343cc892720SAdrian Hunter	sample	   = param_dict["sample"]
344cc892720SAdrian Hunter	raw_buf	   = param_dict["raw_buf"]
345cc892720SAdrian Hunter	comm	   = param_dict["comm"]
346cc892720SAdrian Hunter	name	   = param_dict["ev_name"]
347a92bf335SAdrian Hunter	# Unused fields:
348a92bf335SAdrian Hunter	# callchain  = param_dict["callchain"]
349a92bf335SAdrian Hunter	# brstack    = param_dict["brstack"]
350a92bf335SAdrian Hunter	# brstacksym = param_dict["brstacksym"]
351*984abd34SAlexander Pantyukhin	# event_attr = param_dict["attr"]
352cc892720SAdrian Hunter
353cc892720SAdrian Hunter	# Symbol and dso info are not always resolved
354a92bf335SAdrian Hunter	dso    = get_optional(param_dict, "dso")
355a92bf335SAdrian Hunter	symbol = get_optional(param_dict, "symbol")
356cc892720SAdrian Hunter
3570f80bfbfSAdrian Hunter	cpu = sample["cpu"]
3580f80bfbfSAdrian Hunter	if cpu in glb_switch_str:
3590f80bfbfSAdrian Hunter		print(glb_switch_str[cpu])
3600f80bfbfSAdrian Hunter		del glb_switch_str[cpu]
3610f80bfbfSAdrian Hunter
362*984abd34SAlexander Pantyukhin	if name.startswith("instructions"):
363a483e64cSAdrian Hunter		if glb_src:
364a483e64cSAdrian Hunter			print_srccode(comm, param_dict, sample, symbol, dso, True)
365a483e64cSAdrian Hunter		else:
366a483e64cSAdrian Hunter			print_instructions_start(comm, sample)
367a483e64cSAdrian Hunter			print_common_ip(param_dict, sample, symbol, dso)
368*984abd34SAlexander Pantyukhin	elif name.startswith("branches"):
369a483e64cSAdrian Hunter		if glb_src:
370a483e64cSAdrian Hunter			print_srccode(comm, param_dict, sample, symbol, dso, False)
371a483e64cSAdrian Hunter		else:
372a92bf335SAdrian Hunter			print_common_start(comm, sample, name)
373a483e64cSAdrian Hunter			print_common_ip(param_dict, sample, symbol, dso)
374a483e64cSAdrian Hunter	elif name == "ptwrite":
375a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
376cc892720SAdrian Hunter		print_ptwrite(raw_buf)
377a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
378cc892720SAdrian Hunter	elif name == "cbr":
379a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
380cc892720SAdrian Hunter		print_cbr(raw_buf)
381a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
382cc892720SAdrian Hunter	elif name == "mwait":
383a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
384cc892720SAdrian Hunter		print_mwait(raw_buf)
385a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
386cc892720SAdrian Hunter	elif name == "pwre":
387a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
388cc892720SAdrian Hunter		print_pwre(raw_buf)
389a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
390cc892720SAdrian Hunter	elif name == "exstop":
391a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
392cc892720SAdrian Hunter		print_exstop(raw_buf)
393a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
394cc892720SAdrian Hunter	elif name == "pwrx":
395a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
396cc892720SAdrian Hunter		print_pwrx(raw_buf)
397a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
398a92bf335SAdrian Hunter	elif name == "psb":
399a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
400a92bf335SAdrian Hunter		print_psb(raw_buf)
401a483e64cSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
40295f9bfcfSAdrian Hunter	elif name == "evt":
40395f9bfcfSAdrian Hunter		print_common_start(comm, sample, name)
40495f9bfcfSAdrian Hunter		print_evt(raw_buf)
40595f9bfcfSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
40695f9bfcfSAdrian Hunter	elif name == "iflag":
40795f9bfcfSAdrian Hunter		print_common_start(comm, sample, name)
40895f9bfcfSAdrian Hunter		print_iflag(raw_buf)
40995f9bfcfSAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
410a483e64cSAdrian Hunter	else:
411a483e64cSAdrian Hunter		print_common_start(comm, sample, name)
412a92bf335SAdrian Hunter		print_common_ip(param_dict, sample, symbol, dso)
413a92bf335SAdrian Hunter
414ad7ad6b5SAdrian Hunterdef interleave_events(param_dict):
415ad7ad6b5SAdrian Hunter	global glb_cpu
416ad7ad6b5SAdrian Hunter	global glb_time
417ad7ad6b5SAdrian Hunter	global glb_output
418ad7ad6b5SAdrian Hunter	global glb_output_pos
419ad7ad6b5SAdrian Hunter
420ad7ad6b5SAdrian Hunter	sample  = param_dict["sample"]
421ad7ad6b5SAdrian Hunter	glb_cpu = sample["cpu"]
422ad7ad6b5SAdrian Hunter	ts      = sample["time"]
423ad7ad6b5SAdrian Hunter
424ad7ad6b5SAdrian Hunter	if glb_time != ts:
425ad7ad6b5SAdrian Hunter		glb_time = ts
426ad7ad6b5SAdrian Hunter		flush_stashed_output()
427ad7ad6b5SAdrian Hunter
428ad7ad6b5SAdrian Hunter	glb_output_pos = 0
429ad7ad6b5SAdrian Hunter	with contextlib.redirect_stdout(io.StringIO()) as glb_output:
430ad7ad6b5SAdrian Hunter		do_process_event(param_dict)
431ad7ad6b5SAdrian Hunter
432ad7ad6b5SAdrian Hunter	stash_output()
433ad7ad6b5SAdrian Hunter
434a92bf335SAdrian Hunterdef process_event(param_dict):
435a92bf335SAdrian Hunter	try:
436ad7ad6b5SAdrian Hunter		if glb_args.interleave:
437ad7ad6b5SAdrian Hunter			interleave_events(param_dict)
438ad7ad6b5SAdrian Hunter		else:
439a92bf335SAdrian Hunter			do_process_event(param_dict)
440a92bf335SAdrian Hunter	except broken_pipe_exception:
441a92bf335SAdrian Hunter		# Stop python printing broken pipe errors and traceback
442a92bf335SAdrian Hunter		sys.stdout = open(os.devnull, 'w')
443a92bf335SAdrian Hunter		sys.exit(1)
444a92bf335SAdrian Hunter
445a92bf335SAdrian Hunterdef auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x):
446ad7ad6b5SAdrian Hunter	if glb_args.interleave:
447ad7ad6b5SAdrian Hunter		flush_stashed_output()
44813a133b2SAdrian Hunter	if len(x) >= 2 and x[0]:
44913a133b2SAdrian Hunter		machine_pid = x[0]
45013a133b2SAdrian Hunter		vcpu = x[1]
45113a133b2SAdrian Hunter	else:
45213a133b2SAdrian Hunter		machine_pid = 0
45313a133b2SAdrian Hunter		vcpu = -1
454a92bf335SAdrian Hunter	try:
45513a133b2SAdrian Hunter		if machine_pid:
45613a133b2SAdrian Hunter			print("VM:%5d VCPU:%03d %16s %5u/%-5u [%03u] %9u.%09u  error type %u code %u: %s ip 0x%16x" %
45713a133b2SAdrian Hunter				(machine_pid, vcpu, "Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip))
45813a133b2SAdrian Hunter		else:
459a92bf335SAdrian Hunter			print("%16s %5u/%-5u [%03u] %9u.%09u  error type %u code %u: %s ip 0x%16x" %
460a92bf335SAdrian Hunter				("Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip))
461a92bf335SAdrian Hunter	except broken_pipe_exception:
462a92bf335SAdrian Hunter		# Stop python printing broken pipe errors and traceback
463a92bf335SAdrian Hunter		sys.stdout = open(os.devnull, 'w')
464a92bf335SAdrian Hunter		sys.exit(1)
465a92bf335SAdrian Hunter
466a92bf335SAdrian Hunterdef context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x):
467ad7ad6b5SAdrian Hunter	if glb_args.interleave:
468ad7ad6b5SAdrian Hunter		flush_stashed_output()
469a92bf335SAdrian Hunter	if out:
470a92bf335SAdrian Hunter		out_str = "Switch out "
471a92bf335SAdrian Hunter	else:
472a92bf335SAdrian Hunter		out_str = "Switch In  "
473a92bf335SAdrian Hunter	if out_preempt:
474a92bf335SAdrian Hunter		preempt_str = "preempt"
475a92bf335SAdrian Hunter	else:
476a92bf335SAdrian Hunter		preempt_str = ""
47713a133b2SAdrian Hunter	if len(x) >= 2 and x[0]:
47813a133b2SAdrian Hunter		machine_pid = x[0]
47913a133b2SAdrian Hunter		vcpu = x[1]
48013a133b2SAdrian Hunter	else:
48113a133b2SAdrian Hunter		vcpu = None;
482a92bf335SAdrian Hunter	if machine_pid == -1:
483a92bf335SAdrian Hunter		machine_str = ""
48413a133b2SAdrian Hunter	elif vcpu is None:
485a92bf335SAdrian Hunter		machine_str = "machine PID %d" % machine_pid
48613a133b2SAdrian Hunter	else:
48713a133b2SAdrian Hunter		machine_str = "machine PID %d VCPU %d" % (machine_pid, vcpu)
4880f80bfbfSAdrian Hunter	switch_str = "%16s %5d/%-5d [%03u] %9u.%09u %5d/%-5d %s %s" % \
489a92bf335SAdrian Hunter		(out_str, pid, tid, cpu, ts / 1000000000, ts %1000000000, np_pid, np_tid, machine_str, preempt_str)
4900f80bfbfSAdrian Hunter	if glb_args.all_switch_events:
49113a133b2SAdrian Hunter		print(switch_str)
4920f80bfbfSAdrian Hunter	else:
4930f80bfbfSAdrian Hunter		global glb_switch_str
4940f80bfbfSAdrian Hunter		glb_switch_str[cpu] = switch_str
495