blob: 23b88862c6a033d5c11425cb65012d407fd5db7b [file] [log] [blame]
#!/usr/bin/python
#
# Copyright (c) 2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import sys,re,os
class monitorEvent():
def __init__(self, time, data1, data2, ptr):
self.time = time
self.data1 = data1
self.data2 = data2
self.ptr = ptr
class Params():
# Quark X1000
TICKS_PER_MSEC = 14318.1
def getData(monitorFile):
eventList = []
with open(monitorFile, 'rb') as f:
for chunk in iter(lambda: f.read(16), ''):
time = int(chunk[0:4][::-1].encode('hex'), 16)
data1 = int(chunk[4:8][::-1].encode('hex'), 16)
data2 = int(chunk[8:12][::-1].encode('hex'), 16)
ptr = int(chunk[12:16][::-1].encode('hex'), 16)
if ((time == 0) and (data1 == 0) and (data2 == 0)):
break
eventList.append(monitorEvent(time, data1, data2, ptr))
return eventList
def formatTime(val):
ticks_per_ms = Params.TICKS_PER_MSEC
val_ms = val / ticks_per_ms
return "{:15.3f}".format(val_ms)
def getTask(val):
global symbols
if val == 0:
return "Idle"
else:
return symbols[val].replace('_k_task_obj_', '')
def formatEvent(time, data1, data2, ptr):
global symbols
global prevTaskName
global prevTaskId
mo_stbit0 = 0x20000000
mo_stbit1 = 0x30000000
mo_event = 0x40000000
mo_lcomm = 0x50000000
evt_type = data2 & 0xF0000000
mask = 0xFFFFFFF
evt_mask = 0xFFFFFFC
if (evt_type == mo_stbit0):
event = [ "State clear", decodeStateBits(data2 & mask), getTask(data1) ]
elif (evt_type == mo_stbit1):
event = [ "State set", decodeStateBits(data2 & mask), getTask(data1) ]
elif (evt_type == mo_event):
event = [ "Server event",
symbols[data2 & evt_mask].replace('_k_event_obj_',''),
"" ]
elif (evt_type == mo_lcomm):
event = [ "Server cmd", symbols[ptr], getTask(data1) ]
elif (evt_type == 0):
event = [ "Task switch to", "", getTask(data1) ]
if (ftrace_format):
ret = ""
if (prevTaskId >= 0):
ret = " {:>16}-{:<8} [000] .... {:12}: sched_switch: prev_comm={}" \
" prev_pid={} prev_prio=0 prev_state=S ==> next_comm={}" \
" next_pid={} next_prio=0".format(prevTaskName,
prevTaskId,
formatTime(time),
prevTaskName,
prevTaskId,
getTask(data1),
data1)
prevTaskName = getTask(data1)
prevTaskId = data1
return ret
else:
event = [ "UNDEFINED",
"data1={:08x}".format(data1),
"data2={:08x}".format(data2),
"ptr={:08x}".format(ptr) ]
if (ftrace_format):
return ""
else:
return "{} ms: {:15} {:13} {}".format(formatTime(time),
event[0],
event[2],
event[1])
def decode(eventList):
for evt in eventList:
s = formatEvent(evt.time, evt.data1, evt.data2, evt.ptr)
if len(s) > 0:
print s
def decodeStateBits(flags):
bitValue = [ "STOP", "TERM", "SUSP", "BLCK", "GDBSTOP", "PRIO" , "NA" , "NA", "NA", "NA",
"NA", "TIME", "DRIV", "RESV", "EVNT", "ENQU", "DEQU", "SEND", "RECV", "SEMA",
"LIST", "LOCK", "ALLOC", "GTBL", "RESV", "RESV", "RECVDATA", "SENDDATA" ]
s = ''
for x in range(0, len(bitValue) - 1):
if (flags & (1 << x)):
s += bitValue[x] + " "
return s
def loadSymbols(elfFile):
os.system('readelf -s ' + elfFile + ' > symbols.txt')
prog = re.compile("\s+\S+:\s+([a-fA-F0-9]+)\s+\d+\s+\S+\s+\S+\s+\S+\s+\S+\s+(\S+)")
objList = {}
with open('symbols.txt', 'r') as f:
for line in f:
match = prog.match(line)
if match:
idx = int(match.group(1), 16)
if not objList.has_key(idx):
objList[idx] = match.group(2)
else:
s = match.group(2)
# Prioritize tasks / event symbols when multiple symbols
# on same address
if "_k_task_obj" in s or "_k_event_obj" in s:
objList[idx] = s
os.system('rm -rf symbols.txt')
return objList
symbols = {}
prevTaskName = ""
prevTaskId = -1
ftrace_format=0
def Main(argv):
global symbols
dumpFile = ""
elfFile = ""
sys.argv.pop(0)
for arg in sys.argv:
if arg == "--qemu":
Params.TICKS_PER_MSEC=100000.0
else:
if not dumpFile:
dumpFile = arg
elif not elfFile:
elfFile = arg
if not elfFile:
print "profile.py [DUMP FILE] [ELF FILE]"
sys.exit(0)
eventList = getData(dumpFile)
symbols = loadSymbols(elfFile)
decode(eventList)
if __name__ == "__main__":
Main(sys.argv[1:])