110259SAndrew.Bardsley@arm.com# Copyright (c) 2013 ARM Limited 210259SAndrew.Bardsley@arm.com# All rights reserved 310259SAndrew.Bardsley@arm.com# 410259SAndrew.Bardsley@arm.com# The license below extends only to copyright in the software and shall 510259SAndrew.Bardsley@arm.com# not be construed as granting a license to any other intellectual 610259SAndrew.Bardsley@arm.com# property including but not limited to intellectual property relating 710259SAndrew.Bardsley@arm.com# to a hardware implementation of the functionality of the software 810259SAndrew.Bardsley@arm.com# licensed hereunder. You may use the software subject to the license 910259SAndrew.Bardsley@arm.com# terms below provided that you ensure that this notice is replicated 1010259SAndrew.Bardsley@arm.com# unmodified and in its entirety in all distributions of the software, 1110259SAndrew.Bardsley@arm.com# modified or unmodified, in source code or in binary form. 1210259SAndrew.Bardsley@arm.com# 1310259SAndrew.Bardsley@arm.com# Redistribution and use in source and binary forms, with or without 1410259SAndrew.Bardsley@arm.com# modification, are permitted provided that the following conditions are 1510259SAndrew.Bardsley@arm.com# met: redistributions of source code must retain the above copyright 1610259SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer; 1710259SAndrew.Bardsley@arm.com# redistributions in binary form must reproduce the above copyright 1810259SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer in the 1910259SAndrew.Bardsley@arm.com# documentation and/or other materials provided with the distribution; 2010259SAndrew.Bardsley@arm.com# neither the name of the copyright holders nor the names of its 2110259SAndrew.Bardsley@arm.com# contributors may be used to endorse or promote products derived from 2210259SAndrew.Bardsley@arm.com# this software without specific prior written permission. 2310259SAndrew.Bardsley@arm.com# 2410259SAndrew.Bardsley@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2510259SAndrew.Bardsley@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2610259SAndrew.Bardsley@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2710259SAndrew.Bardsley@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2810259SAndrew.Bardsley@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2910259SAndrew.Bardsley@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3010259SAndrew.Bardsley@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3110259SAndrew.Bardsley@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3210259SAndrew.Bardsley@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3310259SAndrew.Bardsley@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3410259SAndrew.Bardsley@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3510259SAndrew.Bardsley@arm.com# 3610259SAndrew.Bardsley@arm.com# Authors: Andrew Bardsley 3710259SAndrew.Bardsley@arm.com 3810259SAndrew.Bardsley@arm.comimport parse 3910259SAndrew.Bardsley@arm.comimport colours 4010259SAndrew.Bardsley@arm.comfrom colours import unknownColour 4110259SAndrew.Bardsley@arm.comfrom point import Point 4210259SAndrew.Bardsley@arm.comimport re 4310259SAndrew.Bardsley@arm.comimport blobs 4410259SAndrew.Bardsley@arm.comfrom time import time as wall_time 4510259SAndrew.Bardsley@arm.comimport os 4610259SAndrew.Bardsley@arm.com 4710259SAndrew.Bardsley@arm.comid_parts = "TSPLFE" 4810259SAndrew.Bardsley@arm.com 4910259SAndrew.Bardsley@arm.comall_ids = set(id_parts) 5010259SAndrew.Bardsley@arm.comno_ids = set([]) 5110259SAndrew.Bardsley@arm.com 5210259SAndrew.Bardsley@arm.comclass BlobDataSelect(object): 5310259SAndrew.Bardsley@arm.com """Represents which data is displayed for Ided object""" 5410259SAndrew.Bardsley@arm.com def __init__(self): 5510259SAndrew.Bardsley@arm.com # Copy all_ids 5610259SAndrew.Bardsley@arm.com self.ids = set(all_ids) 5710259SAndrew.Bardsley@arm.com 5810259SAndrew.Bardsley@arm.com def __and__(self, rhs): 5910259SAndrew.Bardsley@arm.com """And for filtering""" 6010259SAndrew.Bardsley@arm.com ret = BlobDataSelect() 6110259SAndrew.Bardsley@arm.com ret.ids = self.ids.intersection(rhs.ids) 6210259SAndrew.Bardsley@arm.com return ret 6310259SAndrew.Bardsley@arm.com 6410259SAndrew.Bardsley@arm.comclass BlobVisualData(object): 6510259SAndrew.Bardsley@arm.com """Super class for block data colouring""" 6610259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 6710259SAndrew.Bardsley@arm.com """Return an array of colours to use for a striped block""" 6810259SAndrew.Bardsley@arm.com return unknownColour 6910259SAndrew.Bardsley@arm.com 7010259SAndrew.Bardsley@arm.com def get_inst(self): 7110259SAndrew.Bardsley@arm.com """Get an instruction Id (if any) from this data""" 7210259SAndrew.Bardsley@arm.com return None 7310259SAndrew.Bardsley@arm.com 7410259SAndrew.Bardsley@arm.com def get_line(self): 7510259SAndrew.Bardsley@arm.com """Get a line Id (if any) from this data""" 7610259SAndrew.Bardsley@arm.com return None 7710259SAndrew.Bardsley@arm.com 7810259SAndrew.Bardsley@arm.com def __repr__(self): 7910259SAndrew.Bardsley@arm.com return self.__class__.__name__ + '().from_string(' + \ 8010259SAndrew.Bardsley@arm.com self.__str__() + ')' 8110259SAndrew.Bardsley@arm.com 8210259SAndrew.Bardsley@arm.com def __str__(self): 8310259SAndrew.Bardsley@arm.com return '' 8410259SAndrew.Bardsley@arm.com 8510259SAndrew.Bardsley@arm.comclass Id(BlobVisualData): 8610259SAndrew.Bardsley@arm.com """A line or instruction id""" 8710259SAndrew.Bardsley@arm.com def __init__(self): 8810259SAndrew.Bardsley@arm.com self.isFault = False 8910259SAndrew.Bardsley@arm.com self.threadId = 0 9010259SAndrew.Bardsley@arm.com self.streamSeqNum = 0 9110259SAndrew.Bardsley@arm.com self.predictionSeqNum = 0 9210259SAndrew.Bardsley@arm.com self.lineSeqNum = 0 9310259SAndrew.Bardsley@arm.com self.fetchSeqNum = 0 9410259SAndrew.Bardsley@arm.com self.execSeqNum = 0 9510259SAndrew.Bardsley@arm.com 9610259SAndrew.Bardsley@arm.com def as_list(self): 9710259SAndrew.Bardsley@arm.com return [self.threadId, self.streamSeqNum, self.predictionSeqNum, 9810259SAndrew.Bardsley@arm.com self.lineSeqNum, self.fetchSeqNum, self.execSeqNum] 9910259SAndrew.Bardsley@arm.com 10010259SAndrew.Bardsley@arm.com def __cmp__(self, right): 10110259SAndrew.Bardsley@arm.com return cmp(self.as_list(), right.as_list()) 10210259SAndrew.Bardsley@arm.com 10310259SAndrew.Bardsley@arm.com def from_string(self, string): 10410259SAndrew.Bardsley@arm.com m = re.match('^(F;)?(\d+)/(\d+)\.(\d+)/(\d+)(/(\d+)(\.(\d+))?)?', 10510259SAndrew.Bardsley@arm.com string) 10610259SAndrew.Bardsley@arm.com 10710259SAndrew.Bardsley@arm.com def seqnum_from_string(string): 10810259SAndrew.Bardsley@arm.com if string is None: 10910259SAndrew.Bardsley@arm.com return 0 11010259SAndrew.Bardsley@arm.com else: 11110259SAndrew.Bardsley@arm.com return int(string) 11210259SAndrew.Bardsley@arm.com 11310259SAndrew.Bardsley@arm.com if m is None: 11410259SAndrew.Bardsley@arm.com print 'Invalid Id string', string 11510259SAndrew.Bardsley@arm.com else: 11610259SAndrew.Bardsley@arm.com elems = m.groups() 11710259SAndrew.Bardsley@arm.com 11810259SAndrew.Bardsley@arm.com if elems[0] is not None: 11910259SAndrew.Bardsley@arm.com self.isFault = True 12010259SAndrew.Bardsley@arm.com else: 12110259SAndrew.Bardsley@arm.com self.isFault = False 12210259SAndrew.Bardsley@arm.com 12310259SAndrew.Bardsley@arm.com self.threadId = seqnum_from_string(elems[1]) 12410259SAndrew.Bardsley@arm.com self.streamSeqNum = seqnum_from_string(elems[2]) 12510259SAndrew.Bardsley@arm.com self.predictionSeqNum = seqnum_from_string(elems[3]) 12610259SAndrew.Bardsley@arm.com self.lineSeqNum = seqnum_from_string(elems[4]) 12710259SAndrew.Bardsley@arm.com self.fetchSeqNum = seqnum_from_string(elems[6]) 12810259SAndrew.Bardsley@arm.com self.execSeqNum = seqnum_from_string(elems[8]) 12910259SAndrew.Bardsley@arm.com return self 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.com def get_inst(self): 13210259SAndrew.Bardsley@arm.com if self.fetchSeqNum != 0: 13310259SAndrew.Bardsley@arm.com return self 13410259SAndrew.Bardsley@arm.com else: 13510259SAndrew.Bardsley@arm.com return None 13610259SAndrew.Bardsley@arm.com 13710259SAndrew.Bardsley@arm.com def get_line(self): 13810259SAndrew.Bardsley@arm.com return self 13910259SAndrew.Bardsley@arm.com 14010259SAndrew.Bardsley@arm.com def __str__(self): 14110259SAndrew.Bardsley@arm.com """Returns the usual id T/S.P/L/F.E string""" 14210259SAndrew.Bardsley@arm.com return ( 14310259SAndrew.Bardsley@arm.com str(self.threadId) + '/' + 14410259SAndrew.Bardsley@arm.com str(self.streamSeqNum) + '.' + 14510259SAndrew.Bardsley@arm.com str(self.predictionSeqNum) + '/' + 14610259SAndrew.Bardsley@arm.com str(self.lineSeqNum) + '/' + 14710259SAndrew.Bardsley@arm.com str(self.fetchSeqNum) + '.' + 14810259SAndrew.Bardsley@arm.com str(self.execSeqNum)) 14910259SAndrew.Bardsley@arm.com 15010259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 15110259SAndrew.Bardsley@arm.com ret = [] 15210259SAndrew.Bardsley@arm.com 15310259SAndrew.Bardsley@arm.com if self.isFault: 15410259SAndrew.Bardsley@arm.com ret.append(colours.faultColour) 15510259SAndrew.Bardsley@arm.com 15610259SAndrew.Bardsley@arm.com if 'T' in select.ids: 15710259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.threadId)) 15810259SAndrew.Bardsley@arm.com if 'S' in select.ids: 15910259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.streamSeqNum)) 16010259SAndrew.Bardsley@arm.com if 'P' in select.ids: 16110259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.predictionSeqNum)) 16210259SAndrew.Bardsley@arm.com if 'L' in select.ids: 16310259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.lineSeqNum)) 16410259SAndrew.Bardsley@arm.com if self.fetchSeqNum != 0 and 'F' in select.ids: 16510259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.fetchSeqNum)) 16610259SAndrew.Bardsley@arm.com if self.execSeqNum != 0 and 'E' in select.ids: 16710259SAndrew.Bardsley@arm.com ret.append(colours.number_to_colour(self.execSeqNum)) 16810259SAndrew.Bardsley@arm.com 16910259SAndrew.Bardsley@arm.com if len(ret) == 0: 17010259SAndrew.Bardsley@arm.com ret = [colours.unknownColour] 17110259SAndrew.Bardsley@arm.com 17210259SAndrew.Bardsley@arm.com if self.isFault: 17310259SAndrew.Bardsley@arm.com ret.append(colours.faultColour) 17410259SAndrew.Bardsley@arm.com 17510259SAndrew.Bardsley@arm.com return ret 17610259SAndrew.Bardsley@arm.com 17710259SAndrew.Bardsley@arm.comclass Branch(BlobVisualData): 17810259SAndrew.Bardsley@arm.com """Branch data new stream and prediction sequence numbers, a branch 17910259SAndrew.Bardsley@arm.com reason and a new PC""" 18010259SAndrew.Bardsley@arm.com def __init__(self): 18110259SAndrew.Bardsley@arm.com self.newStreamSeqNum = 0 18210259SAndrew.Bardsley@arm.com self.newPredictionSeqNum = 0 18310259SAndrew.Bardsley@arm.com self.newPC = 0 18410259SAndrew.Bardsley@arm.com self.reason = "NoBranch" 18510259SAndrew.Bardsley@arm.com self.id = Id() 18610259SAndrew.Bardsley@arm.com 18710259SAndrew.Bardsley@arm.com def from_string(self, string): 18810259SAndrew.Bardsley@arm.com m = re.match('^(\w+);(\d+)\.(\d+);([0-9a-fA-Fx]+);(.*)$', string) 18910259SAndrew.Bardsley@arm.com 19010259SAndrew.Bardsley@arm.com if m is not None: 19110259SAndrew.Bardsley@arm.com self.reason, newStreamSeqNum, newPredictionSeqNum, \ 19210259SAndrew.Bardsley@arm.com newPC, id = m.groups() 19310259SAndrew.Bardsley@arm.com 19410259SAndrew.Bardsley@arm.com self.newStreamSeqNum = int(newStreamSeqNum) 19510259SAndrew.Bardsley@arm.com self.newPredictionSeqNum = int(newPredictionSeqNum) 19610259SAndrew.Bardsley@arm.com self.newPC = int(newPC, 0) 19710259SAndrew.Bardsley@arm.com self.id = special_view_decoder(Id)(id) 19810259SAndrew.Bardsley@arm.com # self.branch = special_view_decoder(Branch)(branch) 19910259SAndrew.Bardsley@arm.com else: 20010259SAndrew.Bardsley@arm.com print "Bad Branch data:", string 20110259SAndrew.Bardsley@arm.com return self 20210259SAndrew.Bardsley@arm.com 20310259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 20410259SAndrew.Bardsley@arm.com return [colours.number_to_colour(self.newStreamSeqNum), 20510259SAndrew.Bardsley@arm.com colours.number_to_colour(self.newPredictionSeqNum), 20610259SAndrew.Bardsley@arm.com colours.number_to_colour(self.newPC)] 20710259SAndrew.Bardsley@arm.com 20810259SAndrew.Bardsley@arm.comclass Counts(BlobVisualData): 20910259SAndrew.Bardsley@arm.com """Treat the input data as just a /-separated list of count values (or 21010259SAndrew.Bardsley@arm.com just a single value)""" 21110259SAndrew.Bardsley@arm.com def __init__(self): 21210259SAndrew.Bardsley@arm.com self.counts = [] 21310259SAndrew.Bardsley@arm.com 21410259SAndrew.Bardsley@arm.com def from_string(self, string): 21510259SAndrew.Bardsley@arm.com self.counts = map(int, re.split('/', string)) 21610259SAndrew.Bardsley@arm.com return self 21710259SAndrew.Bardsley@arm.com 21810259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 21910259SAndrew.Bardsley@arm.com return map(colours.number_to_colour, self.counts) 22010259SAndrew.Bardsley@arm.com 22110259SAndrew.Bardsley@arm.comclass Colour(BlobVisualData): 22210259SAndrew.Bardsley@arm.com """A fixed colour block, used for special colour decoding""" 22310259SAndrew.Bardsley@arm.com def __init__(self, colour): 22410259SAndrew.Bardsley@arm.com self.colour = colour 22510259SAndrew.Bardsley@arm.com 22610259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 22710259SAndrew.Bardsley@arm.com return [self.colour] 22810259SAndrew.Bardsley@arm.com 22910259SAndrew.Bardsley@arm.comclass DcacheAccess(BlobVisualData): 23010259SAndrew.Bardsley@arm.com """Data cache accesses [RW];id""" 23110259SAndrew.Bardsley@arm.com def __init__(self): 23210259SAndrew.Bardsley@arm.com self.direc = 'R' 23310259SAndrew.Bardsley@arm.com self.id = Id() 23410259SAndrew.Bardsley@arm.com 23510259SAndrew.Bardsley@arm.com def from_string(self, string): 23610259SAndrew.Bardsley@arm.com self.direc, id = re.match('^([RW]);([^;]*);.*$', string).groups() 23710259SAndrew.Bardsley@arm.com self.id.from_string(id) 23810259SAndrew.Bardsley@arm.com return self 23910259SAndrew.Bardsley@arm.com 24010259SAndrew.Bardsley@arm.com def get_inst(self): 24110259SAndrew.Bardsley@arm.com return self.id 24210259SAndrew.Bardsley@arm.com 24310259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 24410259SAndrew.Bardsley@arm.com if self.direc == 'R': 24510259SAndrew.Bardsley@arm.com direc_colour = colours.readColour 24610259SAndrew.Bardsley@arm.com elif self.direc == 'R': 24710259SAndrew.Bardsley@arm.com direc_colour = colours.writeColour 24810259SAndrew.Bardsley@arm.com else: 24910259SAndrew.Bardsley@arm.com direc_colour = colours.errorColour 25010259SAndrew.Bardsley@arm.com return [direc_colour] + self.id.to_striped_block(select) 25110259SAndrew.Bardsley@arm.com 25210259SAndrew.Bardsley@arm.comclass ColourPattern(object): 25310259SAndrew.Bardsley@arm.com """Super class for decoders that make 2D grids rather than just single 25410259SAndrew.Bardsley@arm.com striped blocks""" 25510259SAndrew.Bardsley@arm.com def elems(self): 25610259SAndrew.Bardsley@arm.com return [] 25710259SAndrew.Bardsley@arm.com 25810259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 25910259SAndrew.Bardsley@arm.com return [[[colours.errorColour]]] 26010259SAndrew.Bardsley@arm.com 26110259SAndrew.Bardsley@arm.comdef special_view_decoder(class_): 26210259SAndrew.Bardsley@arm.com """Generate a decode function that checks for special character 26310259SAndrew.Bardsley@arm.com arguments first (and generates a fixed colour) before building a 26410259SAndrew.Bardsley@arm.com BlobVisualData of the given class""" 26510259SAndrew.Bardsley@arm.com def decode(symbol): 26610259SAndrew.Bardsley@arm.com if symbol in special_state_colours: 26710259SAndrew.Bardsley@arm.com return Colour(special_state_colours[symbol]) 26810259SAndrew.Bardsley@arm.com else: 26910259SAndrew.Bardsley@arm.com return class_().from_string(symbol) 27010259SAndrew.Bardsley@arm.com return decode 27110259SAndrew.Bardsley@arm.com 27210259SAndrew.Bardsley@arm.comclass TwoDColours(ColourPattern): 27310259SAndrew.Bardsley@arm.com """A 2D grid pattern decoder""" 27410259SAndrew.Bardsley@arm.com def __init__(self, blockss): 27510259SAndrew.Bardsley@arm.com self.blockss = blockss 27610259SAndrew.Bardsley@arm.com 27710259SAndrew.Bardsley@arm.com @classmethod 27810259SAndrew.Bardsley@arm.com def decoder(class_, elemClass, dataName): 27910259SAndrew.Bardsley@arm.com """Factory for making decoders for particular block types""" 28010259SAndrew.Bardsley@arm.com def decode(pairs): 28110259SAndrew.Bardsley@arm.com if dataName not in pairs: 28210259SAndrew.Bardsley@arm.com print 'TwoDColours: no event data called:', \ 28310259SAndrew.Bardsley@arm.com dataName, 'in:', pairs 28410259SAndrew.Bardsley@arm.com return class_([[Colour(colours.errorColour)]]) 28510259SAndrew.Bardsley@arm.com else: 28610259SAndrew.Bardsley@arm.com parsed = parse.list_parser(pairs[dataName]) 28710259SAndrew.Bardsley@arm.com return class_(parse.map2(special_view_decoder(elemClass), \ 28810259SAndrew.Bardsley@arm.com parsed)) 28910259SAndrew.Bardsley@arm.com return decode 29010259SAndrew.Bardsley@arm.com 29110259SAndrew.Bardsley@arm.com @classmethod 29210259SAndrew.Bardsley@arm.com def indexed_decoder(class_, elemClass, dataName, picPairs): 29310259SAndrew.Bardsley@arm.com """Factory for making decoders for particular block types but 29410259SAndrew.Bardsley@arm.com where the list elements are pairs of (index, data) and 29510259SAndrew.Bardsley@arm.com strip and stripelems counts are picked up from the pair 29610259SAndrew.Bardsley@arm.com data on the decoder's picture file. This gives a 2D layout 29710259SAndrew.Bardsley@arm.com of the values with index 0 at strip=0, elem=0 and index 1 29810259SAndrew.Bardsley@arm.com at strip=0, elem=1""" 29910259SAndrew.Bardsley@arm.com def decode(pairs): 30010259SAndrew.Bardsley@arm.com if dataName not in pairs: 30110259SAndrew.Bardsley@arm.com print 'TwoDColours: no event data called:', \ 30210259SAndrew.Bardsley@arm.com dataName, 'in:', pairs 30310259SAndrew.Bardsley@arm.com return class_([[Colour(colours.errorColour)]]) 30410259SAndrew.Bardsley@arm.com else: 30510259SAndrew.Bardsley@arm.com strips = int(picPairs['strips']) 30610259SAndrew.Bardsley@arm.com strip_elems = int(picPairs['stripelems']) 30710259SAndrew.Bardsley@arm.com 30810259SAndrew.Bardsley@arm.com raw_iv_pairs = pairs[dataName] 30910259SAndrew.Bardsley@arm.com 31010259SAndrew.Bardsley@arm.com parsed = parse.parse_indexed_list(raw_iv_pairs) 31110259SAndrew.Bardsley@arm.com 31210259SAndrew.Bardsley@arm.com array = [[Colour(colours.emptySlotColour) 31310259SAndrew.Bardsley@arm.com for i in xrange(0, strip_elems)] 31410259SAndrew.Bardsley@arm.com for j in xrange(0, strips)] 31510259SAndrew.Bardsley@arm.com 31610259SAndrew.Bardsley@arm.com for index, value in parsed: 31710259SAndrew.Bardsley@arm.com try: 31810259SAndrew.Bardsley@arm.com array[index % strips][index / strips] = \ 31910259SAndrew.Bardsley@arm.com special_view_decoder(elemClass)(value) 32010259SAndrew.Bardsley@arm.com except: 32110259SAndrew.Bardsley@arm.com print "Element out of range strips: %d," \ 32210259SAndrew.Bardsley@arm.com " stripelems %d, index: %d" % (strips, 32310259SAndrew.Bardsley@arm.com strip_elems, index) 32410259SAndrew.Bardsley@arm.com 32510259SAndrew.Bardsley@arm.com # return class_(array) 32610259SAndrew.Bardsley@arm.com return class_(array) 32710259SAndrew.Bardsley@arm.com return decode 32810259SAndrew.Bardsley@arm.com 32910259SAndrew.Bardsley@arm.com def elems(self): 33010259SAndrew.Bardsley@arm.com """Get a flat list of all elements""" 33110259SAndrew.Bardsley@arm.com ret = [] 33210259SAndrew.Bardsley@arm.com for blocks in self.blockss: 33310259SAndrew.Bardsley@arm.com ret += blocks 33410259SAndrew.Bardsley@arm.com return ret 33510259SAndrew.Bardsley@arm.com 33610259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 33710259SAndrew.Bardsley@arm.com return parse.map2(lambda d: d.to_striped_block(select), self.blockss) 33810259SAndrew.Bardsley@arm.com 33910259SAndrew.Bardsley@arm.comclass FrameColours(ColourPattern): 34010259SAndrew.Bardsley@arm.com """Decode to a 2D grid which has a single occupied row from the event 34110259SAndrew.Bardsley@arm.com data and some blank rows forming a frame with the occupied row as a 34210259SAndrew.Bardsley@arm.com 'title' coloured stripe""" 34310259SAndrew.Bardsley@arm.com def __init__(self, block, numBlankSlots): 34410259SAndrew.Bardsley@arm.com self.numBlankSlots = numBlankSlots 34510259SAndrew.Bardsley@arm.com self.block = block 34610259SAndrew.Bardsley@arm.com 34710259SAndrew.Bardsley@arm.com @classmethod 34810259SAndrew.Bardsley@arm.com def decoder(class_, elemClass, numBlankSlots, dataName): 34910259SAndrew.Bardsley@arm.com """Factory for element type""" 35010259SAndrew.Bardsley@arm.com def decode(pairs): 35110259SAndrew.Bardsley@arm.com if dataName not in pairs: 35210259SAndrew.Bardsley@arm.com print 'FrameColours: no event data called:', dataName, \ 35310259SAndrew.Bardsley@arm.com 'in:', pairs 35410259SAndrew.Bardsley@arm.com return class_([Colour(colours.errorColour)]) 35510259SAndrew.Bardsley@arm.com else: 35610259SAndrew.Bardsley@arm.com parsed = parse.list_parser(pairs[dataName]) 35710259SAndrew.Bardsley@arm.com return class_(special_view_decoder(elemClass) 35810259SAndrew.Bardsley@arm.com (parsed[0][0]), numBlankSlots) 35910259SAndrew.Bardsley@arm.com return decode 36010259SAndrew.Bardsley@arm.com 36110259SAndrew.Bardsley@arm.com def elems(self): 36210259SAndrew.Bardsley@arm.com return [self.block] 36310259SAndrew.Bardsley@arm.com 36410259SAndrew.Bardsley@arm.com def to_striped_block(self, select): 36510259SAndrew.Bardsley@arm.com return ([[self.block.to_striped_block(select)]] + 36610259SAndrew.Bardsley@arm.com (self.numBlankSlots * [[[colours.backgroundColour]]])) 36710259SAndrew.Bardsley@arm.com 36810259SAndrew.Bardsley@arm.comspecial_state_colours = { 36910259SAndrew.Bardsley@arm.com 'U': colours.unknownColour, 37010259SAndrew.Bardsley@arm.com 'B': colours.blockedColour, 37110259SAndrew.Bardsley@arm.com '-': colours.bubbleColour, 37210259SAndrew.Bardsley@arm.com '': colours.emptySlotColour, 37310259SAndrew.Bardsley@arm.com 'E': colours.emptySlotColour, 37410259SAndrew.Bardsley@arm.com 'R': colours.reservedSlotColour, 37510259SAndrew.Bardsley@arm.com 'X': colours.errorColour, 37610259SAndrew.Bardsley@arm.com 'F': colours.faultColour, 37710259SAndrew.Bardsley@arm.com 'r': colours.readColour, 37810259SAndrew.Bardsley@arm.com 'w': colours.writeColour 37910259SAndrew.Bardsley@arm.com } 38010259SAndrew.Bardsley@arm.com 38110259SAndrew.Bardsley@arm.comspecial_state_names = { 38210259SAndrew.Bardsley@arm.com 'U': '(U)nknown', 38310259SAndrew.Bardsley@arm.com 'B': '(B)locked', 38410259SAndrew.Bardsley@arm.com '-': '(-)Bubble', 38510259SAndrew.Bardsley@arm.com '': '()Empty', 38610259SAndrew.Bardsley@arm.com 'E': '(E)mpty', 38710259SAndrew.Bardsley@arm.com 'R': '(R)eserved', 38810259SAndrew.Bardsley@arm.com 'X': '(X)Error', 38910259SAndrew.Bardsley@arm.com 'F': '(F)ault', 39010259SAndrew.Bardsley@arm.com 'r': '(r)ead', 39110259SAndrew.Bardsley@arm.com 'w': '(w)rite' 39210259SAndrew.Bardsley@arm.com } 39310259SAndrew.Bardsley@arm.com 39410259SAndrew.Bardsley@arm.comspecial_state_chars = special_state_colours.keys() 39510259SAndrew.Bardsley@arm.com 39610259SAndrew.Bardsley@arm.com# The complete set of available block data types 39710259SAndrew.Bardsley@arm.comdecoder_element_classes = { 39810259SAndrew.Bardsley@arm.com 'insts': Id, 39910259SAndrew.Bardsley@arm.com 'lines': Id, 40010259SAndrew.Bardsley@arm.com 'branch': Branch, 40110259SAndrew.Bardsley@arm.com 'dcache': DcacheAccess, 40210259SAndrew.Bardsley@arm.com 'counts': Counts 40310259SAndrew.Bardsley@arm.com } 40410259SAndrew.Bardsley@arm.com 40510259SAndrew.Bardsley@arm.comindexed_decoder_element_classes = { 40610259SAndrew.Bardsley@arm.com 'indexedCounts' : Counts 40710259SAndrew.Bardsley@arm.com } 40810259SAndrew.Bardsley@arm.com 40910259SAndrew.Bardsley@arm.comdef find_colour_decoder(stripSpace, decoderName, dataName, picPairs): 41010259SAndrew.Bardsley@arm.com """Make a colour decoder from some picture file blob attributes""" 41110259SAndrew.Bardsley@arm.com if decoderName == 'frame': 41210259SAndrew.Bardsley@arm.com return FrameColours.decoder(Counts, stripSpace, dataName) 41310259SAndrew.Bardsley@arm.com elif decoderName in decoder_element_classes: 41410259SAndrew.Bardsley@arm.com return TwoDColours.decoder(decoder_element_classes[decoderName], 41510259SAndrew.Bardsley@arm.com dataName) 41610259SAndrew.Bardsley@arm.com elif decoderName in indexed_decoder_element_classes: 41710259SAndrew.Bardsley@arm.com return TwoDColours.indexed_decoder( 41810259SAndrew.Bardsley@arm.com indexed_decoder_element_classes[decoderName], dataName, picPairs) 41910259SAndrew.Bardsley@arm.com else: 42010259SAndrew.Bardsley@arm.com return None 42110259SAndrew.Bardsley@arm.com 42210259SAndrew.Bardsley@arm.comclass IdedObj(object): 42310259SAndrew.Bardsley@arm.com """An object identified by an Id carrying paired data. 42410259SAndrew.Bardsley@arm.com The super class for Inst and Line""" 42510259SAndrew.Bardsley@arm.com 42610259SAndrew.Bardsley@arm.com def __init__(self, id, pairs={}): 42710259SAndrew.Bardsley@arm.com self.id = id 42810259SAndrew.Bardsley@arm.com self.pairs = pairs 42910259SAndrew.Bardsley@arm.com 43010259SAndrew.Bardsley@arm.com def __cmp__(self, right): 43110259SAndrew.Bardsley@arm.com return cmp(self.id, right.id) 43210259SAndrew.Bardsley@arm.com 43310259SAndrew.Bardsley@arm.com def table_line(self): 43410259SAndrew.Bardsley@arm.com """Represent the object as a list of table row data""" 43510259SAndrew.Bardsley@arm.com return [] 43610259SAndrew.Bardsley@arm.com 43710259SAndrew.Bardsley@arm.com # FIXME, add a table column titles? 43810259SAndrew.Bardsley@arm.com 43910259SAndrew.Bardsley@arm.com def __repr__(self): 44010259SAndrew.Bardsley@arm.com return ' '.join(self.table_line()) 44110259SAndrew.Bardsley@arm.com 44210259SAndrew.Bardsley@arm.comclass Inst(IdedObj): 44310259SAndrew.Bardsley@arm.com """A non-fault instruction""" 44410259SAndrew.Bardsley@arm.com def __init__(self, id, disassembly, addr, pairs={}): 44510259SAndrew.Bardsley@arm.com super(Inst,self).__init__(id, pairs) 44610259SAndrew.Bardsley@arm.com if 'nextAddr' in pairs: 44710259SAndrew.Bardsley@arm.com self.nextAddr = int(pairs['nextAddr'], 0) 44810259SAndrew.Bardsley@arm.com del pairs['nextAddr'] 44910259SAndrew.Bardsley@arm.com else: 45010259SAndrew.Bardsley@arm.com self.nextAddr = None 45110259SAndrew.Bardsley@arm.com self.disassembly = disassembly 45210259SAndrew.Bardsley@arm.com self.addr = addr 45310259SAndrew.Bardsley@arm.com 45410259SAndrew.Bardsley@arm.com def table_line(self): 45510259SAndrew.Bardsley@arm.com if self.nextAddr is not None: 45610259SAndrew.Bardsley@arm.com addrStr = '0x%x->0x%x' % (self.addr, self.nextAddr) 45710259SAndrew.Bardsley@arm.com else: 45810259SAndrew.Bardsley@arm.com addrStr = '0x%x' % self.addr 45910259SAndrew.Bardsley@arm.com ret = [addrStr, self.disassembly] 46010259SAndrew.Bardsley@arm.com for name, value in self.pairs.iteritems(): 46110259SAndrew.Bardsley@arm.com ret.append("%s=%s" % (name, str(value))) 46210259SAndrew.Bardsley@arm.com return ret 46310259SAndrew.Bardsley@arm.com 46410259SAndrew.Bardsley@arm.comclass InstFault(IdedObj): 46510259SAndrew.Bardsley@arm.com """A fault instruction""" 46610259SAndrew.Bardsley@arm.com def __init__(self, id, fault, addr, pairs={}): 46710259SAndrew.Bardsley@arm.com super(InstFault,self).__init__(id, pairs) 46810259SAndrew.Bardsley@arm.com self.fault = fault 46910259SAndrew.Bardsley@arm.com self.addr = addr 47010259SAndrew.Bardsley@arm.com 47110259SAndrew.Bardsley@arm.com def table_line(self): 47210259SAndrew.Bardsley@arm.com ret = ["0x%x" % self.addr, self.fault] 47310259SAndrew.Bardsley@arm.com for name, value in self.pairs: 47410259SAndrew.Bardsley@arm.com ret.append("%s=%s", name, str(value)) 47510259SAndrew.Bardsley@arm.com return ret 47610259SAndrew.Bardsley@arm.com 47710259SAndrew.Bardsley@arm.comclass Line(IdedObj): 47810259SAndrew.Bardsley@arm.com """A fetched line""" 47910259SAndrew.Bardsley@arm.com def __init__(self, id, vaddr, paddr, size, pairs={}): 48010259SAndrew.Bardsley@arm.com super(Line,self).__init__(id, pairs) 48110259SAndrew.Bardsley@arm.com self.vaddr = vaddr 48210259SAndrew.Bardsley@arm.com self.paddr = paddr 48310259SAndrew.Bardsley@arm.com self.size = size 48410259SAndrew.Bardsley@arm.com 48510259SAndrew.Bardsley@arm.com def table_line(self): 48610259SAndrew.Bardsley@arm.com ret = ["0x%x/0x%x" % (self.vaddr, self.paddr), "%d" % self.size] 48710259SAndrew.Bardsley@arm.com for name, value in self.pairs: 48810259SAndrew.Bardsley@arm.com ret.append("%s=%s", name, str(value)) 48910259SAndrew.Bardsley@arm.com return ret 49010259SAndrew.Bardsley@arm.com 49110259SAndrew.Bardsley@arm.comclass LineFault(IdedObj): 49210259SAndrew.Bardsley@arm.com """A faulting line""" 49310259SAndrew.Bardsley@arm.com def __init__(self, id, fault, vaddr, pairs={}): 49410259SAndrew.Bardsley@arm.com super(LineFault,self).__init__(id, pairs) 49510259SAndrew.Bardsley@arm.com self.vaddr = vaddr 49610259SAndrew.Bardsley@arm.com self.fault = fault 49710259SAndrew.Bardsley@arm.com 49810259SAndrew.Bardsley@arm.com def table_line(self): 49910259SAndrew.Bardsley@arm.com ret = ["0x%x" % self.vaddr, self.fault] 50010259SAndrew.Bardsley@arm.com for name, value in self.pairs: 50110259SAndrew.Bardsley@arm.com ret.append("%s=%s", name, str(value)) 50210259SAndrew.Bardsley@arm.com return ret 50310259SAndrew.Bardsley@arm.com 50410259SAndrew.Bardsley@arm.comclass BlobEvent(object): 50510259SAndrew.Bardsley@arm.com """Time event for a single blob""" 50610259SAndrew.Bardsley@arm.com def __init__(self, unit, time, pairs = {}): 50710259SAndrew.Bardsley@arm.com # blob's unit name 50810259SAndrew.Bardsley@arm.com self.unit = unit 50910259SAndrew.Bardsley@arm.com self.time = time 51010259SAndrew.Bardsley@arm.com # dict of picChar (blob name) to visual data 51110259SAndrew.Bardsley@arm.com self.visuals = {} 51210259SAndrew.Bardsley@arm.com # Miscellaneous unparsed MinorTrace line data 51310259SAndrew.Bardsley@arm.com self.pairs = pairs 51410259SAndrew.Bardsley@arm.com # Non-MinorTrace debug printout for this unit at this time 51510259SAndrew.Bardsley@arm.com self.comments = [] 51610259SAndrew.Bardsley@arm.com 51710259SAndrew.Bardsley@arm.com def find_ided_objects(self, model, picChar, includeInstLines): 51810259SAndrew.Bardsley@arm.com """Find instructions/lines mentioned in the blob's event 51910259SAndrew.Bardsley@arm.com data""" 52010259SAndrew.Bardsley@arm.com ret = [] 52110259SAndrew.Bardsley@arm.com if picChar in self.visuals: 52210259SAndrew.Bardsley@arm.com blocks = self.visuals[picChar].elems() 52310259SAndrew.Bardsley@arm.com def find_inst(data): 52410259SAndrew.Bardsley@arm.com instId = data.get_inst() 52510259SAndrew.Bardsley@arm.com lineId = data.get_line() 52610259SAndrew.Bardsley@arm.com if instId is not None: 52710259SAndrew.Bardsley@arm.com inst = model.find_inst(instId) 52810259SAndrew.Bardsley@arm.com line = model.find_line(instId) 52910259SAndrew.Bardsley@arm.com if inst is not None: 53010259SAndrew.Bardsley@arm.com ret.append(inst) 53110259SAndrew.Bardsley@arm.com if includeInstLines and line is not None: 53210259SAndrew.Bardsley@arm.com ret.append(line) 53310259SAndrew.Bardsley@arm.com elif lineId is not None: 53410259SAndrew.Bardsley@arm.com line = model.find_line(lineId) 53510259SAndrew.Bardsley@arm.com if line is not None: 53610259SAndrew.Bardsley@arm.com ret.append(line) 53710259SAndrew.Bardsley@arm.com map(find_inst, blocks) 53810259SAndrew.Bardsley@arm.com return sorted(ret) 53910259SAndrew.Bardsley@arm.com 54010259SAndrew.Bardsley@arm.comclass BlobModel(object): 54110259SAndrew.Bardsley@arm.com """Model bringing together blob definitions and parsed events""" 54210259SAndrew.Bardsley@arm.com def __init__(self, unitNamePrefix=''): 54310259SAndrew.Bardsley@arm.com self.blobs = [] 54410259SAndrew.Bardsley@arm.com self.unitNameToBlobs = {} 54510259SAndrew.Bardsley@arm.com self.unitEvents = {} 54610259SAndrew.Bardsley@arm.com self.clear_events() 54710259SAndrew.Bardsley@arm.com self.picSize = Point(20,10) 54810259SAndrew.Bardsley@arm.com self.lastTime = 0 54910259SAndrew.Bardsley@arm.com self.unitNamePrefix = unitNamePrefix 55010259SAndrew.Bardsley@arm.com 55110259SAndrew.Bardsley@arm.com def clear_events(self): 55210259SAndrew.Bardsley@arm.com """Drop all events and times""" 55310259SAndrew.Bardsley@arm.com self.lastTime = 0 55410259SAndrew.Bardsley@arm.com self.times = [] 55510259SAndrew.Bardsley@arm.com self.insts = {} 55610259SAndrew.Bardsley@arm.com self.lines = {} 55710259SAndrew.Bardsley@arm.com self.numEvents = 0 55810259SAndrew.Bardsley@arm.com 55910259SAndrew.Bardsley@arm.com for unit, events in self.unitEvents.iteritems(): 56010259SAndrew.Bardsley@arm.com self.unitEvents[unit] = [] 56110259SAndrew.Bardsley@arm.com 56210259SAndrew.Bardsley@arm.com def add_blob(self, blob): 56310259SAndrew.Bardsley@arm.com """Add a parsed blob to the model""" 56410259SAndrew.Bardsley@arm.com self.blobs.append(blob) 56510259SAndrew.Bardsley@arm.com if blob.unit not in self.unitNameToBlobs: 56610259SAndrew.Bardsley@arm.com self.unitNameToBlobs[blob.unit] = [] 56710259SAndrew.Bardsley@arm.com 56810259SAndrew.Bardsley@arm.com self.unitNameToBlobs[blob.unit].append(blob) 56910259SAndrew.Bardsley@arm.com 57010259SAndrew.Bardsley@arm.com def add_inst(self, inst): 57110259SAndrew.Bardsley@arm.com """Add a MinorInst instruction definition to the model""" 57210259SAndrew.Bardsley@arm.com # Is this a non micro-op instruction. Microops (usually) get their 57310259SAndrew.Bardsley@arm.com # fetchSeqNum == 0 varient stored first 57410259SAndrew.Bardsley@arm.com macroop_key = (inst.id.fetchSeqNum, 0) 57510259SAndrew.Bardsley@arm.com full_key = (inst.id.fetchSeqNum, inst.id.execSeqNum) 57610259SAndrew.Bardsley@arm.com 57710259SAndrew.Bardsley@arm.com if inst.id.execSeqNum != 0 and macroop_key not in self.insts: 57810259SAndrew.Bardsley@arm.com self.insts[macroop_key] = inst 57910259SAndrew.Bardsley@arm.com 58010259SAndrew.Bardsley@arm.com self.insts[full_key] = inst 58110259SAndrew.Bardsley@arm.com 58210259SAndrew.Bardsley@arm.com def find_inst(self, id): 58310259SAndrew.Bardsley@arm.com """Find an instruction either as a microop or macroop""" 58410259SAndrew.Bardsley@arm.com macroop_key = (id.fetchSeqNum, 0) 58510259SAndrew.Bardsley@arm.com full_key = (id.fetchSeqNum, id.execSeqNum) 58610259SAndrew.Bardsley@arm.com 58710259SAndrew.Bardsley@arm.com if full_key in self.insts: 58810259SAndrew.Bardsley@arm.com return self.insts[full_key] 58910259SAndrew.Bardsley@arm.com elif macroop_key in self.insts: 59010259SAndrew.Bardsley@arm.com return self.insts[macroop_key] 59110259SAndrew.Bardsley@arm.com else: 59210259SAndrew.Bardsley@arm.com return None 59310259SAndrew.Bardsley@arm.com 59410259SAndrew.Bardsley@arm.com def add_line(self, line): 59510259SAndrew.Bardsley@arm.com """Add a MinorLine line to the model""" 59610259SAndrew.Bardsley@arm.com self.lines[line.id.lineSeqNum] = line 59710259SAndrew.Bardsley@arm.com 59810259SAndrew.Bardsley@arm.com def add_unit_event(self, event): 59910259SAndrew.Bardsley@arm.com """Add a single event to the model. This must be an event at a 60010259SAndrew.Bardsley@arm.com time >= the current maximum time""" 60110259SAndrew.Bardsley@arm.com if event.unit in self.unitEvents: 60210259SAndrew.Bardsley@arm.com events = self.unitEvents[event.unit] 60310259SAndrew.Bardsley@arm.com if len(events) > 0 and events[len(events)-1].time > event.time: 60410259SAndrew.Bardsley@arm.com print "Bad event ordering" 60510259SAndrew.Bardsley@arm.com events.append(event) 60610259SAndrew.Bardsley@arm.com self.numEvents += 1 60710259SAndrew.Bardsley@arm.com self.lastTime = max(self.lastTime, event.time) 60810259SAndrew.Bardsley@arm.com 60910259SAndrew.Bardsley@arm.com def extract_times(self): 61010259SAndrew.Bardsley@arm.com """Extract a list of all the times from the seen events. Call after 61110259SAndrew.Bardsley@arm.com reading events to give a safe index list to use for time indices""" 61210259SAndrew.Bardsley@arm.com times = {} 61310259SAndrew.Bardsley@arm.com for unitEvents in self.unitEvents.itervalues(): 61410259SAndrew.Bardsley@arm.com for event in unitEvents: 61510259SAndrew.Bardsley@arm.com times[event.time] = 1 61610259SAndrew.Bardsley@arm.com self.times = times.keys() 61710259SAndrew.Bardsley@arm.com self.times.sort() 61810259SAndrew.Bardsley@arm.com 61910259SAndrew.Bardsley@arm.com def find_line(self, id): 62010259SAndrew.Bardsley@arm.com """Find a line by id""" 62110259SAndrew.Bardsley@arm.com key = id.lineSeqNum 62210259SAndrew.Bardsley@arm.com return self.lines.get(key, None) 62310259SAndrew.Bardsley@arm.com 62410259SAndrew.Bardsley@arm.com def find_event_bisection(self, unit, time, events, 62510259SAndrew.Bardsley@arm.com lower_index, upper_index): 62610259SAndrew.Bardsley@arm.com """Find an event by binary search on time indices""" 62710259SAndrew.Bardsley@arm.com while lower_index <= upper_index: 62810259SAndrew.Bardsley@arm.com pivot = (upper_index + lower_index) / 2 62910259SAndrew.Bardsley@arm.com pivotEvent = events[pivot] 63010259SAndrew.Bardsley@arm.com event_equal = (pivotEvent.time == time or 63110259SAndrew.Bardsley@arm.com (pivotEvent.time < time and 63210259SAndrew.Bardsley@arm.com (pivot == len(events) - 1 or 63310259SAndrew.Bardsley@arm.com events[pivot + 1].time > time))) 63410259SAndrew.Bardsley@arm.com 63510259SAndrew.Bardsley@arm.com if event_equal: 63610259SAndrew.Bardsley@arm.com return pivotEvent 63710259SAndrew.Bardsley@arm.com elif time > pivotEvent.time: 63810259SAndrew.Bardsley@arm.com if pivot == upper_index: 63910259SAndrew.Bardsley@arm.com return None 64010259SAndrew.Bardsley@arm.com else: 64110259SAndrew.Bardsley@arm.com lower_index = pivot + 1 64210259SAndrew.Bardsley@arm.com elif time < pivotEvent.time: 64310259SAndrew.Bardsley@arm.com if pivot == lower_index: 64410259SAndrew.Bardsley@arm.com return None 64510259SAndrew.Bardsley@arm.com else: 64610259SAndrew.Bardsley@arm.com upper_index = pivot - 1 64710259SAndrew.Bardsley@arm.com else: 64810259SAndrew.Bardsley@arm.com return None 64910259SAndrew.Bardsley@arm.com return None 65010259SAndrew.Bardsley@arm.com 65110259SAndrew.Bardsley@arm.com def find_unit_event_by_time(self, unit, time): 65210259SAndrew.Bardsley@arm.com """Find the last event for the given unit at time <= time""" 65310259SAndrew.Bardsley@arm.com if unit in self.unitEvents: 65410259SAndrew.Bardsley@arm.com events = self.unitEvents[unit] 65510259SAndrew.Bardsley@arm.com ret = self.find_event_bisection(unit, time, events, 65610259SAndrew.Bardsley@arm.com 0, len(events)-1) 65710259SAndrew.Bardsley@arm.com 65810259SAndrew.Bardsley@arm.com return ret 65910259SAndrew.Bardsley@arm.com else: 66010259SAndrew.Bardsley@arm.com return None 66110259SAndrew.Bardsley@arm.com 66210259SAndrew.Bardsley@arm.com def find_time_index(self, time): 66310259SAndrew.Bardsley@arm.com """Find a time index close to the given time (where 66410259SAndrew.Bardsley@arm.com times[return] <= time and times[return+1] > time""" 66510259SAndrew.Bardsley@arm.com ret = 0 66610259SAndrew.Bardsley@arm.com lastIndex = len(self.times) - 1 66710259SAndrew.Bardsley@arm.com while ret < lastIndex and self.times[ret + 1] <= time: 66810259SAndrew.Bardsley@arm.com ret += 1 66910259SAndrew.Bardsley@arm.com return ret 67010259SAndrew.Bardsley@arm.com 67110259SAndrew.Bardsley@arm.com def add_minor_inst(self, rest): 67210259SAndrew.Bardsley@arm.com """Parse and add a MinorInst line to the model""" 67310259SAndrew.Bardsley@arm.com pairs = parse.parse_pairs(rest) 67410259SAndrew.Bardsley@arm.com other_pairs = dict(pairs) 67510259SAndrew.Bardsley@arm.com 67610259SAndrew.Bardsley@arm.com id = Id().from_string(pairs['id']) 67710259SAndrew.Bardsley@arm.com del other_pairs['id'] 67810259SAndrew.Bardsley@arm.com 67910259SAndrew.Bardsley@arm.com addr = int(pairs['addr'], 0) 68010259SAndrew.Bardsley@arm.com del other_pairs['addr'] 68110259SAndrew.Bardsley@arm.com 68210259SAndrew.Bardsley@arm.com if 'inst' in other_pairs: 68310259SAndrew.Bardsley@arm.com del other_pairs['inst'] 68410259SAndrew.Bardsley@arm.com 68510259SAndrew.Bardsley@arm.com # Collapse unnecessary spaces in disassembly 68610259SAndrew.Bardsley@arm.com disassembly = re.sub(' *', ' ', 68710259SAndrew.Bardsley@arm.com re.sub('^ *', '', pairs['inst'])) 68810259SAndrew.Bardsley@arm.com 68910259SAndrew.Bardsley@arm.com inst = Inst(id, disassembly, addr, other_pairs) 69010259SAndrew.Bardsley@arm.com self.add_inst(inst) 69110259SAndrew.Bardsley@arm.com elif 'fault' in other_pairs: 69210259SAndrew.Bardsley@arm.com del other_pairs['fault'] 69310259SAndrew.Bardsley@arm.com 69410259SAndrew.Bardsley@arm.com inst = InstFault(id, pairs['fault'], addr, other_pairs) 69510259SAndrew.Bardsley@arm.com 69610259SAndrew.Bardsley@arm.com self.add_inst(inst) 69710259SAndrew.Bardsley@arm.com 69810259SAndrew.Bardsley@arm.com def add_minor_line(self, rest): 69910259SAndrew.Bardsley@arm.com """Parse and add a MinorLine line to the model""" 70010259SAndrew.Bardsley@arm.com pairs = parse.parse_pairs(rest) 70110259SAndrew.Bardsley@arm.com other_pairs = dict(pairs) 70210259SAndrew.Bardsley@arm.com 70310259SAndrew.Bardsley@arm.com id = Id().from_string(pairs['id']) 70410259SAndrew.Bardsley@arm.com del other_pairs['id'] 70510259SAndrew.Bardsley@arm.com 70610259SAndrew.Bardsley@arm.com vaddr = int(pairs['vaddr'], 0) 70710259SAndrew.Bardsley@arm.com del other_pairs['vaddr'] 70810259SAndrew.Bardsley@arm.com 70910259SAndrew.Bardsley@arm.com if 'paddr' in other_pairs: 71010259SAndrew.Bardsley@arm.com del other_pairs['paddr'] 71110259SAndrew.Bardsley@arm.com del other_pairs['size'] 71210259SAndrew.Bardsley@arm.com paddr = int(pairs['paddr'], 0) 71310259SAndrew.Bardsley@arm.com size = int(pairs['size'], 0) 71410259SAndrew.Bardsley@arm.com 71510259SAndrew.Bardsley@arm.com self.add_line(Line(id, 71610259SAndrew.Bardsley@arm.com vaddr, paddr, size, other_pairs)) 71710259SAndrew.Bardsley@arm.com elif 'fault' in other_pairs: 71810259SAndrew.Bardsley@arm.com del other_pairs['fault'] 71910259SAndrew.Bardsley@arm.com 72010259SAndrew.Bardsley@arm.com self.add_line(LineFault(id, pairs['fault'], vaddr, other_pairs)) 72110259SAndrew.Bardsley@arm.com 72210259SAndrew.Bardsley@arm.com def load_events(self, file, startTime=0, endTime=None): 72310259SAndrew.Bardsley@arm.com """Load an event file and add everything to this model""" 72410259SAndrew.Bardsley@arm.com def update_comments(comments, time): 72510259SAndrew.Bardsley@arm.com # Add a list of comments to an existing event, if there is one at 72610259SAndrew.Bardsley@arm.com # the given time, or create a new, correctly-timed, event from 72710259SAndrew.Bardsley@arm.com # the last event and attach the comments to that 72810259SAndrew.Bardsley@arm.com for commentUnit, commentRest in comments: 72910259SAndrew.Bardsley@arm.com event = self.find_unit_event_by_time(commentUnit, time) 73010259SAndrew.Bardsley@arm.com # Find an event to which this comment can be attached 73110259SAndrew.Bardsley@arm.com if event is None: 73210259SAndrew.Bardsley@arm.com # No older event, make a new empty one 73310259SAndrew.Bardsley@arm.com event = BlobEvent(commentUnit, time, {}) 73410259SAndrew.Bardsley@arm.com self.add_unit_event(event) 73510259SAndrew.Bardsley@arm.com elif event.time != time: 73610259SAndrew.Bardsley@arm.com # Copy the old event and make a new one with the right 73710259SAndrew.Bardsley@arm.com # time and comment 73810259SAndrew.Bardsley@arm.com newEvent = BlobEvent(commentUnit, time, event.pairs) 73910259SAndrew.Bardsley@arm.com newEvent.visuals = dict(event.visuals) 74010259SAndrew.Bardsley@arm.com event = newEvent 74110259SAndrew.Bardsley@arm.com self.add_unit_event(event) 74210259SAndrew.Bardsley@arm.com event.comments.append(commentRest) 74310259SAndrew.Bardsley@arm.com 74410259SAndrew.Bardsley@arm.com self.clear_events() 74510259SAndrew.Bardsley@arm.com 74610259SAndrew.Bardsley@arm.com # A negative time will *always* be different from an event time 74710259SAndrew.Bardsley@arm.com time = -1 74810259SAndrew.Bardsley@arm.com time_events = {} 74910259SAndrew.Bardsley@arm.com last_time_lines = {} 75010259SAndrew.Bardsley@arm.com minor_trace_line_count = 0 75110259SAndrew.Bardsley@arm.com comments = [] 75210259SAndrew.Bardsley@arm.com 75310259SAndrew.Bardsley@arm.com default_colour = [[colours.unknownColour]] 75410259SAndrew.Bardsley@arm.com next_progress_print_event_count = 1000 75510259SAndrew.Bardsley@arm.com 75610259SAndrew.Bardsley@arm.com if not os.access(file, os.R_OK): 75710259SAndrew.Bardsley@arm.com print 'Can\'t open file', file 75810259SAndrew.Bardsley@arm.com exit(1) 75910259SAndrew.Bardsley@arm.com else: 76010259SAndrew.Bardsley@arm.com print 'Opening file', file 76110259SAndrew.Bardsley@arm.com 76210259SAndrew.Bardsley@arm.com f = open(file) 76310259SAndrew.Bardsley@arm.com 76410259SAndrew.Bardsley@arm.com start_wall_time = wall_time() 76510259SAndrew.Bardsley@arm.com 76610259SAndrew.Bardsley@arm.com # Skip leading events 76710259SAndrew.Bardsley@arm.com still_skipping = True 76810259SAndrew.Bardsley@arm.com l = f.readline() 76910259SAndrew.Bardsley@arm.com while l and still_skipping: 77010259SAndrew.Bardsley@arm.com match = re.match('^\s*(\d+):', l) 77110259SAndrew.Bardsley@arm.com if match is not None: 77210259SAndrew.Bardsley@arm.com event_time = match.groups() 77310259SAndrew.Bardsley@arm.com if int(event_time[0]) >= startTime: 77410259SAndrew.Bardsley@arm.com still_skipping = False 77510259SAndrew.Bardsley@arm.com else: 77610259SAndrew.Bardsley@arm.com l = f.readline() 77710259SAndrew.Bardsley@arm.com else: 77810259SAndrew.Bardsley@arm.com l = f.readline() 77910259SAndrew.Bardsley@arm.com 78010259SAndrew.Bardsley@arm.com match_line_re = re.compile( 78110259SAndrew.Bardsley@arm.com '^\s*(\d+):\s*([\w\.]+):\s*(Minor\w+:)?\s*(.*)$') 78210259SAndrew.Bardsley@arm.com 78310259SAndrew.Bardsley@arm.com # Parse each line of the events file, accumulating comments to be 78410259SAndrew.Bardsley@arm.com # attached to MinorTrace events when the time changes 78510259SAndrew.Bardsley@arm.com reached_end_time = False 78610259SAndrew.Bardsley@arm.com while not reached_end_time and l: 78710259SAndrew.Bardsley@arm.com match = match_line_re.match(l) 78810259SAndrew.Bardsley@arm.com if match is not None: 78910259SAndrew.Bardsley@arm.com event_time, unit, line_type, rest = match.groups() 79010259SAndrew.Bardsley@arm.com event_time = int(event_time) 79110259SAndrew.Bardsley@arm.com 79210259SAndrew.Bardsley@arm.com unit = re.sub('^' + self.unitNamePrefix + '\.?(.*)$', 79310259SAndrew.Bardsley@arm.com '\\1', unit) 79410259SAndrew.Bardsley@arm.com 79510259SAndrew.Bardsley@arm.com # When the time changes, resolve comments 79610259SAndrew.Bardsley@arm.com if event_time != time: 79710259SAndrew.Bardsley@arm.com if self.numEvents > next_progress_print_event_count: 79810259SAndrew.Bardsley@arm.com print ('Parsed to time: %d' % event_time) 79910259SAndrew.Bardsley@arm.com next_progress_print_event_count = ( 80010259SAndrew.Bardsley@arm.com self.numEvents + 1000) 80110259SAndrew.Bardsley@arm.com update_comments(comments, time) 80210259SAndrew.Bardsley@arm.com comments = [] 80310259SAndrew.Bardsley@arm.com time = event_time 80410259SAndrew.Bardsley@arm.com 80510259SAndrew.Bardsley@arm.com if line_type is None: 80610259SAndrew.Bardsley@arm.com # Treat this line as just a 'comment' 80710259SAndrew.Bardsley@arm.com comments.append((unit, rest)) 80810259SAndrew.Bardsley@arm.com elif line_type == 'MinorTrace:': 80910259SAndrew.Bardsley@arm.com minor_trace_line_count += 1 81010259SAndrew.Bardsley@arm.com 81110259SAndrew.Bardsley@arm.com # Only insert this event if it's not the same as 81210259SAndrew.Bardsley@arm.com # the last event we saw for this unit 81310259SAndrew.Bardsley@arm.com if last_time_lines.get(unit, None) != rest: 81410259SAndrew.Bardsley@arm.com event = BlobEvent(unit, event_time, {}) 81510259SAndrew.Bardsley@arm.com pairs = parse.parse_pairs(rest) 81610259SAndrew.Bardsley@arm.com event.pairs = pairs 81710259SAndrew.Bardsley@arm.com 81810259SAndrew.Bardsley@arm.com # Try to decode the colour data for this event 81910259SAndrew.Bardsley@arm.com blobs = self.unitNameToBlobs.get(unit, []) 82010259SAndrew.Bardsley@arm.com for blob in blobs: 82110259SAndrew.Bardsley@arm.com if blob.visualDecoder is not None: 82210259SAndrew.Bardsley@arm.com event.visuals[blob.picChar] = ( 82310259SAndrew.Bardsley@arm.com blob.visualDecoder(pairs)) 82410259SAndrew.Bardsley@arm.com 82510259SAndrew.Bardsley@arm.com self.add_unit_event(event) 82610259SAndrew.Bardsley@arm.com last_time_lines[unit] = rest 82710259SAndrew.Bardsley@arm.com elif line_type == 'MinorInst:': 82810259SAndrew.Bardsley@arm.com self.add_minor_inst(rest) 82910259SAndrew.Bardsley@arm.com elif line_type == 'MinorLine:': 83010259SAndrew.Bardsley@arm.com self.add_minor_line(rest) 83110259SAndrew.Bardsley@arm.com 83210259SAndrew.Bardsley@arm.com if endTime is not None and time > endTime: 83310259SAndrew.Bardsley@arm.com reached_end_time = True 83410259SAndrew.Bardsley@arm.com 83510259SAndrew.Bardsley@arm.com l = f.readline() 83610259SAndrew.Bardsley@arm.com 83710259SAndrew.Bardsley@arm.com update_comments(comments, time) 83810259SAndrew.Bardsley@arm.com self.extract_times() 83910259SAndrew.Bardsley@arm.com f.close() 84010259SAndrew.Bardsley@arm.com 84110259SAndrew.Bardsley@arm.com end_wall_time = wall_time() 84210259SAndrew.Bardsley@arm.com 84310259SAndrew.Bardsley@arm.com print 'Total events:', minor_trace_line_count, 'unique events:', \ 84410259SAndrew.Bardsley@arm.com self.numEvents 84510259SAndrew.Bardsley@arm.com print 'Time to parse:', end_wall_time - start_wall_time 84610259SAndrew.Bardsley@arm.com 84710259SAndrew.Bardsley@arm.com def add_blob_picture(self, offset, pic, nameDict): 84810259SAndrew.Bardsley@arm.com """Add a parsed ASCII-art pipeline markup to the model""" 84910259SAndrew.Bardsley@arm.com pic_width = 0 85010259SAndrew.Bardsley@arm.com for line in pic: 85110259SAndrew.Bardsley@arm.com pic_width = max(pic_width, len(line)) 85210259SAndrew.Bardsley@arm.com pic_height = len(pic) 85310259SAndrew.Bardsley@arm.com 85410259SAndrew.Bardsley@arm.com # Number of horizontal characters per 'pixel'. Should be 2 85510259SAndrew.Bardsley@arm.com charsPerPixel = 2 85610259SAndrew.Bardsley@arm.com 85710259SAndrew.Bardsley@arm.com # Clean up pic_width to a multiple of charsPerPixel 85810259SAndrew.Bardsley@arm.com pic_width = (pic_width + charsPerPixel - 1) // 2 85910259SAndrew.Bardsley@arm.com 86010259SAndrew.Bardsley@arm.com self.picSize = Point(pic_width, pic_height) 86110259SAndrew.Bardsley@arm.com 86210259SAndrew.Bardsley@arm.com def pic_at(point): 86310259SAndrew.Bardsley@arm.com """Return the char pair at the given point. 86410259SAndrew.Bardsley@arm.com Returns None for characters off the picture""" 86510259SAndrew.Bardsley@arm.com x, y = point.to_pair() 86610259SAndrew.Bardsley@arm.com x *= 2 86710259SAndrew.Bardsley@arm.com if y >= len(pic) or x >= len(pic[y]): 86810259SAndrew.Bardsley@arm.com return None 86910259SAndrew.Bardsley@arm.com else: 87010259SAndrew.Bardsley@arm.com return pic[y][x:x + charsPerPixel] 87110259SAndrew.Bardsley@arm.com 87210259SAndrew.Bardsley@arm.com def clear_pic_at(point): 87310259SAndrew.Bardsley@arm.com """Clear the chars at point so we don't trip over them again""" 87410259SAndrew.Bardsley@arm.com line = pic[point.y] 87510259SAndrew.Bardsley@arm.com x = point.x * charsPerPixel 87610259SAndrew.Bardsley@arm.com pic[point.y] = line[0:x] + (' ' * charsPerPixel) + \ 87710259SAndrew.Bardsley@arm.com line[x + charsPerPixel:] 87810259SAndrew.Bardsley@arm.com 87910259SAndrew.Bardsley@arm.com def skip_same_char(start, increment): 88010259SAndrew.Bardsley@arm.com """Skip characters which match pic_at(start)""" 88110259SAndrew.Bardsley@arm.com char = pic_at(start) 88210259SAndrew.Bardsley@arm.com hunt = start 88310259SAndrew.Bardsley@arm.com while pic_at(hunt) == char: 88410259SAndrew.Bardsley@arm.com hunt += increment 88510259SAndrew.Bardsley@arm.com return hunt 88610259SAndrew.Bardsley@arm.com 88710259SAndrew.Bardsley@arm.com def find_size(start): 88810259SAndrew.Bardsley@arm.com """Find the size of a rectangle with top left hand corner at 88910259SAndrew.Bardsley@arm.com start consisting of (at least) a -. shaped corner describing 89010259SAndrew.Bardsley@arm.com the top right corner of a rectangle of the same char""" 89110259SAndrew.Bardsley@arm.com char = pic_at(start) 89210259SAndrew.Bardsley@arm.com hunt_x = skip_same_char(start, Point(1,0)) 89310259SAndrew.Bardsley@arm.com hunt_y = skip_same_char(start, Point(0,1)) 89410259SAndrew.Bardsley@arm.com off_bottom_right = (hunt_x * Point(1,0)) + (hunt_y * Point(0,1)) 89510259SAndrew.Bardsley@arm.com return off_bottom_right - start 89610259SAndrew.Bardsley@arm.com 89710259SAndrew.Bardsley@arm.com def point_return(point): 89810259SAndrew.Bardsley@arm.com """Carriage return, line feed""" 89910259SAndrew.Bardsley@arm.com return Point(0, point.y + 1) 90010259SAndrew.Bardsley@arm.com 90110259SAndrew.Bardsley@arm.com def find_arrow(start): 90210259SAndrew.Bardsley@arm.com """Find a simple 1-char wide arrow""" 90310259SAndrew.Bardsley@arm.com 90410259SAndrew.Bardsley@arm.com def body(endChar, contChar, direc): 90510259SAndrew.Bardsley@arm.com arrow_point = start 90610259SAndrew.Bardsley@arm.com arrow_point += Point(0, 1) 90710259SAndrew.Bardsley@arm.com clear_pic_at(start) 90810259SAndrew.Bardsley@arm.com while pic_at(arrow_point) == contChar: 90910259SAndrew.Bardsley@arm.com clear_pic_at(arrow_point) 91010259SAndrew.Bardsley@arm.com arrow_point += Point(0, 1) 91110259SAndrew.Bardsley@arm.com 91210259SAndrew.Bardsley@arm.com if pic_at(arrow_point) == endChar: 91310259SAndrew.Bardsley@arm.com clear_pic_at(arrow_point) 91410259SAndrew.Bardsley@arm.com self.add_blob(blobs.Arrow('_', start + offset, 91510259SAndrew.Bardsley@arm.com direc = direc, 91610259SAndrew.Bardsley@arm.com size = (Point(1, 1) + arrow_point - start))) 91710259SAndrew.Bardsley@arm.com else: 91810259SAndrew.Bardsley@arm.com print 'Bad arrow', start 91910259SAndrew.Bardsley@arm.com 92010259SAndrew.Bardsley@arm.com char = pic_at(start) 92110259SAndrew.Bardsley@arm.com if char == '-\\': 92210259SAndrew.Bardsley@arm.com body('-/', ' :', 'right') 92310259SAndrew.Bardsley@arm.com elif char == '/-': 92410259SAndrew.Bardsley@arm.com body('\\-', ': ', 'left') 92510259SAndrew.Bardsley@arm.com 92610259SAndrew.Bardsley@arm.com blank_chars = [' ', ' :', ': '] 92710259SAndrew.Bardsley@arm.com 92810259SAndrew.Bardsley@arm.com # Traverse the picture left to right, top to bottom to find blobs 92910259SAndrew.Bardsley@arm.com seen_dict = {} 93010259SAndrew.Bardsley@arm.com point = Point(0,0) 93110259SAndrew.Bardsley@arm.com while pic_at(point) is not None: 93210259SAndrew.Bardsley@arm.com while pic_at(point) is not None: 93310259SAndrew.Bardsley@arm.com char = pic_at(point) 93410259SAndrew.Bardsley@arm.com if char == '->': 93510259SAndrew.Bardsley@arm.com self.add_blob(blobs.Arrow('_', point + offset, 93610259SAndrew.Bardsley@arm.com direc = 'right')) 93710259SAndrew.Bardsley@arm.com elif char == '<-': 93810259SAndrew.Bardsley@arm.com self.add_blob(blobs.Arrow('_', point + offset, 93910259SAndrew.Bardsley@arm.com direc = 'left')) 94010259SAndrew.Bardsley@arm.com elif char == '-\\' or char == '/-': 94110259SAndrew.Bardsley@arm.com find_arrow(point) 94210259SAndrew.Bardsley@arm.com elif char in blank_chars: 94310259SAndrew.Bardsley@arm.com pass 94410259SAndrew.Bardsley@arm.com else: 94510259SAndrew.Bardsley@arm.com if char not in seen_dict: 94610259SAndrew.Bardsley@arm.com size = find_size(point) 94710259SAndrew.Bardsley@arm.com topLeft = point + offset 94810259SAndrew.Bardsley@arm.com if char not in nameDict: 94910259SAndrew.Bardsley@arm.com # Unnamed blobs 95010259SAndrew.Bardsley@arm.com self.add_blob(blobs.Block(char, 95110259SAndrew.Bardsley@arm.com nameDict.get(char, '_'), 95210259SAndrew.Bardsley@arm.com topLeft, size = size)) 95310259SAndrew.Bardsley@arm.com else: 95410259SAndrew.Bardsley@arm.com # Named blobs, set visual info. 95510259SAndrew.Bardsley@arm.com blob = nameDict[char] 95610259SAndrew.Bardsley@arm.com blob.size = size 95710259SAndrew.Bardsley@arm.com blob.topLeft = topLeft 95810259SAndrew.Bardsley@arm.com self.add_blob(blob) 95910259SAndrew.Bardsley@arm.com seen_dict[char] = True 96010259SAndrew.Bardsley@arm.com point = skip_same_char(point, Point(1,0)) 96110259SAndrew.Bardsley@arm.com point = point_return(point) 96210259SAndrew.Bardsley@arm.com 96310259SAndrew.Bardsley@arm.com def load_picture(self, filename): 96410259SAndrew.Bardsley@arm.com """Load a picture file into the model""" 96510259SAndrew.Bardsley@arm.com def parse_blob_description(char, unit, macros, pairsList): 96610259SAndrew.Bardsley@arm.com # Parse the name value pairs in a blob-describing line 96710259SAndrew.Bardsley@arm.com def expand_macros(pairs, newPairs): 96810259SAndrew.Bardsley@arm.com # Recursively expand macros 96910259SAndrew.Bardsley@arm.com for name, value in newPairs: 97010259SAndrew.Bardsley@arm.com if name in macros: 97110259SAndrew.Bardsley@arm.com expand_macros(pairs, macros[name]) 97210259SAndrew.Bardsley@arm.com else: 97310259SAndrew.Bardsley@arm.com pairs[name] = value 97410259SAndrew.Bardsley@arm.com return pairs 97510259SAndrew.Bardsley@arm.com 97610259SAndrew.Bardsley@arm.com pairs = expand_macros({}, pairsList) 97710259SAndrew.Bardsley@arm.com 97810259SAndrew.Bardsley@arm.com ret = None 97910259SAndrew.Bardsley@arm.com 98010259SAndrew.Bardsley@arm.com typ = pairs.get('type', 'block') 98110259SAndrew.Bardsley@arm.com colour = colours.name_to_colour(pairs.get('colour', 'black')) 98210259SAndrew.Bardsley@arm.com 98310259SAndrew.Bardsley@arm.com if typ == 'key': 98410259SAndrew.Bardsley@arm.com ret = blobs.Key(char, unit, Point(0,0), colour) 98510259SAndrew.Bardsley@arm.com elif typ == 'block': 98610259SAndrew.Bardsley@arm.com ret = blobs.Block(char, unit, Point(0,0), colour) 98710259SAndrew.Bardsley@arm.com else: 98810259SAndrew.Bardsley@arm.com print "Bad picture blog type:", typ 98910259SAndrew.Bardsley@arm.com 99010259SAndrew.Bardsley@arm.com if 'hideId' in pairs: 99110259SAndrew.Bardsley@arm.com hide = pairs['hideId'] 99210259SAndrew.Bardsley@arm.com ret.dataSelect.ids -= set(hide) 99310259SAndrew.Bardsley@arm.com 99410259SAndrew.Bardsley@arm.com if typ == 'block': 99510259SAndrew.Bardsley@arm.com ret.displayName = pairs.get('name', unit) 99610259SAndrew.Bardsley@arm.com ret.nameLoc = pairs.get('nameLoc', 'top') 99710259SAndrew.Bardsley@arm.com ret.shape = pairs.get('shape', 'box') 99810259SAndrew.Bardsley@arm.com ret.stripDir = pairs.get('stripDir', 'horiz') 99910259SAndrew.Bardsley@arm.com ret.stripOrd = pairs.get('stripOrd', 'LR') 100010259SAndrew.Bardsley@arm.com ret.blankStrips = int(pairs.get('blankStrips', '0')) 100110259SAndrew.Bardsley@arm.com ret.shorten = int(pairs.get('shorten', '0')) 100210259SAndrew.Bardsley@arm.com 100310259SAndrew.Bardsley@arm.com if 'decoder' in pairs: 100410259SAndrew.Bardsley@arm.com decoderName = pairs['decoder'] 100510259SAndrew.Bardsley@arm.com dataElement = pairs.get('dataElement', decoderName) 100610259SAndrew.Bardsley@arm.com 100710259SAndrew.Bardsley@arm.com decoder = find_colour_decoder(ret.blankStrips, 100810259SAndrew.Bardsley@arm.com decoderName, dataElement, pairs) 100910259SAndrew.Bardsley@arm.com if decoder is not None: 101010259SAndrew.Bardsley@arm.com ret.visualDecoder = decoder 101110259SAndrew.Bardsley@arm.com else: 101210259SAndrew.Bardsley@arm.com print 'Bad visualDecoder requested:', decoderName 101310259SAndrew.Bardsley@arm.com 101410259SAndrew.Bardsley@arm.com if 'border' in pairs: 101510259SAndrew.Bardsley@arm.com border = pairs['border'] 101610259SAndrew.Bardsley@arm.com if border == 'thin': 101710259SAndrew.Bardsley@arm.com ret.border = 0.2 101810259SAndrew.Bardsley@arm.com elif border == 'mid': 101910259SAndrew.Bardsley@arm.com ret.border = 0.5 102010259SAndrew.Bardsley@arm.com else: 102110259SAndrew.Bardsley@arm.com ret.border = 1.0 102210259SAndrew.Bardsley@arm.com elif typ == 'key': 102310259SAndrew.Bardsley@arm.com ret.colours = pairs.get('colours', ret.colours) 102410259SAndrew.Bardsley@arm.com 102510259SAndrew.Bardsley@arm.com return ret 102610259SAndrew.Bardsley@arm.com 102710259SAndrew.Bardsley@arm.com def line_is_comment(line): 102810259SAndrew.Bardsley@arm.com """Returns true if a line starts with #, returns False 102910259SAndrew.Bardsley@arm.com for lines which are None""" 103010259SAndrew.Bardsley@arm.com return line is not None \ 103110259SAndrew.Bardsley@arm.com and re.match('^\s*#', line) is not None 103210259SAndrew.Bardsley@arm.com 103310259SAndrew.Bardsley@arm.com def get_line(f): 103410259SAndrew.Bardsley@arm.com """Get a line from file f extending that line if it ends in 103510259SAndrew.Bardsley@arm.com '\' and dropping lines that start with '#'s""" 103610259SAndrew.Bardsley@arm.com ret = f.readline() 103710259SAndrew.Bardsley@arm.com 103810259SAndrew.Bardsley@arm.com # Discard comment lines 103910259SAndrew.Bardsley@arm.com while line_is_comment(ret): 104010259SAndrew.Bardsley@arm.com ret = f.readline() 104110259SAndrew.Bardsley@arm.com 104210259SAndrew.Bardsley@arm.com if ret is not None: 104310259SAndrew.Bardsley@arm.com extend_match = re.match('^(.*)\\\\$', ret) 104410259SAndrew.Bardsley@arm.com 104510259SAndrew.Bardsley@arm.com while extend_match is not None: 104610259SAndrew.Bardsley@arm.com new_line = f.readline() 104710259SAndrew.Bardsley@arm.com 104810259SAndrew.Bardsley@arm.com if new_line is not None and not line_is_comment(new_line): 104910259SAndrew.Bardsley@arm.com line_wo_backslash, = extend_match.groups() 105010259SAndrew.Bardsley@arm.com ret = line_wo_backslash + new_line 105110259SAndrew.Bardsley@arm.com extend_match = re.match('^(.*)\\\\$', ret) 105210259SAndrew.Bardsley@arm.com else: 105310259SAndrew.Bardsley@arm.com extend_match = None 105410259SAndrew.Bardsley@arm.com 105510259SAndrew.Bardsley@arm.com return ret 105610259SAndrew.Bardsley@arm.com 105710259SAndrew.Bardsley@arm.com # Macros are recursively expanded into name=value pairs 105810259SAndrew.Bardsley@arm.com macros = {} 105910259SAndrew.Bardsley@arm.com 106010259SAndrew.Bardsley@arm.com if not os.access(filename, os.R_OK): 106110259SAndrew.Bardsley@arm.com print 'Can\'t open file', filename 106210259SAndrew.Bardsley@arm.com exit(1) 106310259SAndrew.Bardsley@arm.com else: 106410259SAndrew.Bardsley@arm.com print 'Opening file', filename 106510259SAndrew.Bardsley@arm.com 106610259SAndrew.Bardsley@arm.com f = open(filename) 106710259SAndrew.Bardsley@arm.com l = get_line(f) 106810259SAndrew.Bardsley@arm.com picture = [] 106910259SAndrew.Bardsley@arm.com blob_char_dict = {} 107010259SAndrew.Bardsley@arm.com 107110259SAndrew.Bardsley@arm.com self.unitEvents = {} 107210259SAndrew.Bardsley@arm.com self.clear_events() 107310259SAndrew.Bardsley@arm.com 107410259SAndrew.Bardsley@arm.com # Actually parse the file 107510259SAndrew.Bardsley@arm.com in_picture = False 107610259SAndrew.Bardsley@arm.com while l: 107710259SAndrew.Bardsley@arm.com l = parse.remove_trailing_ws(l) 107810259SAndrew.Bardsley@arm.com l = re.sub('#.*', '', l) 107910259SAndrew.Bardsley@arm.com 108010259SAndrew.Bardsley@arm.com if re.match("^\s*$", l) is not None: 108110259SAndrew.Bardsley@arm.com pass 108210259SAndrew.Bardsley@arm.com elif l == '<<<': 108310259SAndrew.Bardsley@arm.com in_picture = True 108410259SAndrew.Bardsley@arm.com elif l == '>>>': 108510259SAndrew.Bardsley@arm.com in_picture = False 108610259SAndrew.Bardsley@arm.com elif in_picture: 108710259SAndrew.Bardsley@arm.com picture.append(re.sub('\s*$', '', l)) 108810259SAndrew.Bardsley@arm.com else: 108910259SAndrew.Bardsley@arm.com line_match = re.match( 109010259SAndrew.Bardsley@arm.com '^([a-zA-Z0-9][a-zA-Z0-9]):\s+([\w.]+)\s*(.*)', l) 109110259SAndrew.Bardsley@arm.com macro_match = re.match('macro\s+(\w+):(.*)', l) 109210259SAndrew.Bardsley@arm.com 109310259SAndrew.Bardsley@arm.com if macro_match is not None: 109410259SAndrew.Bardsley@arm.com name, defn = macro_match.groups() 109510259SAndrew.Bardsley@arm.com macros[name] = parse.parse_pairs_list(defn) 109610259SAndrew.Bardsley@arm.com elif line_match is not None: 109710259SAndrew.Bardsley@arm.com char, unit, pairs = line_match.groups() 109810259SAndrew.Bardsley@arm.com blob = parse_blob_description(char, unit, macros, 109910259SAndrew.Bardsley@arm.com parse.parse_pairs_list(pairs)) 110010259SAndrew.Bardsley@arm.com blob_char_dict[char] = blob 110110259SAndrew.Bardsley@arm.com # Setup the events structure 110210259SAndrew.Bardsley@arm.com self.unitEvents[unit] = [] 110310259SAndrew.Bardsley@arm.com else: 110410259SAndrew.Bardsley@arm.com print 'Problem with Blob line:', l 110510259SAndrew.Bardsley@arm.com 110610259SAndrew.Bardsley@arm.com l = get_line(f) 110710259SAndrew.Bardsley@arm.com 110810259SAndrew.Bardsley@arm.com self.blobs = [] 110910259SAndrew.Bardsley@arm.com self.add_blob_picture(Point(0,1), picture, blob_char_dict) 1110