decode_packet_trace.py revision 12212:1ae8dc8fdb97
11689SN/A#!/usr/bin/env python2
210273Sandreas.hansson@arm.com
39480Snilay@cs.wisc.edu# Copyright (c) 2013-2014 ARM Limited
48843SN/A# All rights reserved
58843SN/A#
68843SN/A# The license below extends only to copyright in the software and shall
78843SN/A# not be construed as granting a license to any other intellectual
88843SN/A# property including but not limited to intellectual property relating
98843SN/A# to a hardware implementation of the functionality of the software
108843SN/A# licensed hereunder.  You may use the software subject to the license
118843SN/A# terms below provided that you ensure that this notice is replicated
128843SN/A# unmodified and in its entirety in all distributions of the software,
138843SN/A# modified or unmodified, in source code or in binary form.
148843SN/A#
151689SN/A# Redistribution and use in source and binary forms, with or without
161689SN/A# modification, are permitted provided that the following conditions are
171689SN/A# met: redistributions of source code must retain the above copyright
181689SN/A# notice, this list of conditions and the following disclaimer;
191689SN/A# redistributions in binary form must reproduce the above copyright
201689SN/A# notice, this list of conditions and the following disclaimer in the
211689SN/A# documentation and/or other materials provided with the distribution;
221689SN/A# neither the name of the copyright holders nor the names of its
231689SN/A# contributors may be used to endorse or promote products derived from
241689SN/A# this software without specific prior written permission.
251689SN/A#
261689SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
271689SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
281689SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
291689SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
301689SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
311689SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
321689SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
331689SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
341689SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
351689SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
361689SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
371689SN/A#
381689SN/A# Authors: Andreas Hansson
391689SN/A
402665SN/A# This script is used to dump protobuf packet traces to ASCII
412665SN/A# format. It assumes that protoc has been executed and already
429480Snilay@cs.wisc.edu# generated the Python package for the packet messages. This can
439480Snilay@cs.wisc.edu# be done manually using:
449480Snilay@cs.wisc.edu# protoc --python_out=. --proto_path=src/proto src/proto/packet.proto
451689SN/A#
461061SN/A# The ASCII trace format uses one line per request on the format cmd,
479480Snilay@cs.wisc.edu# addr, size, tick,flags. For example:
489480Snilay@cs.wisc.edu# r,128,64,4000,0
491061SN/A# w,232123,64,500000,0
5010273Sandreas.hansson@arm.com
516216SN/Aimport protolib
521062SN/Aimport sys
536216SN/A
546226SN/A# Import the packet proto definitions. If they are not found, attempt
556226SN/A# to generate them automatically.
568229SN/Atry:
579480Snilay@cs.wisc.edu    import packet_pb2
589480Snilay@cs.wisc.eduexcept:
599480Snilay@cs.wisc.edu    print "Did not find packet proto definitions, attempting to generate"
605529SN/A    import os
611061SN/A    util_dir = os.path.dirname(os.path.realpath(__file__))
621061SN/A    proto_dir = os.path.join(os.path.dirname(util_dir), 'src', 'proto')
632329SN/A    proto_file = os.path.join(proto_dir, 'packet.proto')
641061SN/A    from subprocess import call
659480Snilay@cs.wisc.edu    error = call(['protoc', '--python_out=' + util_dir,
661061SN/A                  '--proto_path=' + proto_dir, proto_file])
672345SN/A    if not error:
689480Snilay@cs.wisc.edu        print "Generated packet proto definitions"
692292SN/A
702292SN/A        try:
712292SN/A            import google.protobuf
729480Snilay@cs.wisc.edu        except:
736005SN/A            print "Please install Python protobuf module"
742292SN/A            exit(-1)
752292SN/A
762292SN/A        import packet_pb2
771062SN/A    else:
781062SN/A        print "Failed to import packet proto definitions"
799444SN/A        exit(-1)
809444SN/A
811062SN/Adef main():
822292SN/A    if len(sys.argv) != 3:
832292SN/A        print "Usage: ", sys.argv[0], " <protobuf input> <ASCII output>"
842292SN/A        exit(-1)
852292SN/A
862292SN/A    # Open the file in read mode
872292SN/A    proto_in = protolib.openFileRd(sys.argv[1])
882292SN/A
892292SN/A    try:
909480Snilay@cs.wisc.edu        ascii_out = open(sys.argv[2], 'w')
919480Snilay@cs.wisc.edu    except IOError:
929480Snilay@cs.wisc.edu        print "Failed to open ", sys.argv[2], " for writing"
9310244Satgutier@umich.edu        exit(-1)
9410244Satgutier@umich.edu
951684SN/A    # Read the magic number in 4-byte Little Endian
962345SN/A    magic_number = proto_in.read(4)
979480Snilay@cs.wisc.edu
982345SN/A    if magic_number != "gem5":
992292SN/A        print "Unrecognized file", sys.argv[1]
1002292SN/A        exit(-1)
1012292SN/A
1022292SN/A    print "Parsing packet header"
1032292SN/A
1042292SN/A    # Add the packet header
1056221SN/A    header = packet_pb2.PacketHeader()
1062165SN/A    protolib.decodeMessage(proto_in, header)
1072292SN/A
1082292SN/A    print "Object id:", header.obj_id
1092292SN/A    print "Tick frequency:", header.tick_freq
1102292SN/A
1112292SN/A    for id_string in header.id_strings:
1122292SN/A        print 'Master id %d: %s' % (id_string.key, id_string.value)
1136221SN/A
1142165SN/A    print "Parsing packets"
1152292SN/A
1162292SN/A    num_packets = 0
1172292SN/A    packet = packet_pb2.Packet()
1182292SN/A
1192292SN/A    # Decode the packet messages until we hit the end of the file
1202292SN/A    while protolib.decodeMessage(proto_in, packet):
1212292SN/A        num_packets += 1
1222292SN/A        # ReadReq is 1 and WriteReq is 4 in src/mem/packet.hh Command enum
1232292SN/A        cmd = 'r' if packet.cmd == 1 else ('w' if packet.cmd == 4 else 'u')
1247720SN/A        if packet.HasField('pkt_id'):
1257720SN/A            ascii_out.write('%s,' % (packet.pkt_id))
1266221SN/A        if packet.HasField('flags'):
1271062SN/A            ascii_out.write('%s,%s,%s,%s,%s' % (cmd, packet.addr, packet.size,
1282292SN/A                            packet.flags, packet.tick))
1292345SN/A        else:
1302345SN/A            ascii_out.write('%s,%s,%s,%s' % (cmd, packet.addr, packet.size,
1312345SN/A                                           packet.tick))
1329480Snilay@cs.wisc.edu        if packet.HasField('pc'):
1332345SN/A            ascii_out.write(',%s\n' % (packet.pc))
1342345SN/A        else:
1352292SN/A            ascii_out.write('\n')
1362292SN/A
1372345SN/A    print "Parsed packets:", num_packets
1382345SN/A
1392292SN/A    # We're done
1402292SN/A    ascii_out.close()
1419480Snilay@cs.wisc.edu    proto_in.close()
1421061SN/A
1438842SN/Aif __name__ == "__main__":
1448842SN/A    main()
1458842SN/A