xref: /openbmc/linux/tools/perf/scripts/python/mem-phys-addr.py (revision 41013f0c095980775e0746272873891ca7c28fb1)
1*41013f0cSKan Liang# mem-phys-addr.py: Resolve physical address samples
2*41013f0cSKan Liang# SPDX-License-Identifier: GPL-2.0
3*41013f0cSKan Liang#
4*41013f0cSKan Liang# Copyright (c) 2018, Intel Corporation.
5*41013f0cSKan Liang
6*41013f0cSKan Liangfrom __future__ import division
7*41013f0cSKan Liangimport os
8*41013f0cSKan Liangimport sys
9*41013f0cSKan Liangimport struct
10*41013f0cSKan Liangimport re
11*41013f0cSKan Liangimport bisect
12*41013f0cSKan Liangimport collections
13*41013f0cSKan Liang
14*41013f0cSKan Liangsys.path.append(os.environ['PERF_EXEC_PATH'] + \
15*41013f0cSKan Liang	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
16*41013f0cSKan Liang
17*41013f0cSKan Liang#physical address ranges for System RAM
18*41013f0cSKan Liangsystem_ram = []
19*41013f0cSKan Liang#physical address ranges for Persistent Memory
20*41013f0cSKan Liangpmem = []
21*41013f0cSKan Liang#file object for proc iomem
22*41013f0cSKan Liangf = None
23*41013f0cSKan Liang#Count for each type of memory
24*41013f0cSKan Liangload_mem_type_cnt = collections.Counter()
25*41013f0cSKan Liang#perf event name
26*41013f0cSKan Liangevent_name = None
27*41013f0cSKan Liang
28*41013f0cSKan Liangdef parse_iomem():
29*41013f0cSKan Liang	global f
30*41013f0cSKan Liang	f = open('/proc/iomem', 'r')
31*41013f0cSKan Liang	for i, j in enumerate(f):
32*41013f0cSKan Liang		m = re.split('-|:',j,2)
33*41013f0cSKan Liang		if m[2].strip() == 'System RAM':
34*41013f0cSKan Liang			system_ram.append(long(m[0], 16))
35*41013f0cSKan Liang			system_ram.append(long(m[1], 16))
36*41013f0cSKan Liang		if m[2].strip() == 'Persistent Memory':
37*41013f0cSKan Liang			pmem.append(long(m[0], 16))
38*41013f0cSKan Liang			pmem.append(long(m[1], 16))
39*41013f0cSKan Liang
40*41013f0cSKan Liangdef print_memory_type():
41*41013f0cSKan Liang	print "Event: %s" % (event_name)
42*41013f0cSKan Liang	print "%-40s  %10s  %10s\n" % ("Memory type", "count", "percentage"),
43*41013f0cSKan Liang	print "%-40s  %10s  %10s\n" % ("----------------------------------------", \
44*41013f0cSKan Liang					"-----------", "-----------"),
45*41013f0cSKan Liang	total = sum(load_mem_type_cnt.values())
46*41013f0cSKan Liang	for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
47*41013f0cSKan Liang					key = lambda(k, v): (v, k), reverse = True):
48*41013f0cSKan Liang		print "%-40s  %10d  %10.1f%%\n" % (mem_type, count, 100 * count / total),
49*41013f0cSKan Liang
50*41013f0cSKan Liangdef trace_begin():
51*41013f0cSKan Liang	parse_iomem()
52*41013f0cSKan Liang
53*41013f0cSKan Liangdef trace_end():
54*41013f0cSKan Liang	print_memory_type()
55*41013f0cSKan Liang	f.close()
56*41013f0cSKan Liang
57*41013f0cSKan Liangdef is_system_ram(phys_addr):
58*41013f0cSKan Liang	#/proc/iomem is sorted
59*41013f0cSKan Liang	position = bisect.bisect(system_ram, phys_addr)
60*41013f0cSKan Liang	if position % 2 == 0:
61*41013f0cSKan Liang		return False
62*41013f0cSKan Liang	return True
63*41013f0cSKan Liang
64*41013f0cSKan Liangdef is_persistent_mem(phys_addr):
65*41013f0cSKan Liang	position = bisect.bisect(pmem, phys_addr)
66*41013f0cSKan Liang	if position % 2 == 0:
67*41013f0cSKan Liang		return False
68*41013f0cSKan Liang	return True
69*41013f0cSKan Liang
70*41013f0cSKan Liangdef find_memory_type(phys_addr):
71*41013f0cSKan Liang	if phys_addr == 0:
72*41013f0cSKan Liang		return "N/A"
73*41013f0cSKan Liang	if is_system_ram(phys_addr):
74*41013f0cSKan Liang		return "System RAM"
75*41013f0cSKan Liang
76*41013f0cSKan Liang	if is_persistent_mem(phys_addr):
77*41013f0cSKan Liang		return "Persistent Memory"
78*41013f0cSKan Liang
79*41013f0cSKan Liang	#slow path, search all
80*41013f0cSKan Liang	f.seek(0, 0)
81*41013f0cSKan Liang	for j in f:
82*41013f0cSKan Liang		m = re.split('-|:',j,2)
83*41013f0cSKan Liang		if long(m[0], 16) <= phys_addr <= long(m[1], 16):
84*41013f0cSKan Liang			return m[2]
85*41013f0cSKan Liang	return "N/A"
86*41013f0cSKan Liang
87*41013f0cSKan Liangdef process_event(param_dict):
88*41013f0cSKan Liang	name       = param_dict["ev_name"]
89*41013f0cSKan Liang	sample     = param_dict["sample"]
90*41013f0cSKan Liang	phys_addr  = sample["phys_addr"]
91*41013f0cSKan Liang
92*41013f0cSKan Liang	global event_name
93*41013f0cSKan Liang	if event_name == None:
94*41013f0cSKan Liang		event_name = name
95*41013f0cSKan Liang	load_mem_type_cnt[find_memory_type(phys_addr)] += 1
96