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 1580be169cSAlex Bennée /* Any changes to order/number of events will need to bump REPLAY_VERSION */ 1626bc60acSPavel Dovgalyuk enum ReplayEvents { 1726bc60acSPavel Dovgalyuk /* for instruction event */ 1826bc60acSPavel Dovgalyuk EVENT_INSTRUCTION, 196f060969SPavel Dovgalyuk /* for software interrupt */ 206f060969SPavel Dovgalyuk EVENT_INTERRUPT, 216f060969SPavel Dovgalyuk /* for emulated exceptions */ 226f060969SPavel Dovgalyuk EVENT_EXCEPTION, 23c0c071d0SPavel Dovgalyuk /* for async events */ 24c0c071d0SPavel Dovgalyuk EVENT_ASYNC, 25802f045aSEric Blake /* for shutdown requests, range allows recovery of ShutdownCause */ 26b60c48a7SPavel Dovgalyuk EVENT_SHUTDOWN, 27802f045aSEric Blake EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX, 2833577b47SPavel Dovgalyuk /* for character device write event */ 2933577b47SPavel Dovgalyuk EVENT_CHAR_WRITE, 3033577b47SPavel Dovgalyuk /* for character device read all event */ 3133577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL, 3233577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL_ERROR, 333d4d16f4SPavel Dovgalyuk /* for audio out event */ 343d4d16f4SPavel Dovgalyuk EVENT_AUDIO_OUT, 353d4d16f4SPavel Dovgalyuk /* for audio in event */ 363d4d16f4SPavel Dovgalyuk EVENT_AUDIO_IN, 378eda206eSPavel Dovgalyuk /* for clock read/writes */ 388eda206eSPavel Dovgalyuk /* some of greater codes are reserved for clocks */ 398eda206eSPavel Dovgalyuk EVENT_CLOCK, 408eda206eSPavel Dovgalyuk EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1, 418bd7f71dSPavel Dovgalyuk /* for checkpoint event */ 428bd7f71dSPavel Dovgalyuk /* some of greater codes are reserved for checkpoints */ 438bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT, 448bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1, 457615936eSPavel Dovgalyuk /* end of log event */ 467615936eSPavel Dovgalyuk EVENT_END, 4726bc60acSPavel Dovgalyuk EVENT_COUNT 4826bc60acSPavel Dovgalyuk }; 4926bc60acSPavel Dovgalyuk 50c0c071d0SPavel Dovgalyuk /* Asynchronous events IDs */ 51c0c071d0SPavel Dovgalyuk 52c0c071d0SPavel Dovgalyuk enum ReplayAsyncEventKind { 538a354bd9SPavel Dovgalyuk REPLAY_ASYNC_EVENT_BH, 54ee312992SPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT, 55ee312992SPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT_SYNC, 5633577b47SPavel Dovgalyuk REPLAY_ASYNC_EVENT_CHAR_READ, 5763785678SPavel Dovgalyuk REPLAY_ASYNC_EVENT_BLOCK, 58646c5478SPavel Dovgalyuk REPLAY_ASYNC_EVENT_NET, 59c0c071d0SPavel Dovgalyuk REPLAY_ASYNC_COUNT 60c0c071d0SPavel Dovgalyuk }; 61c0c071d0SPavel Dovgalyuk 62c0c071d0SPavel Dovgalyuk typedef enum ReplayAsyncEventKind ReplayAsyncEventKind; 63c0c071d0SPavel Dovgalyuk 6426bc60acSPavel Dovgalyuk typedef struct ReplayState { 658eda206eSPavel Dovgalyuk /*! Cached clock values. */ 668eda206eSPavel Dovgalyuk int64_t cached_clock[REPLAY_CLOCK_COUNT]; 6726bc60acSPavel Dovgalyuk /*! Current step - number of processed instructions and timer events. */ 6826bc60acSPavel Dovgalyuk uint64_t current_step; 6926bc60acSPavel Dovgalyuk /*! Number of instructions to be executed before other events happen. */ 7026bc60acSPavel Dovgalyuk int instructions_count; 71f186d64dSPavel Dovgalyuk /*! Type of the currently executed event. */ 72f186d64dSPavel Dovgalyuk unsigned int data_kind; 73f186d64dSPavel Dovgalyuk /*! Flag which indicates that event is not processed yet. */ 74f186d64dSPavel Dovgalyuk unsigned int has_unread_data; 75306e196fSPavel Dovgalyuk /*! Temporary variable for saving current log offset. */ 76306e196fSPavel Dovgalyuk uint64_t file_offset; 776d0ceb80SPavel Dovgalyuk /*! Next block operation id. 786d0ceb80SPavel Dovgalyuk This counter is global, because requests from different 796d0ceb80SPavel Dovgalyuk block devices should not get overlapping ids. */ 806d0ceb80SPavel Dovgalyuk uint64_t block_request_id; 814b930d26SPavel Dovgalyuk /*! Prior value of the host clock */ 824b930d26SPavel Dovgalyuk uint64_t host_clock_last; 8326bc60acSPavel Dovgalyuk } ReplayState; 8426bc60acSPavel Dovgalyuk extern ReplayState replay_state; 8526bc60acSPavel Dovgalyuk 86c92079f4SPavel Dovgalyuk /* File for replay writing */ 87c92079f4SPavel Dovgalyuk extern FILE *replay_file; 88c92079f4SPavel Dovgalyuk 89c92079f4SPavel Dovgalyuk void replay_put_byte(uint8_t byte); 90c92079f4SPavel Dovgalyuk void replay_put_event(uint8_t event); 91c92079f4SPavel Dovgalyuk void replay_put_word(uint16_t word); 92c92079f4SPavel Dovgalyuk void replay_put_dword(uint32_t dword); 93c92079f4SPavel Dovgalyuk void replay_put_qword(int64_t qword); 94c92079f4SPavel Dovgalyuk void replay_put_array(const uint8_t *buf, size_t size); 95c92079f4SPavel Dovgalyuk 96c92079f4SPavel Dovgalyuk uint8_t replay_get_byte(void); 97c92079f4SPavel Dovgalyuk uint16_t replay_get_word(void); 98c92079f4SPavel Dovgalyuk uint32_t replay_get_dword(void); 99c92079f4SPavel Dovgalyuk int64_t replay_get_qword(void); 100c92079f4SPavel Dovgalyuk void replay_get_array(uint8_t *buf, size_t *size); 101c92079f4SPavel Dovgalyuk void replay_get_array_alloc(uint8_t **buf, size_t *size); 102c92079f4SPavel Dovgalyuk 103*a36544d3SAlex Bennée /* Mutex functions for protecting replay log file and ensuring 104*a36544d3SAlex Bennée * synchronisation between vCPU and main-loop threads. */ 105c16861efSPavel Dovgalyuk 106c16861efSPavel Dovgalyuk void replay_mutex_init(void); 107c16861efSPavel Dovgalyuk void replay_mutex_destroy(void); 108*a36544d3SAlex Bennée bool replay_mutex_locked(void); 109c16861efSPavel Dovgalyuk 110c92079f4SPavel Dovgalyuk /*! Checks error status of the file. */ 111c92079f4SPavel Dovgalyuk void replay_check_error(void); 112c92079f4SPavel Dovgalyuk 113c92079f4SPavel Dovgalyuk /*! Finishes processing of the replayed event and fetches 114c92079f4SPavel Dovgalyuk the next event from the log. */ 115c92079f4SPavel Dovgalyuk void replay_finish_event(void); 116c92079f4SPavel Dovgalyuk /*! Reads data type from the file and stores it in the 117f186d64dSPavel Dovgalyuk data_kind variable. */ 118c92079f4SPavel Dovgalyuk void replay_fetch_data_kind(void); 119c92079f4SPavel Dovgalyuk 12026bc60acSPavel Dovgalyuk /*! Saves queued events (like instructions and sound). */ 12126bc60acSPavel Dovgalyuk void replay_save_instructions(void); 12226bc60acSPavel Dovgalyuk 12326bc60acSPavel Dovgalyuk /*! Skips async events until some sync event will be found. 12426bc60acSPavel Dovgalyuk \return true, if event was found */ 12526bc60acSPavel Dovgalyuk bool replay_next_event_is(int event); 12626bc60acSPavel Dovgalyuk 1278eda206eSPavel Dovgalyuk /*! Reads next clock value from the file. 1288eda206eSPavel Dovgalyuk If clock kind read from the file is different from the parameter, 1298eda206eSPavel Dovgalyuk the value is not used. */ 1308eda206eSPavel Dovgalyuk void replay_read_next_clock(unsigned int kind); 1318eda206eSPavel Dovgalyuk 132c0c071d0SPavel Dovgalyuk /* Asynchronous events queue */ 133c0c071d0SPavel Dovgalyuk 134c0c071d0SPavel Dovgalyuk /*! Initializes events' processing internals */ 135c0c071d0SPavel Dovgalyuk void replay_init_events(void); 136c0c071d0SPavel Dovgalyuk /*! Clears internal data structures for events handling */ 137c0c071d0SPavel Dovgalyuk void replay_finish_events(void); 138c0c071d0SPavel Dovgalyuk /*! Flushes events queue */ 139c0c071d0SPavel Dovgalyuk void replay_flush_events(void); 140c0c071d0SPavel Dovgalyuk /*! Clears events list before loading new VM state */ 141c0c071d0SPavel Dovgalyuk void replay_clear_events(void); 142c0c071d0SPavel Dovgalyuk /*! Returns true if there are any unsaved events in the queue */ 143c0c071d0SPavel Dovgalyuk bool replay_has_events(void); 144c0c071d0SPavel Dovgalyuk /*! Saves events from queue into the file */ 145c0c071d0SPavel Dovgalyuk void replay_save_events(int checkpoint); 146c0c071d0SPavel Dovgalyuk /*! Read events from the file into the input queue */ 147c0c071d0SPavel Dovgalyuk void replay_read_events(int checkpoint); 14833577b47SPavel Dovgalyuk /*! Adds specified async event to the queue */ 14933577b47SPavel Dovgalyuk void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque, 15033577b47SPavel Dovgalyuk void *opaque2, uint64_t id); 151c0c071d0SPavel Dovgalyuk 152ee312992SPavel Dovgalyuk /* Input events */ 153ee312992SPavel Dovgalyuk 154ee312992SPavel Dovgalyuk /*! Saves input event to the log */ 155ee312992SPavel Dovgalyuk void replay_save_input_event(InputEvent *evt); 156ee312992SPavel Dovgalyuk /*! Reads input event from the log */ 157ee312992SPavel Dovgalyuk InputEvent *replay_read_input_event(void); 158ee312992SPavel Dovgalyuk /*! Adds input event to the queue */ 159ee312992SPavel Dovgalyuk void replay_add_input_event(struct InputEvent *event); 160ee312992SPavel Dovgalyuk /*! Adds input sync event to the queue */ 161ee312992SPavel Dovgalyuk void replay_add_input_sync_event(void); 162ee312992SPavel Dovgalyuk 16333577b47SPavel Dovgalyuk /* Character devices */ 16433577b47SPavel Dovgalyuk 16533577b47SPavel Dovgalyuk /*! Called to run char device read event. */ 16633577b47SPavel Dovgalyuk void replay_event_char_read_run(void *opaque); 16733577b47SPavel Dovgalyuk /*! Writes char read event to the file. */ 16833577b47SPavel Dovgalyuk void replay_event_char_read_save(void *opaque); 16933577b47SPavel Dovgalyuk /*! Reads char event read from the file. */ 17033577b47SPavel Dovgalyuk void *replay_event_char_read_load(void); 17133577b47SPavel Dovgalyuk 172646c5478SPavel Dovgalyuk /* Network devices */ 173646c5478SPavel Dovgalyuk 174646c5478SPavel Dovgalyuk /*! Called to run network event. */ 175646c5478SPavel Dovgalyuk void replay_event_net_run(void *opaque); 176646c5478SPavel Dovgalyuk /*! Writes network event to the file. */ 177646c5478SPavel Dovgalyuk void replay_event_net_save(void *opaque); 178646c5478SPavel Dovgalyuk /*! Reads network from the file. */ 179646c5478SPavel Dovgalyuk void *replay_event_net_load(void); 180646c5478SPavel Dovgalyuk 181306e196fSPavel Dovgalyuk /* VMState-related functions */ 182306e196fSPavel Dovgalyuk 183306e196fSPavel Dovgalyuk /* Registers replay VMState. 184306e196fSPavel Dovgalyuk Should be called before virtual devices initialization 185306e196fSPavel Dovgalyuk to make cached timers available for post_load functions. */ 186306e196fSPavel Dovgalyuk void replay_vmstate_register(void); 187306e196fSPavel Dovgalyuk 188c92079f4SPavel Dovgalyuk #endif 189