1c92079f4SPavel Dovgalyuk #ifndef REPLAY_INTERNAL_H 2c92079f4SPavel Dovgalyuk #define REPLAY_INTERNAL_H 3c92079f4SPavel Dovgalyuk 4c92079f4SPavel Dovgalyuk /* 5c92079f4SPavel Dovgalyuk * replay-internal.h 6c92079f4SPavel Dovgalyuk * 7c92079f4SPavel Dovgalyuk * Copyright (c) 2010-2015 Institute for System Programming 8c92079f4SPavel Dovgalyuk * of the Russian Academy of Sciences. 9c92079f4SPavel Dovgalyuk * 10c92079f4SPavel Dovgalyuk * This work is licensed under the terms of the GNU GPL, version 2 or later. 11c92079f4SPavel Dovgalyuk * See the COPYING file in the top-level directory. 12c92079f4SPavel Dovgalyuk * 13c92079f4SPavel Dovgalyuk */ 14c92079f4SPavel Dovgalyuk 153e21408bSPavel Dovgalyuk /* Asynchronous events IDs */ 163e21408bSPavel Dovgalyuk 173e21408bSPavel Dovgalyuk typedef enum ReplayAsyncEventKind { 183e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_BH, 193e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_BH_ONESHOT, 203e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT, 213e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT_SYNC, 223e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_CHAR_READ, 233e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_BLOCK, 243e21408bSPavel Dovgalyuk REPLAY_ASYNC_EVENT_NET, 253e21408bSPavel Dovgalyuk REPLAY_ASYNC_COUNT 263e21408bSPavel Dovgalyuk } ReplayAsyncEventKind; 273e21408bSPavel Dovgalyuk 28*dcda7321SAlex Bennée /* 29*dcda7321SAlex Bennée * Any changes to order/number of events will need to bump 30*dcda7321SAlex Bennée * REPLAY_VERSION to prevent confusion with old logs. Also don't 31*dcda7321SAlex Bennée * forget to update replay_event_name() to make your debugging life 32*dcda7321SAlex Bennée * easier. 33*dcda7321SAlex Bennée */ 3426bc60acSPavel Dovgalyuk enum ReplayEvents { 3526bc60acSPavel Dovgalyuk /* for instruction event */ 3626bc60acSPavel Dovgalyuk EVENT_INSTRUCTION, 376f060969SPavel Dovgalyuk /* for software interrupt */ 386f060969SPavel Dovgalyuk EVENT_INTERRUPT, 396f060969SPavel Dovgalyuk /* for emulated exceptions */ 406f060969SPavel Dovgalyuk EVENT_EXCEPTION, 41c0c071d0SPavel Dovgalyuk /* for async events */ 42c0c071d0SPavel Dovgalyuk EVENT_ASYNC, 433e21408bSPavel Dovgalyuk EVENT_ASYNC_LAST = EVENT_ASYNC + REPLAY_ASYNC_COUNT - 1, 44802f045aSEric Blake /* for shutdown requests, range allows recovery of ShutdownCause */ 45b60c48a7SPavel Dovgalyuk EVENT_SHUTDOWN, 46802f045aSEric Blake EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX, 4733577b47SPavel Dovgalyuk /* for character device write event */ 4833577b47SPavel Dovgalyuk EVENT_CHAR_WRITE, 4933577b47SPavel Dovgalyuk /* for character device read all event */ 5033577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL, 5133577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL_ERROR, 523d4d16f4SPavel Dovgalyuk /* for audio out event */ 533d4d16f4SPavel Dovgalyuk EVENT_AUDIO_OUT, 543d4d16f4SPavel Dovgalyuk /* for audio in event */ 553d4d16f4SPavel Dovgalyuk EVENT_AUDIO_IN, 56878ec29bSPavel Dovgalyuk /* for random number generator */ 57878ec29bSPavel Dovgalyuk EVENT_RANDOM, 588eda206eSPavel Dovgalyuk /* for clock read/writes */ 598eda206eSPavel Dovgalyuk /* some of greater codes are reserved for clocks */ 608eda206eSPavel Dovgalyuk EVENT_CLOCK, 618eda206eSPavel Dovgalyuk EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1, 628bd7f71dSPavel Dovgalyuk /* for checkpoint event */ 638bd7f71dSPavel Dovgalyuk /* some of greater codes are reserved for checkpoints */ 648bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT, 658bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1, 667615936eSPavel Dovgalyuk /* end of log event */ 677615936eSPavel Dovgalyuk EVENT_END, 6826bc60acSPavel Dovgalyuk EVENT_COUNT 6926bc60acSPavel Dovgalyuk }; 7026bc60acSPavel Dovgalyuk 71808eab62SAlex Bennée /** 72808eab62SAlex Bennée * typedef ReplayState - global tracking Replay state 73808eab62SAlex Bennée * 74808eab62SAlex Bennée * This structure tracks where we are in the current ReplayState 75808eab62SAlex Bennée * including the logged events from the recorded replay stream. Some 76808eab62SAlex Bennée * of the data is also stored/restored from VMStateDescription when VM 77808eab62SAlex Bennée * save/restore events take place. 78808eab62SAlex Bennée * 79808eab62SAlex Bennée * @cached_clock: Cached clocks values 80808eab62SAlex Bennée * @current_icount: number of processed instructions 81808eab62SAlex Bennée * @instruction_count: number of instructions until next event 82*dcda7321SAlex Bennée * @current_event: current event index 83808eab62SAlex Bennée * @data_kind: current event 842b7a58b6SAlex Bennée * @has_unread_data: true if event not yet processed 85808eab62SAlex Bennée * @file_offset: offset into replay log at replay snapshot 86808eab62SAlex Bennée * @block_request_id: current serialised block request id 87808eab62SAlex Bennée * @read_event_id: current async read event id 88808eab62SAlex Bennée */ 8926bc60acSPavel Dovgalyuk typedef struct ReplayState { 908eda206eSPavel Dovgalyuk int64_t cached_clock[REPLAY_CLOCK_COUNT]; 9113f26713SPavel Dovgalyuk uint64_t current_icount; 9213f26713SPavel Dovgalyuk int instruction_count; 93*dcda7321SAlex Bennée unsigned int current_event; 94f186d64dSPavel Dovgalyuk unsigned int data_kind; 952b7a58b6SAlex Bennée bool has_unread_data; 96306e196fSPavel Dovgalyuk uint64_t file_offset; 976d0ceb80SPavel Dovgalyuk uint64_t block_request_id; 980b30dc01SPavel Dovgalyuk uint64_t read_event_id; 9926bc60acSPavel Dovgalyuk } ReplayState; 10026bc60acSPavel Dovgalyuk extern ReplayState replay_state; 10126bc60acSPavel Dovgalyuk 102c92079f4SPavel Dovgalyuk /* File for replay writing */ 103c92079f4SPavel Dovgalyuk extern FILE *replay_file; 104e7510671SPavel Dovgalyuk /* Instruction count of the replay breakpoint */ 105e7510671SPavel Dovgalyuk extern uint64_t replay_break_icount; 106e7510671SPavel Dovgalyuk /* Timer for the replay breakpoint callback */ 107e7510671SPavel Dovgalyuk extern QEMUTimer *replay_break_timer; 108c92079f4SPavel Dovgalyuk 109c92079f4SPavel Dovgalyuk void replay_put_byte(uint8_t byte); 110c92079f4SPavel Dovgalyuk void replay_put_event(uint8_t event); 111c92079f4SPavel Dovgalyuk void replay_put_word(uint16_t word); 112c92079f4SPavel Dovgalyuk void replay_put_dword(uint32_t dword); 113c92079f4SPavel Dovgalyuk void replay_put_qword(int64_t qword); 114c92079f4SPavel Dovgalyuk void replay_put_array(const uint8_t *buf, size_t size); 115c92079f4SPavel Dovgalyuk 116c92079f4SPavel Dovgalyuk uint8_t replay_get_byte(void); 117c92079f4SPavel Dovgalyuk uint16_t replay_get_word(void); 118c92079f4SPavel Dovgalyuk uint32_t replay_get_dword(void); 119c92079f4SPavel Dovgalyuk int64_t replay_get_qword(void); 120c92079f4SPavel Dovgalyuk void replay_get_array(uint8_t *buf, size_t *size); 121c92079f4SPavel Dovgalyuk void replay_get_array_alloc(uint8_t **buf, size_t *size); 122c92079f4SPavel Dovgalyuk 123a36544d3SAlex Bennée /* Mutex functions for protecting replay log file and ensuring 124a36544d3SAlex Bennée * synchronisation between vCPU and main-loop threads. */ 125c16861efSPavel Dovgalyuk 126c16861efSPavel Dovgalyuk void replay_mutex_init(void); 127a36544d3SAlex Bennée bool replay_mutex_locked(void); 128c16861efSPavel Dovgalyuk 129c92079f4SPavel Dovgalyuk /*! Checks error status of the file. */ 130c92079f4SPavel Dovgalyuk void replay_check_error(void); 131c92079f4SPavel Dovgalyuk 132c92079f4SPavel Dovgalyuk /*! Finishes processing of the replayed event and fetches 133c92079f4SPavel Dovgalyuk the next event from the log. */ 134c92079f4SPavel Dovgalyuk void replay_finish_event(void); 135c92079f4SPavel Dovgalyuk /*! Reads data type from the file and stores it in the 136f186d64dSPavel Dovgalyuk data_kind variable. */ 137c92079f4SPavel Dovgalyuk void replay_fetch_data_kind(void); 138c92079f4SPavel Dovgalyuk 13913f26713SPavel Dovgalyuk /*! Advance replay_state.current_icount to the specified value. */ 14013f26713SPavel Dovgalyuk void replay_advance_current_icount(uint64_t current_icount); 14126bc60acSPavel Dovgalyuk /*! Saves queued events (like instructions and sound). */ 14226bc60acSPavel Dovgalyuk void replay_save_instructions(void); 14326bc60acSPavel Dovgalyuk 14426bc60acSPavel Dovgalyuk /*! Skips async events until some sync event will be found. 14526bc60acSPavel Dovgalyuk \return true, if event was found */ 14626bc60acSPavel Dovgalyuk bool replay_next_event_is(int event); 14726bc60acSPavel Dovgalyuk 1488eda206eSPavel Dovgalyuk /*! Reads next clock value from the file. 1498eda206eSPavel Dovgalyuk If clock kind read from the file is different from the parameter, 1508eda206eSPavel Dovgalyuk the value is not used. */ 151fb72e779SRichard Henderson void replay_read_next_clock(ReplayClockKind kind); 1528eda206eSPavel Dovgalyuk 153c0c071d0SPavel Dovgalyuk /* Asynchronous events queue */ 154c0c071d0SPavel Dovgalyuk 155c0c071d0SPavel Dovgalyuk /*! Initializes events' processing internals */ 156c0c071d0SPavel Dovgalyuk void replay_init_events(void); 157c0c071d0SPavel Dovgalyuk /*! Clears internal data structures for events handling */ 158c0c071d0SPavel Dovgalyuk void replay_finish_events(void); 159c0c071d0SPavel Dovgalyuk /*! Returns true if there are any unsaved events in the queue */ 160c0c071d0SPavel Dovgalyuk bool replay_has_events(void); 161c0c071d0SPavel Dovgalyuk /*! Saves events from queue into the file */ 16260618e2dSPavel Dovgalyuk void replay_save_events(void); 163c0c071d0SPavel Dovgalyuk /*! Read events from the file into the input queue */ 16460618e2dSPavel Dovgalyuk void replay_read_events(void); 16533577b47SPavel Dovgalyuk /*! Adds specified async event to the queue */ 16633577b47SPavel Dovgalyuk void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque, 16733577b47SPavel Dovgalyuk void *opaque2, uint64_t id); 168c0c071d0SPavel Dovgalyuk 169ee312992SPavel Dovgalyuk /* Input events */ 170ee312992SPavel Dovgalyuk 171ee312992SPavel Dovgalyuk /*! Saves input event to the log */ 172ee312992SPavel Dovgalyuk void replay_save_input_event(InputEvent *evt); 173ee312992SPavel Dovgalyuk /*! Reads input event from the log */ 174ee312992SPavel Dovgalyuk InputEvent *replay_read_input_event(void); 175ee312992SPavel Dovgalyuk /*! Adds input event to the queue */ 176ee312992SPavel Dovgalyuk void replay_add_input_event(struct InputEvent *event); 177ee312992SPavel Dovgalyuk /*! Adds input sync event to the queue */ 178ee312992SPavel Dovgalyuk void replay_add_input_sync_event(void); 179ee312992SPavel Dovgalyuk 18033577b47SPavel Dovgalyuk /* Character devices */ 18133577b47SPavel Dovgalyuk 18233577b47SPavel Dovgalyuk /*! Called to run char device read event. */ 18333577b47SPavel Dovgalyuk void replay_event_char_read_run(void *opaque); 18433577b47SPavel Dovgalyuk /*! Writes char read event to the file. */ 18533577b47SPavel Dovgalyuk void replay_event_char_read_save(void *opaque); 18633577b47SPavel Dovgalyuk /*! Reads char event read from the file. */ 18733577b47SPavel Dovgalyuk void *replay_event_char_read_load(void); 18833577b47SPavel Dovgalyuk 189646c5478SPavel Dovgalyuk /* Network devices */ 190646c5478SPavel Dovgalyuk 191646c5478SPavel Dovgalyuk /*! Called to run network event. */ 192646c5478SPavel Dovgalyuk void replay_event_net_run(void *opaque); 193646c5478SPavel Dovgalyuk /*! Writes network event to the file. */ 194646c5478SPavel Dovgalyuk void replay_event_net_save(void *opaque); 195646c5478SPavel Dovgalyuk /*! Reads network from the file. */ 196646c5478SPavel Dovgalyuk void *replay_event_net_load(void); 197646c5478SPavel Dovgalyuk 198*dcda7321SAlex Bennée /* Diagnostics */ 199*dcda7321SAlex Bennée 200*dcda7321SAlex Bennée /** 201*dcda7321SAlex Bennée * replay_sync_error(): report sync error and exit 202*dcda7321SAlex Bennée * 203*dcda7321SAlex Bennée * When we reach an error condition we want to report it centrally so 204*dcda7321SAlex Bennée * we can also dump some useful information into the logs. 205*dcda7321SAlex Bennée */ 206*dcda7321SAlex Bennée G_NORETURN void replay_sync_error(const char *error); 207*dcda7321SAlex Bennée 208306e196fSPavel Dovgalyuk /* VMState-related functions */ 209306e196fSPavel Dovgalyuk 210306e196fSPavel Dovgalyuk /* Registers replay VMState. 211306e196fSPavel Dovgalyuk Should be called before virtual devices initialization 212306e196fSPavel Dovgalyuk to make cached timers available for post_load functions. */ 213306e196fSPavel Dovgalyuk void replay_vmstate_register(void); 214306e196fSPavel Dovgalyuk 215c92079f4SPavel Dovgalyuk #endif 216