13d004a37SPhilippe Mathieu-Daudé#!/usr/bin/env python3 2821c1130SAlex Bennée# -*- coding: utf-8 -*- 3821c1130SAlex Bennée# 4821c1130SAlex Bennée# Dump the contents of a recorded execution stream 5821c1130SAlex Bennée# 649ebe9b1SAlex Bennée# Copyright (c) 2017 Alex Bennée <alex.bennee@linaro.org> 7821c1130SAlex Bennée# 8821c1130SAlex Bennée# This library is free software; you can redistribute it and/or 9821c1130SAlex Bennée# modify it under the terms of the GNU Lesser General Public 10821c1130SAlex Bennée# License as published by the Free Software Foundation; either 1161f3c91aSChetan Pant# version 2.1 of the License, or (at your option) any later version. 12821c1130SAlex Bennée# 13821c1130SAlex Bennée# This library is distributed in the hope that it will be useful, 14821c1130SAlex Bennée# but WITHOUT ANY WARRANTY; without even the implied warranty of 15821c1130SAlex Bennée# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16821c1130SAlex Bennée# Lesser General Public License for more details. 17821c1130SAlex Bennée# 18821c1130SAlex Bennée# You should have received a copy of the GNU Lesser General Public 19821c1130SAlex Bennée# License along with this library; if not, see <http://www.gnu.org/licenses/>. 20821c1130SAlex Bennée 21821c1130SAlex Bennéeimport argparse 22821c1130SAlex Bennéeimport struct 2300140e79SNicholas Pigginimport os 24*4926b6e6SNicholas Pigginimport sys 25821c1130SAlex Bennéefrom collections import namedtuple 26fcc8c529SAlex Bennéefrom os import path 27821c1130SAlex Bennée 28821c1130SAlex Bennée# This mirrors some of the global replay state which some of the 29821c1130SAlex Bennée# stream loading refers to. Some decoders may read the next event so 30821c1130SAlex Bennée# we need handle that case. Calling reuse_event will ensure the next 31821c1130SAlex Bennée# event is read from the cache rather than advancing the file. 32821c1130SAlex Bennée 33821c1130SAlex Bennéeclass ReplayState(object): 34821c1130SAlex Bennée def __init__(self): 35821c1130SAlex Bennée self.event = -1 36821c1130SAlex Bennée self.event_count = 0 37821c1130SAlex Bennée self.already_read = False 38821c1130SAlex Bennée self.current_checkpoint = 0 39821c1130SAlex Bennée self.checkpoint = 0 40821c1130SAlex Bennée 41821c1130SAlex Bennée def set_event(self, ev): 42821c1130SAlex Bennée self.event = ev 43821c1130SAlex Bennée self.event_count += 1 44821c1130SAlex Bennée 45821c1130SAlex Bennée def get_event(self): 46821c1130SAlex Bennée self.already_read = False 47821c1130SAlex Bennée return self.event 48821c1130SAlex Bennée 49821c1130SAlex Bennée def reuse_event(self, ev): 50821c1130SAlex Bennée self.event = ev 51821c1130SAlex Bennée self.already_read = True 52821c1130SAlex Bennée 53821c1130SAlex Bennée def set_checkpoint(self): 54821c1130SAlex Bennée self.checkpoint = self.event - self.checkpoint_start 55821c1130SAlex Bennée 56821c1130SAlex Bennée def get_checkpoint(self): 57821c1130SAlex Bennée return self.checkpoint 58821c1130SAlex Bennée 59821c1130SAlex Bennéereplay_state = ReplayState() 60821c1130SAlex Bennée 61821c1130SAlex Bennée# Simple read functions that mirror replay-internal.c 62821c1130SAlex Bennée# The file-stream is big-endian and manually written out a byte at a time. 63821c1130SAlex Bennée 64821c1130SAlex Bennéedef read_byte(fin): 65821c1130SAlex Bennée "Read a single byte" 66821c1130SAlex Bennée return struct.unpack('>B', fin.read(1))[0] 67821c1130SAlex Bennée 68821c1130SAlex Bennéedef read_event(fin): 69821c1130SAlex Bennée "Read a single byte event, but save some state" 70821c1130SAlex Bennée if replay_state.already_read: 71821c1130SAlex Bennée return replay_state.get_event() 72821c1130SAlex Bennée else: 73821c1130SAlex Bennée replay_state.set_event(read_byte(fin)) 74821c1130SAlex Bennée return replay_state.event 75821c1130SAlex Bennée 76821c1130SAlex Bennéedef read_word(fin): 77821c1130SAlex Bennée "Read a 16 bit word" 78821c1130SAlex Bennée return struct.unpack('>H', fin.read(2))[0] 79821c1130SAlex Bennée 80821c1130SAlex Bennéedef read_dword(fin): 81821c1130SAlex Bennée "Read a 32 bit word" 82821c1130SAlex Bennée return struct.unpack('>I', fin.read(4))[0] 83821c1130SAlex Bennée 84821c1130SAlex Bennéedef read_qword(fin): 85821c1130SAlex Bennée "Read a 64 bit word" 86821c1130SAlex Bennée return struct.unpack('>Q', fin.read(8))[0] 87821c1130SAlex Bennée 88fcc8c529SAlex Bennéedef read_array(fin): 89fcc8c529SAlex Bennée "Read a sized array" 90fcc8c529SAlex Bennée size = read_dword(fin) 91fcc8c529SAlex Bennée data = fin.read(size) 92fcc8c529SAlex Bennée return data 93fcc8c529SAlex Bennée 94821c1130SAlex Bennée# Generic decoder structure 95821c1130SAlex BennéeDecoder = namedtuple("Decoder", "eid name fn") 96821c1130SAlex Bennée 97821c1130SAlex Bennéedef call_decode(table, index, dumpfile): 98821c1130SAlex Bennée "Search decode table for next step" 99821c1130SAlex Bennée decoder = next((d for d in table if d.eid == index), None) 100821c1130SAlex Bennée if not decoder: 101f03868bdSEduardo Habkost print("Could not decode index: %d" % (index)) 102f03868bdSEduardo Habkost print("Entry is: %s" % (decoder)) 103f03868bdSEduardo Habkost print("Decode Table is:\n%s" % (table)) 104*4926b6e6SNicholas Piggin raise(Exception("unknown event")) 105821c1130SAlex Bennée else: 106821c1130SAlex Bennée return decoder.fn(decoder.eid, decoder.name, dumpfile) 107821c1130SAlex Bennée 108821c1130SAlex Bennée# Print event 109821c1130SAlex Bennéedef print_event(eid, name, string=None, event_count=None): 110821c1130SAlex Bennée "Print event with count" 111821c1130SAlex Bennée if not event_count: 112821c1130SAlex Bennée event_count = replay_state.event_count 113821c1130SAlex Bennée 114821c1130SAlex Bennée if string: 115f03868bdSEduardo Habkost print("%d:%s(%d) %s" % (event_count, name, eid, string)) 116821c1130SAlex Bennée else: 117f03868bdSEduardo Habkost print("%d:%s(%d)" % (event_count, name, eid)) 118821c1130SAlex Bennée 119821c1130SAlex Bennée 120821c1130SAlex Bennée# Decoders for each event type 121821c1130SAlex Bennée 122821c1130SAlex Bennéedef decode_unimp(eid, name, _unused_dumpfile): 123d30b5bc9SMichael Tokarev "Unimplemented decoder, will trigger exit" 124f03868bdSEduardo Habkost print("%s not handled - will now stop" % (name)) 125*4926b6e6SNicholas Piggin raise(Exception("unhandled event")) 126821c1130SAlex Bennée 127fcc8c529SAlex Bennéedef decode_plain(eid, name, _unused_dumpfile): 128fcc8c529SAlex Bennée "Plain events without additional data" 129fcc8c529SAlex Bennée print_event(eid, name, "no data") 130fcc8c529SAlex Bennée return True 131fcc8c529SAlex Bennée 132821c1130SAlex Bennée# Checkpoint decoder 133821c1130SAlex Bennéedef swallow_async_qword(eid, name, dumpfile): 134821c1130SAlex Bennée "Swallow a qword of data without looking at it" 135821c1130SAlex Bennée step_id = read_qword(dumpfile) 136f03868bdSEduardo Habkost print(" %s(%d) @ %d" % (name, eid, step_id)) 137821c1130SAlex Bennée return True 138821c1130SAlex Bennée 13900140e79SNicholas Piggindef swallow_bytes(eid, name, dumpfile, nr): 14000140e79SNicholas Piggin """Swallow nr bytes of data without looking at it""" 14100140e79SNicholas Piggin dumpfile.seek(nr, os.SEEK_CUR) 14200140e79SNicholas Piggin 14301a385fbSNicholas Piggintotal_insns = 0 14401a385fbSNicholas Piggin 14501a385fbSNicholas Piggindef decode_instruction(eid, name, dumpfile): 14601a385fbSNicholas Piggin global total_insns 14701a385fbSNicholas Piggin ins_diff = read_dword(dumpfile) 14801a385fbSNicholas Piggin total_insns += ins_diff 14901a385fbSNicholas Piggin print_event(eid, name, "+ %d -> %d" % (ins_diff, total_insns)) 15001a385fbSNicholas Piggin return True 15101a385fbSNicholas Piggin 15201a385fbSNicholas Piggindef decode_interrupt(eid, name, dumpfile): 15301a385fbSNicholas Piggin print_event(eid, name) 15401a385fbSNicholas Piggin return True 15501a385fbSNicholas Piggin 15600140e79SNicholas Piggindef decode_exception(eid, name, dumpfile): 15700140e79SNicholas Piggin print_event(eid, name) 15800140e79SNicholas Piggin return True 15900140e79SNicholas Piggin 16000140e79SNicholas Piggin# v12 does away with the additional event byte and encodes it in the main type 16100140e79SNicholas Piggin# Between v8 and v9, REPLAY_ASYNC_BH_ONESHOT was added, but we don't decode 16200140e79SNicholas Piggin# those versions so leave it out. 163821c1130SAlex Bennéeasync_decode_table = [ Decoder(0, "REPLAY_ASYNC_EVENT_BH", swallow_async_qword), 164821c1130SAlex Bennée Decoder(1, "REPLAY_ASYNC_INPUT", decode_unimp), 165821c1130SAlex Bennée Decoder(2, "REPLAY_ASYNC_INPUT_SYNC", decode_unimp), 166821c1130SAlex Bennée Decoder(3, "REPLAY_ASYNC_CHAR_READ", decode_unimp), 167821c1130SAlex Bennée Decoder(4, "REPLAY_ASYNC_EVENT_BLOCK", decode_unimp), 168821c1130SAlex Bennée Decoder(5, "REPLAY_ASYNC_EVENT_NET", decode_unimp), 169821c1130SAlex Bennée] 170821c1130SAlex Bennée# See replay_read_events/replay_read_event 17100140e79SNicholas Piggindef decode_async_old(eid, name, dumpfile): 17200140e79SNicholas Piggin """Decode an ASYNC event (pre-v8)""" 173821c1130SAlex Bennée 174821c1130SAlex Bennée print_event(eid, name) 175821c1130SAlex Bennée 176821c1130SAlex Bennée async_event_kind = read_byte(dumpfile) 177821c1130SAlex Bennée async_event_checkpoint = read_byte(dumpfile) 178821c1130SAlex Bennée 179821c1130SAlex Bennée if async_event_checkpoint != replay_state.current_checkpoint: 180f03868bdSEduardo Habkost print(" mismatch between checkpoint %d and async data %d" % ( 181f03868bdSEduardo Habkost replay_state.current_checkpoint, async_event_checkpoint)) 182821c1130SAlex Bennée return True 183821c1130SAlex Bennée 184821c1130SAlex Bennée return call_decode(async_decode_table, async_event_kind, dumpfile) 185821c1130SAlex Bennée 18600140e79SNicholas Piggindef decode_async_bh(eid, name, dumpfile): 18700140e79SNicholas Piggin op_id = read_qword(dumpfile) 18800140e79SNicholas Piggin print_event(eid, name) 18900140e79SNicholas Piggin return True 19000140e79SNicholas Piggin 19100140e79SNicholas Piggindef decode_async_bh_oneshot(eid, name, dumpfile): 19200140e79SNicholas Piggin op_id = read_qword(dumpfile) 19300140e79SNicholas Piggin print_event(eid, name) 19400140e79SNicholas Piggin return True 19500140e79SNicholas Piggin 19600140e79SNicholas Piggindef decode_async_char_read(eid, name, dumpfile): 19700140e79SNicholas Piggin char_id = read_byte(dumpfile) 19800140e79SNicholas Piggin size = read_dword(dumpfile) 19900140e79SNicholas Piggin print_event(eid, name, "device:%x chars:%s" % (char_id, dumpfile.read(size))) 20000140e79SNicholas Piggin return True 20100140e79SNicholas Piggin 20200140e79SNicholas Piggindef decode_async_block(eid, name, dumpfile): 20300140e79SNicholas Piggin op_id = read_qword(dumpfile) 20400140e79SNicholas Piggin print_event(eid, name) 20500140e79SNicholas Piggin return True 20600140e79SNicholas Piggin 20700140e79SNicholas Piggindef decode_async_net(eid, name, dumpfile): 20800140e79SNicholas Piggin net_id = read_byte(dumpfile) 20900140e79SNicholas Piggin flags = read_dword(dumpfile) 21000140e79SNicholas Piggin size = read_dword(dumpfile) 21100140e79SNicholas Piggin swallow_bytes(eid, name, dumpfile, size) 21200140e79SNicholas Piggin print_event(eid, name, "net:%x flags:%x bytes:%d" % (net_id, flags, size)) 21300140e79SNicholas Piggin return True 21400140e79SNicholas Piggin 21500140e79SNicholas Piggindef decode_shutdown(eid, name, dumpfile): 21600140e79SNicholas Piggin print_event(eid, name) 21700140e79SNicholas Piggin return True 21800140e79SNicholas Piggin 219fcc8c529SAlex Bennéedef decode_char_write(eid, name, dumpfile): 220fcc8c529SAlex Bennée res = read_dword(dumpfile) 221fcc8c529SAlex Bennée offset = read_dword(dumpfile) 222fcc8c529SAlex Bennée print_event(eid, name, "%d -> %d" % (offset, res)) 223fcc8c529SAlex Bennée return True 224fcc8c529SAlex Bennée 225821c1130SAlex Bennéedef decode_audio_out(eid, name, dumpfile): 226821c1130SAlex Bennée audio_data = read_dword(dumpfile) 227821c1130SAlex Bennée print_event(eid, name, "%d" % (audio_data)) 228821c1130SAlex Bennée return True 229821c1130SAlex Bennée 23001a385fbSNicholas Piggindef decode_random(eid, name, dumpfile): 23101a385fbSNicholas Piggin ret = read_dword(dumpfile) 23201a385fbSNicholas Piggin size = read_dword(dumpfile) 23301a385fbSNicholas Piggin swallow_bytes(eid, name, dumpfile, size) 23401a385fbSNicholas Piggin if (ret): 23501a385fbSNicholas Piggin print_event(eid, name, "%d bytes (getrandom failed)" % (size)) 23601a385fbSNicholas Piggin else: 23701a385fbSNicholas Piggin print_event(eid, name, "%d bytes" % (size)) 23801a385fbSNicholas Piggin return True 23901a385fbSNicholas Piggin 24001a385fbSNicholas Piggindef decode_clock(eid, name, dumpfile): 24101a385fbSNicholas Piggin clock_data = read_qword(dumpfile) 24201a385fbSNicholas Piggin print_event(eid, name, "0x%x" % (clock_data)) 24301a385fbSNicholas Piggin return True 24401a385fbSNicholas Piggin 24500140e79SNicholas Piggindef __decode_checkpoint(eid, name, dumpfile, old): 246821c1130SAlex Bennée """Decode a checkpoint. 247821c1130SAlex Bennée 248821c1130SAlex Bennée Checkpoints contain a series of async events with their own specific data. 249821c1130SAlex Bennée """ 250821c1130SAlex Bennée replay_state.set_checkpoint() 251821c1130SAlex Bennée # save event count as we peek ahead 252821c1130SAlex Bennée event_number = replay_state.event_count 253821c1130SAlex Bennée next_event = read_event(dumpfile) 254821c1130SAlex Bennée 255821c1130SAlex Bennée # if the next event is EVENT_ASYNC there are a bunch of 256821c1130SAlex Bennée # async events to read, otherwise we are done 25700140e79SNicholas Piggin if (old and next_event == 3) or (not old and next_event >= 3 and next_event <= 9): 258821c1130SAlex Bennée print_event(eid, name, "more data follows", event_number) 25900140e79SNicholas Piggin else: 26000140e79SNicholas Piggin print_event(eid, name, "no additional data", event_number) 261821c1130SAlex Bennée 262821c1130SAlex Bennée replay_state.reuse_event(next_event) 263821c1130SAlex Bennée return True 264821c1130SAlex Bennée 26500140e79SNicholas Piggindef decode_checkpoint_old(eid, name, dumpfile): 26600140e79SNicholas Piggin return __decode_checkpoint(eid, name, dumpfile, False) 26700140e79SNicholas Piggin 26800140e79SNicholas Piggindef decode_checkpoint(eid, name, dumpfile): 26900140e79SNicholas Piggin return __decode_checkpoint(eid, name, dumpfile, True) 27000140e79SNicholas Piggin 271821c1130SAlex Bennéedef decode_checkpoint_init(eid, name, dumpfile): 272821c1130SAlex Bennée print_event(eid, name) 273821c1130SAlex Bennée return True 274821c1130SAlex Bennée 27500140e79SNicholas Piggindef decode_end(eid, name, dumpfile): 27600140e79SNicholas Piggin print_event(eid, name) 27700140e79SNicholas Piggin return False 27800140e79SNicholas Piggin 279821c1130SAlex Bennée# pre-MTTCG merge 280821c1130SAlex Bennéev5_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), 281821c1130SAlex Bennée Decoder(1, "EVENT_INTERRUPT", decode_interrupt), 282fcc8c529SAlex Bennée Decoder(2, "EVENT_EXCEPTION", decode_plain), 28300140e79SNicholas Piggin Decoder(3, "EVENT_ASYNC", decode_async_old), 284821c1130SAlex Bennée Decoder(4, "EVENT_SHUTDOWN", decode_unimp), 285fcc8c529SAlex Bennée Decoder(5, "EVENT_CHAR_WRITE", decode_char_write), 286821c1130SAlex Bennée Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), 287821c1130SAlex Bennée Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), 288821c1130SAlex Bennée Decoder(8, "EVENT_CLOCK_HOST", decode_clock), 289821c1130SAlex Bennée Decoder(9, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), 290821c1130SAlex Bennée Decoder(10, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), 291821c1130SAlex Bennée Decoder(11, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), 292821c1130SAlex Bennée Decoder(12, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), 293821c1130SAlex Bennée Decoder(13, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), 294821c1130SAlex Bennée Decoder(14, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), 295821c1130SAlex Bennée Decoder(15, "EVENT_CP_CLOCK_HOST", decode_checkpoint), 296821c1130SAlex Bennée Decoder(16, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), 297821c1130SAlex Bennée Decoder(17, "EVENT_CP_INIT", decode_checkpoint_init), 298821c1130SAlex Bennée Decoder(18, "EVENT_CP_RESET", decode_checkpoint), 299821c1130SAlex Bennée] 300821c1130SAlex Bennée 301821c1130SAlex Bennée# post-MTTCG merge, AUDIO support added 302821c1130SAlex Bennéev6_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), 303821c1130SAlex Bennée Decoder(1, "EVENT_INTERRUPT", decode_interrupt), 304fcc8c529SAlex Bennée Decoder(2, "EVENT_EXCEPTION", decode_plain), 30500140e79SNicholas Piggin Decoder(3, "EVENT_ASYNC", decode_async_old), 306821c1130SAlex Bennée Decoder(4, "EVENT_SHUTDOWN", decode_unimp), 307fcc8c529SAlex Bennée Decoder(5, "EVENT_CHAR_WRITE", decode_char_write), 308821c1130SAlex Bennée Decoder(6, "EVENT_CHAR_READ_ALL", decode_unimp), 309821c1130SAlex Bennée Decoder(7, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), 310821c1130SAlex Bennée Decoder(8, "EVENT_AUDIO_OUT", decode_audio_out), 311821c1130SAlex Bennée Decoder(9, "EVENT_AUDIO_IN", decode_unimp), 312821c1130SAlex Bennée Decoder(10, "EVENT_CLOCK_HOST", decode_clock), 313821c1130SAlex Bennée Decoder(11, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), 314821c1130SAlex Bennée Decoder(12, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), 315821c1130SAlex Bennée Decoder(13, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), 316821c1130SAlex Bennée Decoder(14, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), 317821c1130SAlex Bennée Decoder(15, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), 318821c1130SAlex Bennée Decoder(16, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), 319821c1130SAlex Bennée Decoder(17, "EVENT_CP_CLOCK_HOST", decode_checkpoint), 320821c1130SAlex Bennée Decoder(18, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), 321821c1130SAlex Bennée Decoder(19, "EVENT_CP_INIT", decode_checkpoint_init), 322821c1130SAlex Bennée Decoder(20, "EVENT_CP_RESET", decode_checkpoint), 323821c1130SAlex Bennée] 324821c1130SAlex Bennée 325821c1130SAlex Bennée# Shutdown cause added 326821c1130SAlex Bennéev7_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), 327821c1130SAlex Bennée Decoder(1, "EVENT_INTERRUPT", decode_interrupt), 328821c1130SAlex Bennée Decoder(2, "EVENT_EXCEPTION", decode_unimp), 32900140e79SNicholas Piggin Decoder(3, "EVENT_ASYNC", decode_async_old), 330821c1130SAlex Bennée Decoder(4, "EVENT_SHUTDOWN", decode_unimp), 331821c1130SAlex Bennée Decoder(5, "EVENT_SHUTDOWN_HOST_ERR", decode_unimp), 332821c1130SAlex Bennée Decoder(6, "EVENT_SHUTDOWN_HOST_QMP", decode_unimp), 333821c1130SAlex Bennée Decoder(7, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_unimp), 334821c1130SAlex Bennée Decoder(8, "EVENT_SHUTDOWN_HOST_UI", decode_unimp), 335821c1130SAlex Bennée Decoder(9, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_unimp), 336821c1130SAlex Bennée Decoder(10, "EVENT_SHUTDOWN_GUEST_RESET", decode_unimp), 337821c1130SAlex Bennée Decoder(11, "EVENT_SHUTDOWN_GUEST_PANIC", decode_unimp), 338821c1130SAlex Bennée Decoder(12, "EVENT_SHUTDOWN___MAX", decode_unimp), 339fcc8c529SAlex Bennée Decoder(13, "EVENT_CHAR_WRITE", decode_char_write), 340821c1130SAlex Bennée Decoder(14, "EVENT_CHAR_READ_ALL", decode_unimp), 341821c1130SAlex Bennée Decoder(15, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), 342821c1130SAlex Bennée Decoder(16, "EVENT_AUDIO_OUT", decode_audio_out), 343821c1130SAlex Bennée Decoder(17, "EVENT_AUDIO_IN", decode_unimp), 344821c1130SAlex Bennée Decoder(18, "EVENT_CLOCK_HOST", decode_clock), 345821c1130SAlex Bennée Decoder(19, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), 346821c1130SAlex Bennée Decoder(20, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), 347821c1130SAlex Bennée Decoder(21, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), 348821c1130SAlex Bennée Decoder(22, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), 349821c1130SAlex Bennée Decoder(23, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), 350821c1130SAlex Bennée Decoder(24, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), 351821c1130SAlex Bennée Decoder(25, "EVENT_CP_CLOCK_HOST", decode_checkpoint), 352821c1130SAlex Bennée Decoder(26, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), 353821c1130SAlex Bennée Decoder(27, "EVENT_CP_INIT", decode_checkpoint_init), 354821c1130SAlex Bennée Decoder(28, "EVENT_CP_RESET", decode_checkpoint), 355821c1130SAlex Bennée] 356821c1130SAlex Bennée 357fcc8c529SAlex Bennéev12_event_table = [Decoder(0, "EVENT_INSTRUCTION", decode_instruction), 358fcc8c529SAlex Bennée Decoder(1, "EVENT_INTERRUPT", decode_interrupt), 35900140e79SNicholas Piggin Decoder(2, "EVENT_EXCEPTION", decode_exception), 36000140e79SNicholas Piggin Decoder(3, "EVENT_ASYNC_BH", decode_async_bh), 36100140e79SNicholas Piggin Decoder(4, "EVENT_ASYNC_BH_ONESHOT", decode_async_bh_oneshot), 36200140e79SNicholas Piggin Decoder(5, "EVENT_ASYNC_INPUT", decode_unimp), 36300140e79SNicholas Piggin Decoder(6, "EVENT_ASYNC_INPUT_SYNC", decode_unimp), 36400140e79SNicholas Piggin Decoder(7, "EVENT_ASYNC_CHAR_READ", decode_async_char_read), 36500140e79SNicholas Piggin Decoder(8, "EVENT_ASYNC_BLOCK", decode_async_block), 36600140e79SNicholas Piggin Decoder(9, "EVENT_ASYNC_NET", decode_async_net), 36700140e79SNicholas Piggin Decoder(10, "EVENT_SHUTDOWN", decode_shutdown), 36800140e79SNicholas Piggin Decoder(11, "EVENT_SHUTDOWN_HOST_ERR", decode_shutdown), 36900140e79SNicholas Piggin Decoder(12, "EVENT_SHUTDOWN_HOST_QMP_QUIT", decode_shutdown), 37000140e79SNicholas Piggin Decoder(13, "EVENT_SHUTDOWN_HOST_QMP_RESET", decode_shutdown), 37100140e79SNicholas Piggin Decoder(14, "EVENT_SHUTDOWN_HOST_SIGNAL", decode_shutdown), 37200140e79SNicholas Piggin Decoder(15, "EVENT_SHUTDOWN_HOST_UI", decode_shutdown), 37300140e79SNicholas Piggin Decoder(16, "EVENT_SHUTDOWN_GUEST_SHUTDOWN", decode_shutdown), 37400140e79SNicholas Piggin Decoder(17, "EVENT_SHUTDOWN_GUEST_RESET", decode_shutdown), 37500140e79SNicholas Piggin Decoder(18, "EVENT_SHUTDOWN_GUEST_PANIC", decode_shutdown), 37600140e79SNicholas Piggin Decoder(19, "EVENT_SHUTDOWN_SUBSYS_RESET", decode_shutdown), 37700140e79SNicholas Piggin Decoder(20, "EVENT_SHUTDOWN_SNAPSHOT_LOAD", decode_shutdown), 37800140e79SNicholas Piggin Decoder(21, "EVENT_SHUTDOWN___MAX", decode_shutdown), 379fcc8c529SAlex Bennée Decoder(22, "EVENT_CHAR_WRITE", decode_char_write), 380fcc8c529SAlex Bennée Decoder(23, "EVENT_CHAR_READ_ALL", decode_unimp), 381fcc8c529SAlex Bennée Decoder(24, "EVENT_CHAR_READ_ALL_ERROR", decode_unimp), 38200140e79SNicholas Piggin Decoder(25, "EVENT_AUDIO_OUT", decode_audio_out), 38300140e79SNicholas Piggin Decoder(26, "EVENT_AUDIO_IN", decode_unimp), 384fcc8c529SAlex Bennée Decoder(27, "EVENT_RANDOM", decode_random), 385fcc8c529SAlex Bennée Decoder(28, "EVENT_CLOCK_HOST", decode_clock), 386fcc8c529SAlex Bennée Decoder(29, "EVENT_CLOCK_VIRTUAL_RT", decode_clock), 387fcc8c529SAlex Bennée Decoder(30, "EVENT_CP_CLOCK_WARP_START", decode_checkpoint), 388fcc8c529SAlex Bennée Decoder(31, "EVENT_CP_CLOCK_WARP_ACCOUNT", decode_checkpoint), 389fcc8c529SAlex Bennée Decoder(32, "EVENT_CP_RESET_REQUESTED", decode_checkpoint), 390fcc8c529SAlex Bennée Decoder(33, "EVENT_CP_SUSPEND_REQUESTED", decode_checkpoint), 391fcc8c529SAlex Bennée Decoder(34, "EVENT_CP_CLOCK_VIRTUAL", decode_checkpoint), 392fcc8c529SAlex Bennée Decoder(35, "EVENT_CP_CLOCK_HOST", decode_checkpoint), 393fcc8c529SAlex Bennée Decoder(36, "EVENT_CP_CLOCK_VIRTUAL_RT", decode_checkpoint), 394fcc8c529SAlex Bennée Decoder(37, "EVENT_CP_INIT", decode_checkpoint_init), 395fcc8c529SAlex Bennée Decoder(38, "EVENT_CP_RESET", decode_checkpoint), 39600140e79SNicholas Piggin Decoder(39, "EVENT_END", decode_end), 397fcc8c529SAlex Bennée] 398fcc8c529SAlex Bennée 399821c1130SAlex Bennéedef parse_arguments(): 400821c1130SAlex Bennée "Grab arguments for script" 401821c1130SAlex Bennée parser = argparse.ArgumentParser() 402821c1130SAlex Bennée parser.add_argument("-f", "--file", help='record/replay dump to read from', 403821c1130SAlex Bennée required=True) 404821c1130SAlex Bennée return parser.parse_args() 405821c1130SAlex Bennée 406821c1130SAlex Bennéedef decode_file(filename): 407821c1130SAlex Bennée "Decode a record/replay dump" 408821c1130SAlex Bennée dumpfile = open(filename, "rb") 409fcc8c529SAlex Bennée dumpsize = path.getsize(filename) 410821c1130SAlex Bennée # read and throwaway the header 411821c1130SAlex Bennée version = read_dword(dumpfile) 412821c1130SAlex Bennée junk = read_qword(dumpfile) 413821c1130SAlex Bennée 414fcc8c529SAlex Bennée # see REPLAY_VERSION 415f03868bdSEduardo Habkost print("HEADER: version 0x%x" % (version)) 416821c1130SAlex Bennée 417fcc8c529SAlex Bennée if version == 0xe0200c: 418fcc8c529SAlex Bennée event_decode_table = v12_event_table 419fcc8c529SAlex Bennée replay_state.checkpoint_start = 30 420fcc8c529SAlex Bennée elif version == 0xe02007: 421821c1130SAlex Bennée event_decode_table = v7_event_table 422821c1130SAlex Bennée replay_state.checkpoint_start = 12 423821c1130SAlex Bennée elif version == 0xe02006: 424821c1130SAlex Bennée event_decode_table = v6_event_table 425821c1130SAlex Bennée replay_state.checkpoint_start = 12 426821c1130SAlex Bennée else: 427821c1130SAlex Bennée event_decode_table = v5_event_table 428821c1130SAlex Bennée replay_state.checkpoint_start = 10 429821c1130SAlex Bennée 430821c1130SAlex Bennée try: 431821c1130SAlex Bennée decode_ok = True 432821c1130SAlex Bennée while decode_ok: 433821c1130SAlex Bennée event = read_event(dumpfile) 434fcc8c529SAlex Bennée decode_ok = call_decode(event_decode_table, event, 435fcc8c529SAlex Bennée dumpfile) 436fcc8c529SAlex Bennée except Exception as inst: 437fcc8c529SAlex Bennée print(f"error {inst}") 438*4926b6e6SNicholas Piggin sys.exit(1) 439fcc8c529SAlex Bennée 440821c1130SAlex Bennée finally: 441fcc8c529SAlex Bennée print(f"Reached {dumpfile.tell()} of {dumpsize} bytes") 442821c1130SAlex Bennée dumpfile.close() 443821c1130SAlex Bennée 444821c1130SAlex Bennéeif __name__ == "__main__": 445821c1130SAlex Bennée args = parse_arguments() 446821c1130SAlex Bennée decode_file(args.file) 447