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 15c92079f4SPavel Dovgalyuk 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, 25b60c48a7SPavel Dovgalyuk /* for shutdown request */ 26b60c48a7SPavel Dovgalyuk EVENT_SHUTDOWN, 2733577b47SPavel Dovgalyuk /* for character device write event */ 2833577b47SPavel Dovgalyuk EVENT_CHAR_WRITE, 2933577b47SPavel Dovgalyuk /* for character device read all event */ 3033577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL, 3133577b47SPavel Dovgalyuk EVENT_CHAR_READ_ALL_ERROR, 328eda206eSPavel Dovgalyuk /* for clock read/writes */ 338eda206eSPavel Dovgalyuk /* some of greater codes are reserved for clocks */ 348eda206eSPavel Dovgalyuk EVENT_CLOCK, 358eda206eSPavel Dovgalyuk EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1, 368bd7f71dSPavel Dovgalyuk /* for checkpoint event */ 378bd7f71dSPavel Dovgalyuk /* some of greater codes are reserved for checkpoints */ 388bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT, 398bd7f71dSPavel Dovgalyuk EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1, 407615936eSPavel Dovgalyuk /* end of log event */ 417615936eSPavel Dovgalyuk EVENT_END, 4226bc60acSPavel Dovgalyuk EVENT_COUNT 4326bc60acSPavel Dovgalyuk }; 4426bc60acSPavel Dovgalyuk 45c0c071d0SPavel Dovgalyuk /* Asynchronous events IDs */ 46c0c071d0SPavel Dovgalyuk 47c0c071d0SPavel Dovgalyuk enum ReplayAsyncEventKind { 488a354bd9SPavel Dovgalyuk REPLAY_ASYNC_EVENT_BH, 49ee312992SPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT, 50ee312992SPavel Dovgalyuk REPLAY_ASYNC_EVENT_INPUT_SYNC, 5133577b47SPavel Dovgalyuk REPLAY_ASYNC_EVENT_CHAR_READ, 5263785678SPavel Dovgalyuk REPLAY_ASYNC_EVENT_BLOCK, 53c0c071d0SPavel Dovgalyuk REPLAY_ASYNC_COUNT 54c0c071d0SPavel Dovgalyuk }; 55c0c071d0SPavel Dovgalyuk 56c0c071d0SPavel Dovgalyuk typedef enum ReplayAsyncEventKind ReplayAsyncEventKind; 57c0c071d0SPavel Dovgalyuk 5826bc60acSPavel Dovgalyuk typedef struct ReplayState { 598eda206eSPavel Dovgalyuk /*! Cached clock values. */ 608eda206eSPavel Dovgalyuk int64_t cached_clock[REPLAY_CLOCK_COUNT]; 6126bc60acSPavel Dovgalyuk /*! Current step - number of processed instructions and timer events. */ 6226bc60acSPavel Dovgalyuk uint64_t current_step; 6326bc60acSPavel Dovgalyuk /*! Number of instructions to be executed before other events happen. */ 6426bc60acSPavel Dovgalyuk int instructions_count; 65*f186d64dSPavel Dovgalyuk /*! Type of the currently executed event. */ 66*f186d64dSPavel Dovgalyuk unsigned int data_kind; 67*f186d64dSPavel Dovgalyuk /*! Flag which indicates that event is not processed yet. */ 68*f186d64dSPavel Dovgalyuk unsigned int has_unread_data; 6926bc60acSPavel Dovgalyuk } ReplayState; 7026bc60acSPavel Dovgalyuk extern ReplayState replay_state; 7126bc60acSPavel Dovgalyuk 72c92079f4SPavel Dovgalyuk /* File for replay writing */ 73c92079f4SPavel Dovgalyuk extern FILE *replay_file; 74c92079f4SPavel Dovgalyuk 75c92079f4SPavel Dovgalyuk void replay_put_byte(uint8_t byte); 76c92079f4SPavel Dovgalyuk void replay_put_event(uint8_t event); 77c92079f4SPavel Dovgalyuk void replay_put_word(uint16_t word); 78c92079f4SPavel Dovgalyuk void replay_put_dword(uint32_t dword); 79c92079f4SPavel Dovgalyuk void replay_put_qword(int64_t qword); 80c92079f4SPavel Dovgalyuk void replay_put_array(const uint8_t *buf, size_t size); 81c92079f4SPavel Dovgalyuk 82c92079f4SPavel Dovgalyuk uint8_t replay_get_byte(void); 83c92079f4SPavel Dovgalyuk uint16_t replay_get_word(void); 84c92079f4SPavel Dovgalyuk uint32_t replay_get_dword(void); 85c92079f4SPavel Dovgalyuk int64_t replay_get_qword(void); 86c92079f4SPavel Dovgalyuk void replay_get_array(uint8_t *buf, size_t *size); 87c92079f4SPavel Dovgalyuk void replay_get_array_alloc(uint8_t **buf, size_t *size); 88c92079f4SPavel Dovgalyuk 89c16861efSPavel Dovgalyuk /* Mutex functions for protecting replay log file */ 90c16861efSPavel Dovgalyuk 91c16861efSPavel Dovgalyuk void replay_mutex_init(void); 92c16861efSPavel Dovgalyuk void replay_mutex_destroy(void); 93c16861efSPavel Dovgalyuk void replay_mutex_lock(void); 94c16861efSPavel Dovgalyuk void replay_mutex_unlock(void); 95c16861efSPavel Dovgalyuk 96c92079f4SPavel Dovgalyuk /*! Checks error status of the file. */ 97c92079f4SPavel Dovgalyuk void replay_check_error(void); 98c92079f4SPavel Dovgalyuk 99c92079f4SPavel Dovgalyuk /*! Finishes processing of the replayed event and fetches 100c92079f4SPavel Dovgalyuk the next event from the log. */ 101c92079f4SPavel Dovgalyuk void replay_finish_event(void); 102c92079f4SPavel Dovgalyuk /*! Reads data type from the file and stores it in the 103*f186d64dSPavel Dovgalyuk data_kind variable. */ 104c92079f4SPavel Dovgalyuk void replay_fetch_data_kind(void); 105c92079f4SPavel Dovgalyuk 10626bc60acSPavel Dovgalyuk /*! Saves queued events (like instructions and sound). */ 10726bc60acSPavel Dovgalyuk void replay_save_instructions(void); 10826bc60acSPavel Dovgalyuk 10926bc60acSPavel Dovgalyuk /*! Skips async events until some sync event will be found. 11026bc60acSPavel Dovgalyuk \return true, if event was found */ 11126bc60acSPavel Dovgalyuk bool replay_next_event_is(int event); 11226bc60acSPavel Dovgalyuk 1138eda206eSPavel Dovgalyuk /*! Reads next clock value from the file. 1148eda206eSPavel Dovgalyuk If clock kind read from the file is different from the parameter, 1158eda206eSPavel Dovgalyuk the value is not used. */ 1168eda206eSPavel Dovgalyuk void replay_read_next_clock(unsigned int kind); 1178eda206eSPavel Dovgalyuk 118c0c071d0SPavel Dovgalyuk /* Asynchronous events queue */ 119c0c071d0SPavel Dovgalyuk 120c0c071d0SPavel Dovgalyuk /*! Initializes events' processing internals */ 121c0c071d0SPavel Dovgalyuk void replay_init_events(void); 122c0c071d0SPavel Dovgalyuk /*! Clears internal data structures for events handling */ 123c0c071d0SPavel Dovgalyuk void replay_finish_events(void); 124c0c071d0SPavel Dovgalyuk /*! Enables storing events in the queue */ 125c0c071d0SPavel Dovgalyuk void replay_enable_events(void); 126c0c071d0SPavel Dovgalyuk /*! Flushes events queue */ 127c0c071d0SPavel Dovgalyuk void replay_flush_events(void); 128c0c071d0SPavel Dovgalyuk /*! Clears events list before loading new VM state */ 129c0c071d0SPavel Dovgalyuk void replay_clear_events(void); 130c0c071d0SPavel Dovgalyuk /*! Returns true if there are any unsaved events in the queue */ 131c0c071d0SPavel Dovgalyuk bool replay_has_events(void); 132c0c071d0SPavel Dovgalyuk /*! Saves events from queue into the file */ 133c0c071d0SPavel Dovgalyuk void replay_save_events(int checkpoint); 134c0c071d0SPavel Dovgalyuk /*! Read events from the file into the input queue */ 135c0c071d0SPavel Dovgalyuk void replay_read_events(int checkpoint); 13633577b47SPavel Dovgalyuk /*! Adds specified async event to the queue */ 13733577b47SPavel Dovgalyuk void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque, 13833577b47SPavel Dovgalyuk void *opaque2, uint64_t id); 139c0c071d0SPavel Dovgalyuk 140ee312992SPavel Dovgalyuk /* Input events */ 141ee312992SPavel Dovgalyuk 142ee312992SPavel Dovgalyuk /*! Saves input event to the log */ 143ee312992SPavel Dovgalyuk void replay_save_input_event(InputEvent *evt); 144ee312992SPavel Dovgalyuk /*! Reads input event from the log */ 145ee312992SPavel Dovgalyuk InputEvent *replay_read_input_event(void); 146ee312992SPavel Dovgalyuk /*! Adds input event to the queue */ 147ee312992SPavel Dovgalyuk void replay_add_input_event(struct InputEvent *event); 148ee312992SPavel Dovgalyuk /*! Adds input sync event to the queue */ 149ee312992SPavel Dovgalyuk void replay_add_input_sync_event(void); 150ee312992SPavel Dovgalyuk 15133577b47SPavel Dovgalyuk /* Character devices */ 15233577b47SPavel Dovgalyuk 15333577b47SPavel Dovgalyuk /*! Called to run char device read event. */ 15433577b47SPavel Dovgalyuk void replay_event_char_read_run(void *opaque); 15533577b47SPavel Dovgalyuk /*! Writes char read event to the file. */ 15633577b47SPavel Dovgalyuk void replay_event_char_read_save(void *opaque); 15733577b47SPavel Dovgalyuk /*! Reads char event read from the file. */ 15833577b47SPavel Dovgalyuk void *replay_event_char_read_load(void); 15933577b47SPavel Dovgalyuk 160c92079f4SPavel Dovgalyuk #endif 161