Skip to content
Snippets Groups Projects
Commit 161d5cf3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "linux-ramdump-parser-v2: Add support to call DCC parser"

parents cf3b4aa1 e1646624
No related branches found
No related tags found
No related merge requests found
*.pyc
# Copyright (c) 2015, The Linux Foundation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that 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.
import datetime
import logging
import logging.handlers
import os
import struct
import sys
from optparse import OptionParser
count = 0
address = []
data = []
def log_init(name, path, filename):
# Set up logger
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
# Add the log message handler to the logger
if filename is not None:
handler = logging.FileHandler(path + '/' + filename, mode='w')
else:
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
return logger
def add_addr(base, offset, length):
for i in range(0, length):
addr = base + offset + (i * 4)
address.append(addr)
def read_data(data_pt):
nr = count
while nr > 0:
word = data_pt.read(4)
if len(word) != 4:
break
val = struct.unpack('<L', word)[0]
data.append(val)
nr = nr - 1
return nr
def read_config(config_pt):
nr = 0
offset = 0
base = 0
while True:
word = config_pt.read(4)
if len(word) != 4:
break
val = struct.unpack('<L', word)[0]
if val == 0:
break
if val & (1 << 31):
base = ((val & 0x0FFFFFFF) << 4)
offset = 0
else:
for i in range(0, 2):
offset = offset + (val & 0xFF) * 4
val = val >> 8
length = (val & 0x7f)
val = val >> 8
if length != 0:
nr += length
add_addr(base, offset, length)
else:
if (i == 0):
log.error("Error! Found zero length!")
return 0
else:
offset = 0
return nr
def dump_regs_json(options):
log.info("Dumping regs in JSON format in \'{0}\' file.".format(options.outfile))
parsed_data.info("{")
parsed_data.info("\t\"version\": 1,")
parsed_data.info("\t\"timestamp\": \"{0}\",".format(datetime.date.today().strftime('%m/%d/%y')))
parsed_data.info("\t\"generator\": \"Linux DCC Parser\",")
parsed_data.info("\t\"chip\": {")
parsed_data.info("\t\t\"name\": \"{0}\",".format(options.chipname))
parsed_data.info("\t\t\"version\": \"{0}\"".format(options.chipversion))
parsed_data.info("\t},")
parsed_data.info("\t\"registers\": [")
for addr, val in zip(address, data):
parsed_data.info("\t\t{{ \"address\": \"0x{0:08x}\", \"value\": \"0x{1:08x}\" }},".format(addr, val))
parsed_data.info("\t]")
parsed_data.info("}")
return
def dump_regs_xml(options):
log.info("Dumping regs in XML format in \'{0}\' file.".format(options.outfile))
parsed_data.info("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
parsed_data.info("<hwioDump version=\"1\"")
parsed_data.info("\t<timestamp>{0}</timestamp>".format(datetime.date.today().strftime('%m/%d/%y')))
parsed_data.info("\t<generator>Linux DCC Parser</generator>")
parsed_data.info("\t<chip name=\"{0}\" version=\"{1}\">".format(options.chipname, options.chipversion))
for addr, val in zip(address, data):
parsed_data.info("\t\t<register address=\"0x{0:08x}\" value=\"0x{1:08x}\" />".format(addr, val))
parsed_data.info("\t</chip>")
parsed_data.info("</hwioDump>")
return
def dump_regs(options):
if options.json is True:
dump_regs_json(options)
else:
dump_regs_xml(options)
if __name__ == '__main__':
usage = 'usage: %prog [options to print]. Run with --help for more details'
parser = OptionParser(usage)
parser.add_option('-s', '--sram-file', dest='sramfile',
help='sram image path')
parser.add_option('-a', '--atb-file', dest='atbfile', help='atb image path')
parser.add_option('-j', '--json', action='store_true',
help='output in JSON format')
parser.add_option('-o', '--out-dir', dest='outdir', help='output dir path')
parser.add_option('-f', '--output-file', dest='outfile',
help='output filename')
parser.add_option('-l', '--log-file', dest='logfile', help='Log filename')
parser.add_option('', '--chip-name', dest='chipname', help='chip name')
parser.add_option('', '--chip-version', dest='chipversion',
help='chip version')
(options, args) = parser.parse_args()
args = ''
for arg in sys.argv:
args = args + arg + ' '
if options.outdir:
if not os.path.exists(options.outdir):
print ('!!! Out directory does not exist. Creating...')
try:
os.makedirs(options.outdir)
except:
print ("Failed to create %s. You probably don't have permissions there. Bailing." % options.outdir)
sys.exit(1)
else:
options.outdir = '.'
if options.json:
ext = '.json'
else:
ext = '.xml'
if options.outfile is None:
options.outfile = 'dcc_captured_data{0}'.format(ext)
log = log_init('LOG', options.outdir, options.logfile)
log.info("Data Capture and Compare(DCC) parser.")
if options.sramfile is None:
log.error("No SRAM image file given! Exiting...")
parser.print_usage()
sys.exit(1)
try:
sram_file = open(options.sramfile, 'rb')
except:
log.error("could not open path {0}".format(options.sramfile))
log.error("Do you have read permissions on the path?")
sys.exit(1)
if options.atbfile is not None:
try:
atb_file = open(options.atbfile, 'rb')
except:
log.error("could not open path {0}".format(options.atbfile))
log.error("Do you have read permissions on the path?")
sys.exit(1)
count = 0
count = read_config(sram_file)
if options.atbfile is None:
atb_file = sram_file
if count == 0:
log.error('No configuration found in SRAM!!')
sys.exit(1)
if read_data(atb_file):
log.error('Couldn\'t read complete data.')
else:
parsed_data = log_init('PARSED_DATA', options.outdir, options.outfile)
dump_regs(options)
sram_file.close()
if options.atbfile is not None:
atb_file.close()
sys.stderr.flush()
# Copyright (c) 2015, The Linux Foundation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that 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.
import struct
from print_out import print_out_str
from ramparse import VERSION
dcc_register_list = [
'DCC_HW_VERSION',
'DCC_HW_INFO',
'DCC_CGC_CFG',
'DCC_LL',
'DCC_RAM_CFG',
'DCC_CFG',
'DCC_SW_CTL',
'DCC_STATUS',
'DCC_FETCH_ADDR',
'DCC_SRAM_ADDR',
'DCC_INT_ENABLE',
'DCC_INT_STATUS',
'DCC_QSB_CFG'
]
# DCC regs hash table
dcc_regs = {}
class DccRegDump():
def __init__(self, start, end):
self.start_addr = start
self.end_addr = end
def parse_all_regs(self, ram_dump):
num_reg = len(dcc_register_list)
if (self.start_addr + 4 * num_reg) > self.end_addr:
return False
for reg in dcc_register_list:
dcc_regs[reg] = ram_dump.read_u32(self.start_addr, False)
self.start_addr += 4
return True
def dump_all_regs(self, ram_dump):
outfile = ram_dump.open_file('dcc_regs.txt')
outfile.write('DCC registers:\n')
for reg in dcc_register_list:
outfile.write('{0} : 0x{1:08x}\n'.format(reg, dcc_regs[reg]))
outfile.close()
class DccSramDump():
def __init__(self, start, end):
self.start_addr = start
self.end_addr = end
def dump_sram_img(self, ram_dump):
if self.start_addr >= self.end_addr:
return False
rsz = self.end_addr - self.start_addr
if dcc_regs.has_key('DCC_HW_INFO') == False \
or dcc_regs['DCC_HW_INFO'] == 0:
print_out_str('DCC HW Info missing! Skipping sram dump...')
return False
if dcc_regs['DCC_CFG'] & 0x1:
print_out_str('DCC is configured in CRC mode. Skipping sram dump ...')
return False
if dcc_regs['DCC_RAM_CFG'] == 0:
print_out_str('No config found in DCC SRAM. Skipping sram dump ...')
return False
sramfile = ram_dump.open_file('sram.bin')
for i in range(0, rsz):
val = ram_dump.read_byte(self.start_addr + i, False)
sramfile.write(struct.pack('<B', val))
sramfile.close()
return True
......@@ -16,7 +16,9 @@ import shutil
import os
import platform
import subprocess
import sys
from dcc import DccRegDump, DccSramDump
from pmic import PmicRegDump
from print_out import print_out_str, print_out_exception
from qdss import QDSSDump
......@@ -57,6 +59,8 @@ client_table = {
'MSM_DUMP_DATA_OCMEM': 'parse_ocmem',
'MSM_DUMP_DATA_DBGUI_REG' : 'parse_qdss_common',
'MSM_DUMP_DATA_PMIC': 'parse_pmic',
'MSM_DUMP_DATA_DCC_REG':'parse_dcc_reg',
'MSM_DUMP_DATA_DCC_SRAM':'parse_dcc_sram',
'MSM_DUMP_DATA_TMC_ETF': 'parse_qdss_common',
'MSM_DUMP_DATA_TMC_REG': 'parse_qdss_common',
'MSM_DUMP_DATA_L2_TLB': 'parse_l2_tlb',
......@@ -102,6 +106,33 @@ class DebugImage_v2():
regs.dump_all_regs(ram_dump)
def parse_dcc_reg(self, version, start, end, client_id, ram_dump):
client_name = self.dump_data_id_lookup_table[client_id]
print_out_str(
'Parsing {0} context start {1:x} end {2:x}'.format(client_name, start, end))
regs = DccRegDump(start, end)
if regs.parse_all_regs(ram_dump) is False:
print_out_str('!!! Could not get registers from DCC register dump')
return
regs.dump_all_regs(ram_dump)
return
def parse_dcc_sram(self, version, start, end, client_id, ram_dump):
client_name = self.dump_data_id_lookup_table[client_id]
print_out_str(
'Parsing {0} context start {1:x} end {2:x}'.format(client_name, start, end))
regs = DccSramDump(start, end)
if regs.dump_sram_img(ram_dump) is False:
print_out_str('!!! Could not dump SRAM')
else:
ram_dump.dcc = True
return
def parse_qdss_common(self, version, start, end, client_id, ram_dump):
client_name = self.dump_data_id_lookup_table[client_id]
......@@ -250,6 +281,30 @@ class DebugImage_v2():
subprocess.call('{0} -c {1} exit'.format(qtf_path, port))
p.communicate('quit')
def parse_dcc(self, ram_dump):
out_dir = ram_dump.outdir
dcc_parser_path = os.path.join(os.path.dirname(__file__), '..', 'dcc_parser', 'dcc_parser.py')
if dcc_parser_path is None:
print_out_str("!!! Incorrect path for DCC specified.")
return
if not os.path.exists(dcc_parser_path):
print_out_str("!!! dcc_parser_path {0} does not exist! Check your settings!".format(dcc_parser_path))
return
if os.path.getsize(os.path.join(out_dir, 'sram.bin')) > 0:
sram_file = os.path.join(out_dir, 'sram.bin')
else:
return
p = subprocess.Popen([sys.executable, dcc_parser_path, '-s', sram_file, '--out-dir', out_dir],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print_out_str('--------')
print_out_str(p.communicate()[0])
def parse_dump_v2(self, ram_dump):
self.dump_type_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
'msm_dump_type', 2)
......@@ -418,3 +473,5 @@ class DebugImage_v2():
self.qdss.dump_all(ram_dump)
if ram_dump.qtf:
self.parse_qtf(ram_dump)
if ram_dump.dcc:
self.parse_dcc(ram_dump)
......@@ -460,6 +460,7 @@ class RamDump():
self.thread_size = 8192
self.qtf_path = options.qtf_path
self.qtf = options.qtf
self.dcc = False
self.t32_host_system = options.t32_host_system or None
self.ipc_log_test = options.ipc_test
self.ipc_log_skip = options.ipc_skip
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment