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 2880be169cSAlex Bennée /* Any changes to order/number of events will need to bump REPLAY_VERSION */ 2926bc60acSPavel Dovgalyuk enum ReplayEvents { 3026bc60acSPavel Dovgalyuk /* for instruction event */ 3126bc60acSPavel Dovgalyuk EVENT_INSTRUCTION, 326f060969SPavel Dovgalyuk /* for software interrupt */ 336f060969SPavel Dovgalyuk EVENT_INTERRUPT, 346f060969SPavel Dovgalyuk /* for emulated exceptions */ 356f060969SPavel Dovgalyuk EVENT_EXCEPTION, 36c0c071d0SPavel Dovgalyuk /* for async events */ 37c0c071d0SPavel Dovgalyuk EVENT_ASYNC, 383e21408bSPavel Dovgalyuk EVENT_ASYNC_LAST = EVENT_ASYNC + REPLAY_ASYNC_COUNT - 1, 39802f045aSEric Blake /* for shutdown requests, range allows recovery of ShutdownCause */ 40b60c48a7SPavel Dovgalyuk EVENT_SHUTDOWN, 41802f045aSEric Blake EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX, 4233577b47SPavel Dovgalyuk /* for character device write event */ 4333577b47SPavel Dovgalyuk EVENT_CHAR_WRITE, 4433577b47SPavel Dovgalyuk /* for character device read all event */ 4533577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL, 4633577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL_ERROR, 473d4d16f4SPavel Dovgalyuk /* for audio out event */ 483d4d16f4SPavel Dovgalyuk EVENT_AUDIO_OUT, 493d4d16f4SPavel Dovgalyuk /* for audio in event */ 503d4d16f4SPavel Dovgalyuk EVENT_AUDIO_IN, 51878ec29bSPavel Dovgalyuk /* for random number generator */ 52878ec29bSPavel Dovgalyuk EVENT_RANDOM, 538eda206eSPavel Dovgalyuk /* for clock read/writes */ 548eda206eSPavel Dovgalyuk /* some of greater codes are reserved for clocks */ 558eda206eSPavel Dovgalyuk EVENT_CLOCK, 568eda206eSPavel Dovgalyuk EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1, 578bd7f71dSPavel Dovgalyuk /* for checkpoint event */ 588bd7f71dSPavel Dovgalyuk /* some of greater codes are reserved for checkpoints */ 598bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT, 608bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1, 617615936eSPavel Dovgalyuk /* end of log event */ 627615936eSPavel Dovgalyuk EVENT_END, 6326bc60acSPavel Dovgalyuk EVENT_COUNT 6426bc60acSPavel Dovgalyuk }; 6526bc60acSPavel Dovgalyuk 6626bc60acSPavel Dovgalyuk typedef struct ReplayState { 678eda206eSPavel Dovgalyuk /*! Cached clock values. */ 688eda206eSPavel Dovgalyuk int64_t cached_clock[REPLAY_CLOCK_COUNT]; 6913f26713SPavel Dovgalyuk /*! Current icount - number of processed instructions. */ 7013f26713SPavel Dovgalyuk uint64_t current_icount; 7126bc60acSPavel Dovgalyuk /*! Number of instructions to be executed before other events happen. */ 7213f26713SPavel Dovgalyuk int instruction_count; 73f186d64dSPavel Dovgalyuk /*! Type of the currently executed event. */ 74f186d64dSPavel Dovgalyuk unsigned int data_kind; 75f186d64dSPavel Dovgalyuk /*! Flag which indicates that event is not processed yet. */ 76f186d64dSPavel Dovgalyuk unsigned int has_unread_data; 77306e196fSPavel Dovgalyuk /*! Temporary variable for saving current log offset. */ 78306e196fSPavel Dovgalyuk uint64_t file_offset; 796d0ceb80SPavel Dovgalyuk /*! Next block operation id. 806d0ceb80SPavel Dovgalyuk This counter is global, because requests from different 816d0ceb80SPavel Dovgalyuk block devices should not get overlapping ids. */ 826d0ceb80SPavel Dovgalyuk uint64_t block_request_id; 834b930d26SPavel Dovgalyuk /*! Prior value of the host clock */ 844b930d26SPavel Dovgalyuk uint64_t host_clock_last; 850b30dc01SPavel Dovgalyuk /*! Asynchronous event id read from the log */ 860b30dc01SPavel Dovgalyuk uint64_t read_event_id; 8726bc60acSPavel Dovgalyuk } ReplayState; 8826bc60acSPavel Dovgalyuk extern ReplayState replay_state; 8926bc60acSPavel Dovgalyuk 90c92079f4SPavel Dovgalyuk /* File for replay writing */ 91c92079f4SPavel Dovgalyuk extern FILE *replay_file; 92e7510671SPavel Dovgalyuk /* Instruction count of the replay breakpoint */ 93e7510671SPavel Dovgalyuk extern uint64_t replay_break_icount; 94e7510671SPavel Dovgalyuk /* Timer for the replay breakpoint callback */ 95e7510671SPavel Dovgalyuk extern QEMUTimer *replay_break_timer; 96c92079f4SPavel Dovgalyuk 97c92079f4SPavel Dovgalyuk void replay_put_byte(uint8_t byte); 98c92079f4SPavel Dovgalyuk void replay_put_event(uint8_t event); 99c92079f4SPavel Dovgalyuk void replay_put_word(uint16_t word); 100c92079f4SPavel Dovgalyuk void replay_put_dword(uint32_t dword); 101c92079f4SPavel Dovgalyuk void replay_put_qword(int64_t qword); 102c92079f4SPavel Dovgalyuk void replay_put_array(const uint8_t *buf, size_t size); 103c92079f4SPavel Dovgalyuk 104c92079f4SPavel Dovgalyuk uint8_t replay_get_byte(void); 105c92079f4SPavel Dovgalyuk uint16_t replay_get_word(void); 106c92079f4SPavel Dovgalyuk uint32_t replay_get_dword(void); 107c92079f4SPavel Dovgalyuk int64_t replay_get_qword(void); 108c92079f4SPavel Dovgalyuk void replay_get_array(uint8_t *buf, size_t *size); 109c92079f4SPavel Dovgalyuk void replay_get_array_alloc(uint8_t **buf, size_t *size); 110c92079f4SPavel Dovgalyuk 111a36544d3SAlex Bennée /* Mutex functions for protecting replay log file and ensuring 112a36544d3SAlex Bennée * synchronisation between vCPU and main-loop threads. */ 113c16861efSPavel Dovgalyuk 114c16861efSPavel Dovgalyuk void replay_mutex_init(void); 115a36544d3SAlex Bennée bool replay_mutex_locked(void); 116c16861efSPavel Dovgalyuk 117c92079f4SPavel Dovgalyuk /*! Checks error status of the file. */ 118c92079f4SPavel Dovgalyuk void replay_check_error(void); 119c92079f4SPavel Dovgalyuk 120c92079f4SPavel Dovgalyuk /*! Finishes processing of the replayed event and fetches 121c92079f4SPavel Dovgalyuk the next event from the log. */ 122c92079f4SPavel Dovgalyuk void replay_finish_event(void); 123c92079f4SPavel Dovgalyuk /*! Reads data type from the file and stores it in the 124f186d64dSPavel Dovgalyuk data_kind variable. */ 125c92079f4SPavel Dovgalyuk void replay_fetch_data_kind(void); 126c92079f4SPavel Dovgalyuk 12713f26713SPavel Dovgalyuk /*! Advance replay_state.current_icount to the specified value. */ 12813f26713SPavel Dovgalyuk void replay_advance_current_icount(uint64_t current_icount); 12926bc60acSPavel Dovgalyuk /*! Saves queued events (like instructions and sound). */ 13026bc60acSPavel Dovgalyuk void replay_save_instructions(void); 13126bc60acSPavel Dovgalyuk 13226bc60acSPavel Dovgalyuk /*! Skips async events until some sync event will be found. 13326bc60acSPavel Dovgalyuk \return true, if event was found */ 13426bc60acSPavel Dovgalyuk bool replay_next_event_is(int event); 13526bc60acSPavel Dovgalyuk 1368eda206eSPavel Dovgalyuk /*! Reads next clock value from the file. 1378eda206eSPavel Dovgalyuk If clock kind read from the file is different from the parameter, 1388eda206eSPavel Dovgalyuk the value is not used. */ 139*fb72e779SRichard Henderson void replay_read_next_clock(ReplayClockKind kind); 1408eda206eSPavel Dovgalyuk 141c0c071d0SPavel Dovgalyuk /* Asynchronous events queue */ 142c0c071d0SPavel Dovgalyuk 143c0c071d0SPavel Dovgalyuk /*! Initializes events' processing internals */ 144c0c071d0SPavel Dovgalyuk void replay_init_events(void); 145c0c071d0SPavel Dovgalyuk /*! Clears internal data structures for events handling */ 146c0c071d0SPavel Dovgalyuk void replay_finish_events(void); 147c0c071d0SPavel Dovgalyuk /*! Returns true if there are any unsaved events in the queue */ 148c0c071d0SPavel Dovgalyuk bool replay_has_events(void); 149c0c071d0SPavel Dovgalyuk /*! Saves events from queue into the file */ 15060618e2dSPavel Dovgalyuk void replay_save_events(void); 151c0c071d0SPavel Dovgalyuk /*! Read events from the file into the input queue */ 15260618e2dSPavel Dovgalyuk void replay_read_events(void); 15333577b47SPavel Dovgalyuk /*! Adds specified async event to the queue */ 15433577b47SPavel Dovgalyuk void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque, 15533577b47SPavel Dovgalyuk void *opaque2, uint64_t id); 156c0c071d0SPavel Dovgalyuk 157ee312992SPavel Dovgalyuk /* Input events */ 158ee312992SPavel Dovgalyuk 159ee312992SPavel Dovgalyuk /*! Saves input event to the log */ 160ee312992SPavel Dovgalyuk void replay_save_input_event(InputEvent *evt); 161ee312992SPavel Dovgalyuk /*! Reads input event from the log */ 162ee312992SPavel Dovgalyuk InputEvent *replay_read_input_event(void); 163ee312992SPavel Dovgalyuk /*! Adds input event to the queue */ 164ee312992SPavel Dovgalyuk void replay_add_input_event(struct InputEvent *event); 165ee312992SPavel Dovgalyuk /*! Adds input sync event to the queue */ 166ee312992SPavel Dovgalyuk void replay_add_input_sync_event(void); 167ee312992SPavel Dovgalyuk 16833577b47SPavel Dovgalyuk /* Character devices */ 16933577b47SPavel Dovgalyuk 17033577b47SPavel Dovgalyuk /*! Called to run char device read event. */ 17133577b47SPavel Dovgalyuk void replay_event_char_read_run(void *opaque); 17233577b47SPavel Dovgalyuk /*! Writes char read event to the file. */ 17333577b47SPavel Dovgalyuk void replay_event_char_read_save(void *opaque); 17433577b47SPavel Dovgalyuk /*! Reads char event read from the file. */ 17533577b47SPavel Dovgalyuk void *replay_event_char_read_load(void); 17633577b47SPavel Dovgalyuk 177646c5478SPavel Dovgalyuk /* Network devices */ 178646c5478SPavel Dovgalyuk 179646c5478SPavel Dovgalyuk /*! Called to run network event. */ 180646c5478SPavel Dovgalyuk void replay_event_net_run(void *opaque); 181646c5478SPavel Dovgalyuk /*! Writes network event to the file. */ 182646c5478SPavel Dovgalyuk void replay_event_net_save(void *opaque); 183646c5478SPavel Dovgalyuk /*! Reads network from the file. */ 184646c5478SPavel Dovgalyuk void *replay_event_net_load(void); 185646c5478SPavel Dovgalyuk 186306e196fSPavel Dovgalyuk /* VMState-related functions */ 187306e196fSPavel Dovgalyuk 188306e196fSPavel Dovgalyuk /* Registers replay VMState. 189306e196fSPavel Dovgalyuk Should be called before virtual devices initialization 190306e196fSPavel Dovgalyuk to make cached timers available for post_load functions. */ 191306e196fSPavel Dovgalyuk void replay_vmstate_register(void); 192306e196fSPavel Dovgalyuk 193c92079f4SPavel Dovgalyuk #endif 194