# SPDX-License-Identifier: GPL-2.0
# intel-pt-events.py: Print Intel PT Events including Power Events and PTWRITE
# Copyright (c) 2017-2021, Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.

from __future__ import print_function

import os
import sys
import struct
import argparse

from libxed import LibXED
from ctypes import create_string_buffer, addressof

sys.path.append(os.environ['PERF_EXEC_PATH'] + \
	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')

from perf_trace_context import perf_set_itrace_options, \
	perf_sample_insn, perf_sample_srccode

try:
	broken_pipe_exception = BrokenPipeError
except:
	broken_pipe_exception = IOError

glb_switch_str		= {}
glb_insn		= False
glb_disassembler	= None
glb_src			= False
glb_source_file_name	= None
glb_line_number		= None
glb_dso			= None

def get_optional_null(perf_dict, field):
	if field in perf_dict:
		return perf_dict[field]
	return ""

def get_optional_zero(perf_dict, field):
	if field in perf_dict:
		return perf_dict[field]
	return 0

def get_optional_bytes(perf_dict, field):
	if field in perf_dict:
		return perf_dict[field]
	return bytes()

def get_optional(perf_dict, field):
	if field in perf_dict:
		return perf_dict[field]
	return "[unknown]"

def get_offset(perf_dict, field):
	if field in perf_dict:
		return "+%#x" % perf_dict[field]
	return ""

def trace_begin():
	ap = argparse.ArgumentParser(usage = "", add_help = False)
	ap.add_argument("--insn-trace", action='store_true')
	ap.add_argument("--src-trace", action='store_true')
	ap.add_argument("--all-switch-events", action='store_true')
	global glb_args
	global glb_insn
	global glb_src
	glb_args = ap.parse_args()
	if glb_args.insn_trace:
		print("Intel PT Instruction Trace")
		itrace = "i0nsepwx"
		glb_insn = True
	elif glb_args.src_trace:
		print("Intel PT Source Trace")
		itrace = "i0nsepwx"
		glb_insn = True
		glb_src = True
	else:
		print("Intel PT Branch Trace, Power Events and PTWRITE")
		itrace = "bepwx"
	global glb_disassembler
	try:
		glb_disassembler = LibXED()
	except:
		glb_disassembler = None
	perf_set_itrace_options(perf_script_context, itrace)

def trace_end():
	print("End")

def trace_unhandled(event_name, context, event_fields_dict):
		print(' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]))

def print_ptwrite(raw_buf):
	data = struct.unpack_from("<IQ", raw_buf)
	flags = data[0]
	payload = data[1]
	exact_ip = flags & 1
	print("IP: %u payload: %#x" % (exact_ip, payload), end=' ')

def print_cbr(raw_buf):
	data = struct.unpack_from("<BBBBII", raw_buf)
	cbr = data[0]
	f = (data[4] + 500) / 1000
	p = ((cbr * 1000 / data[2]) + 5) / 10
	print("%3u  freq: %4u MHz  (%3u%%)" % (cbr, f, p), end=' ')

def print_mwait(raw_buf):
	data = struct.unpack_from("<IQ", raw_buf)
	payload = data[1]
	hints = payload & 0xff
	extensions = (payload >> 32) & 0x3
	print("hints: %#x extensions: %#x" % (hints, extensions), end=' ')

def print_pwre(raw_buf):
	data = struct.unpack_from("<IQ", raw_buf)
	payload = data[1]
	hw = (payload >> 7) & 1
	cstate = (payload >> 12) & 0xf
	subcstate = (payload >> 8) & 0xf
	print("hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate),
		end=' ')

def print_exstop(raw_buf):
	data = struct.unpack_from("<I", raw_buf)
	flags = data[0]
	exact_ip = flags & 1
	print("IP: %u" % (exact_ip), end=' ')

def print_pwrx(raw_buf):
	data = struct.unpack_from("<IQ", raw_buf)
	payload = data[1]
	deepest_cstate = payload & 0xf
	last_cstate = (payload >> 4) & 0xf
	wake_reason = (payload >> 8) & 0xf
	print("deepest cstate: %u last cstate: %u wake reason: %#x" %
		(deepest_cstate, last_cstate, wake_reason), end=' ')

def print_psb(raw_buf):
	data = struct.unpack_from("<IQ", raw_buf)
	offset = data[1]
	print("offset: %#x" % (offset), end=' ')

def common_start_str(comm, sample):
	ts = sample["time"]
	cpu = sample["cpu"]
	pid = sample["pid"]
	tid = sample["tid"]
	return "%16s %5u/%-5u [%03u] %9u.%09u  " % (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000)

def print_common_start(comm, sample, name):
	flags_disp = get_optional_null(sample, "flags_disp")
	# Unused fields:
	# period      = sample["period"]
	# phys_addr   = sample["phys_addr"]
	# weight      = sample["weight"]
	# transaction = sample["transaction"]
	# cpumode     = get_optional_zero(sample, "cpumode")
	print(common_start_str(comm, sample) + "%7s  %19s" % (name, flags_disp), end=' ')

def print_instructions_start(comm, sample):
	if "x" in get_optional_null(sample, "flags"):
		print(common_start_str(comm, sample) + "x", end=' ')
	else:
		print(common_start_str(comm, sample), end='  ')

def disassem(insn, ip):
	inst = glb_disassembler.Instruction()
	glb_disassembler.SetMode(inst, 0) # Assume 64-bit
	buf = create_string_buffer(64)
	buf.value = insn
	return glb_disassembler.DisassembleOne(inst, addressof(buf), len(insn), ip)

def print_common_ip(param_dict, sample, symbol, dso):
	ip   = sample["ip"]
	offs = get_offset(param_dict, "symoff")
	if "cyc_cnt" in sample:
		cyc_cnt = sample["cyc_cnt"]
		insn_cnt = get_optional_zero(sample, "insn_cnt")
		ipc_str = "  IPC: %#.2f (%u/%u)" % (insn_cnt / cyc_cnt, insn_cnt, cyc_cnt)
	else:
		ipc_str = ""
	if glb_insn and glb_disassembler is not None:
		insn = perf_sample_insn(perf_script_context)
		if insn and len(insn):
			cnt, text = disassem(insn, ip)
			byte_str = ("%x" % ip).rjust(16)
			if sys.version_info.major >= 3:
				for k in range(cnt):
					byte_str += " %02x" % insn[k]
			else:
				for k in xrange(cnt):
					byte_str += " %02x" % ord(insn[k])
			print("%-40s  %-30s" % (byte_str, text), end=' ')
		print("%s%s (%s)" % (symbol, offs, dso), end=' ')
	else:
		print("%16x %s%s (%s)" % (ip, symbol, offs, dso), end=' ')
	if "addr_correlates_sym" in sample:
		addr   = sample["addr"]
		dso    = get_optional(sample, "addr_dso")
		symbol = get_optional(sample, "addr_symbol")
		offs   = get_offset(sample, "addr_symoff")
		print("=> %x %s%s (%s)%s" % (addr, symbol, offs, dso, ipc_str))
	else:
		print(ipc_str)

def print_srccode(comm, param_dict, sample, symbol, dso, with_insn):
	ip = sample["ip"]
	if symbol == "[unknown]":
		start_str = common_start_str(comm, sample) + ("%x" % ip).rjust(16).ljust(40)
	else:
		offs = get_offset(param_dict, "symoff")
		start_str = common_start_str(comm, sample) + (symbol + offs).ljust(40)

	if with_insn and glb_insn and glb_disassembler is not None:
		insn = perf_sample_insn(perf_script_context)
		if insn and len(insn):
			cnt, text = disassem(insn, ip)
		start_str += text.ljust(30)

	global glb_source_file_name
	global glb_line_number
	global glb_dso

	source_file_name, line_number, source_line = perf_sample_srccode(perf_script_context)
	if source_file_name:
		if glb_line_number == line_number and glb_source_file_name == source_file_name:
			src_str = ""
		else:
			if len(source_file_name) > 40:
				src_file = ("..." + source_file_name[-37:]) + " "
			else:
				src_file = source_file_name.ljust(41)
			if source_line is None:
				src_str = src_file + str(line_number).rjust(4) + " <source not found>"
			else:
				src_str = src_file + str(line_number).rjust(4) + " " + source_line
		glb_dso = None
	elif dso == glb_dso:
		src_str = ""
	else:
		src_str = dso
		glb_dso = dso

	glb_line_number = line_number
	glb_source_file_name = source_file_name

	print(start_str, src_str)

def do_process_event(param_dict):
	event_attr = param_dict["attr"]
	sample	   = param_dict["sample"]
	raw_buf	   = param_dict["raw_buf"]
	comm	   = param_dict["comm"]
	name	   = param_dict["ev_name"]
	# Unused fields:
	# callchain  = param_dict["callchain"]
	# brstack    = param_dict["brstack"]
	# brstacksym = param_dict["brstacksym"]

	# Symbol and dso info are not always resolved
	dso    = get_optional(param_dict, "dso")
	symbol = get_optional(param_dict, "symbol")

	cpu = sample["cpu"]
	if cpu in glb_switch_str:
		print(glb_switch_str[cpu])
		del glb_switch_str[cpu]

	if name[0:12] == "instructions":
		if glb_src:
			print_srccode(comm, param_dict, sample, symbol, dso, True)
		else:
			print_instructions_start(comm, sample)
			print_common_ip(param_dict, sample, symbol, dso)
	elif name[0:8] == "branches":
		if glb_src:
			print_srccode(comm, param_dict, sample, symbol, dso, False)
		else:
			print_common_start(comm, sample, name)
			print_common_ip(param_dict, sample, symbol, dso)
	elif name == "ptwrite":
		print_common_start(comm, sample, name)
		print_ptwrite(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "cbr":
		print_common_start(comm, sample, name)
		print_cbr(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "mwait":
		print_common_start(comm, sample, name)
		print_mwait(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "pwre":
		print_common_start(comm, sample, name)
		print_pwre(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "exstop":
		print_common_start(comm, sample, name)
		print_exstop(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "pwrx":
		print_common_start(comm, sample, name)
		print_pwrx(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	elif name == "psb":
		print_common_start(comm, sample, name)
		print_psb(raw_buf)
		print_common_ip(param_dict, sample, symbol, dso)
	else:
		print_common_start(comm, sample, name)
		print_common_ip(param_dict, sample, symbol, dso)

def process_event(param_dict):
	try:
		do_process_event(param_dict)
	except broken_pipe_exception:
		# Stop python printing broken pipe errors and traceback
		sys.stdout = open(os.devnull, 'w')
		sys.exit(1)

def auxtrace_error(typ, code, cpu, pid, tid, ip, ts, msg, cpumode, *x):
	try:
		print("%16s %5u/%-5u [%03u] %9u.%09u  error type %u code %u: %s ip 0x%16x" %
			("Trace error", pid, tid, cpu, ts / 1000000000, ts %1000000000, typ, code, msg, ip))
	except broken_pipe_exception:
		# Stop python printing broken pipe errors and traceback
		sys.stdout = open(os.devnull, 'w')
		sys.exit(1)

def context_switch(ts, cpu, pid, tid, np_pid, np_tid, machine_pid, out, out_preempt, *x):
	if out:
		out_str = "Switch out "
	else:
		out_str = "Switch In  "
	if out_preempt:
		preempt_str = "preempt"
	else:
		preempt_str = ""
	if machine_pid == -1:
		machine_str = ""
	else:
		machine_str = "machine PID %d" % machine_pid
	switch_str = "%16s %5d/%-5d [%03u] %9u.%09u %5d/%-5d %s %s" % \
		(out_str, pid, tid, cpu, ts / 1000000000, ts %1000000000, np_pid, np_tid, machine_str, preempt_str)
	if glb_args.all_switch_events:
		print(switch_str);
	else:
		global glb_switch_str
		glb_switch_str[cpu] = switch_str
