11# SPDX-License-Identifier: MIT
22
3- import textwrap
3+ import textwrap , os . path , json , datetime
44from .asc import *
55from ..hw .uat import UAT , MemoryAttr , PTE , Page_PTE , TTBR
66from ..hw .agx import *
@@ -211,13 +211,15 @@ class FWCtlChannelTracer(ChannelTracer):
211211 RPTR = 0x00
212212
213213class CommandQueueTracer (Reloadable ):
214- def __init__ (self , tracer , info_addr , new_queue ):
214+ def __init__ (self , tracer , info_addr , new_queue , queue_type ):
215215 self .tracer = tracer
216216 self .uat = tracer .uat
217217 self .hv = tracer .hv
218218 self .u = self .hv .u
219219 self .verbose = False
220220 self .info_addr = info_addr
221+ self .dumpfile = None
222+ self .queue_type = queue_type
221223
222224 if info_addr not in tracer .state .queues :
223225 self .state = CommandQueueState ()
@@ -230,6 +232,20 @@ def __init__(self, tracer, info_addr, new_queue):
230232 if new_queue :
231233 self .state .rptr = 0
232234
235+ if tracer .cmd_dump_dir :
236+ qtype = ["TA" , "3D" , "CP" ][queue_type ]
237+ fname = f"{ datetime .datetime .now ().isoformat ()} -{ tracer .state .queue_seq :04d} -{ qtype } .json"
238+ self .dumpfile = open (os .path .join (tracer .cmd_dump_dir , fname ), "w" )
239+ json .dump ({
240+ "compatible" : tracer .dev_sgx .compatible ,
241+ "chip_id" : tracer .chip_id ,
242+ "version" : Ver ._version ,
243+ "type" : qtype ,
244+ }, self .dumpfile )
245+ self .dumpfile .write ("\n " )
246+ self .dumpfile .flush ()
247+ tracer .state .queue_seq += 1
248+
233249 self .update_info ()
234250
235251 def update_info (self ):
@@ -242,6 +258,10 @@ def log(self, msg):
242258 def rb_size (self ):
243259 return self .info .pointers .rb_size
244260
261+ def json_default (self , val ):
262+ print (repr (val ))
263+ return None
264+
245265 def get_workitems (self , workmsg ):
246266 self .tracer .uat .invalidate_cache ()
247267 self .update_info ()
@@ -268,7 +288,12 @@ def get_workitems(self, workmsg):
268288 self .log (f"WI item @{ rptr :#x} : { pointer :#x} " )
269289 if pointer :
270290 stream .seek (pointer , 0 )
271- yield CmdBufWork .parse_stream (stream )
291+ wi = CmdBufWork .parse_stream (stream )
292+ if self .dumpfile :
293+ json .dump (wi , self .dumpfile , default = self .json_default )
294+ self .dumpfile .write ("\n " )
295+ self .dumpfile .flush ()
296+ yield wi
272297 rptr = (rptr + 1 ) % self .rb_size
273298
274299 self .state .rptr = rptr
@@ -348,6 +373,7 @@ def __init__(self, hv, devpath, verbose=False):
348373 self .channels = []
349374 self .uat = UAT (hv .iface , hv .u , hv )
350375 self .mon = RegMonitor (hv .u , ascii = True , log = hv .log )
376+ self .chip_id = hv .u .adt ["/chosen" ].chip_id
351377 self .dev_sgx = hv .u .adt ["/arm-io/sgx" ]
352378 self .sgx = SGXRegs (hv .u , self .dev_sgx .get_reg (0 )[0 ])
353379 self .gpu_region = getattr (self .dev_sgx , "gpu-region-base" )
@@ -377,6 +403,7 @@ def __init__(self, hv, devpath, verbose=False):
377403 self .exclude_context_id = None
378404 self .redump = False
379405 self .skip_asc_tracing = True
406+ self .cmd_dump_dir = None
380407
381408 self .vmcnt = 0
382409 self .readlog = {}
@@ -388,11 +415,11 @@ def __init__(self, hv, devpath, verbose=False):
388415 self .last_3d = None
389416 self .last_cp = None
390417
391- def get_cmdqueue (self , info_addr , new_queue ):
418+ def get_cmdqueue (self , info_addr , new_queue , queue_type ):
392419 if info_addr in self .cmdqueues and not new_queue :
393420 return self .cmdqueues [info_addr ]
394421
395- cmdqueue = CommandQueueTracer (self , info_addr , new_queue )
422+ cmdqueue = CommandQueueTracer (self , info_addr , new_queue , queue_type )
396423 self .cmdqueues [info_addr ] = cmdqueue
397424
398425 return cmdqueue
@@ -655,13 +682,13 @@ def mon_addva(self, ctx, va, size, name=""):
655682 self .mon .add (va , size , name , readfn = lambda a , s : self .uat .ioread (ctx , a , s ))
656683
657684 def handle_ringmsg (self , msg ):
658- if isinstance ( msg , FlagMsg ) :
685+ if msg . __class__ . __name__ == " FlagMsg" :
659686 self .log (f"== Event flag notification ==" )
660687 self .handle_event (msg )
661688 return
662- elif isinstance ( msg , RunCmdQueueMsg ) :
689+ elif msg . __class__ . __name__ == " RunCmdQueueMsg" :
663690 self .log (f"== Work notification (type { msg .queue_type } )==" )
664- queue = self .get_cmdqueue (msg .cmdqueue_addr , msg .new_queue )
691+ queue = self .get_cmdqueue (msg .cmdqueue_addr , msg .new_queue , msg . queue_type )
665692 work_items = list (queue .get_workitems (msg ))
666693 if self .encoder_id_filter is not None :
667694 for wi in work_items :
@@ -790,16 +817,16 @@ def read(off, size):
790817
791818 for i in wi0 .microsequence .value :
792819 i = i .cmd
793- if isinstance ( i , StartTACmd ) :
820+ if i . __class__ . __name__ == " StartTACmd" :
794821 self .log (f" # StartTACmd" )
795822
796823
797- self .log (f" unkptr_24 @ { i .unkptr_24 :#x} :" )
798- chexdump (read (i .unkptr_24 , 0x100 ), print_fn = self .log )
799- self .log (f" unk_5c @ { i .unkptr_5c :#x} :" )
800- chexdump (read (i .unkptr_5c , 0x100 ), print_fn = self .log )
824+ # self.log(f" unkptr_24 @ {i.unkptr_24:#x}:")
825+ # chexdump(read(i.unkptr_24, 0x100), print_fn=self.log)
826+ # self.log(f" unk_5c @ {i.unkptr_5c:#x}:")
827+ # chexdump(read(i.unkptr_5c, 0x100), print_fn=self.log)
801828
802- elif isinstance ( i , FinalizeTACmd ) :
829+ elif i . __class__ . __name__ == " FinalizeTACmd" :
803830 self .log (f" # FinalizeTACmd" )
804831
805832
@@ -1098,6 +1125,7 @@ def init_state(self):
10981125 self .state .channel_info = []
10991126 self .state .channels = {}
11001127 self .state .queues = {}
1128+ self .state .queue_seq = 0
11011129
11021130 def init_channels (self ):
11031131 if self .channels :
0 commit comments