4 * Copyright (c) 2010-2016 Institute for System Programming
5 * of the Russian Academy of Sciences.
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "qemu/error-report.h"
14 #include "sysemu/replay.h"
15 #include "replay-internal.h"
16 #include "sysemu/sysemu.h"
17 #include "sysemu/char.h"
19 /* Char drivers that generate qemu_chr_be_write events
20 that should be saved into the log. */
21 static CharDriverState
**char_drivers
;
22 static int drivers_count
;
24 /* Char event attributes. */
25 typedef struct CharEvent
{
31 static int find_char_driver(CharDriverState
*chr
)
34 for ( ; i
< drivers_count
; ++i
) {
35 if (char_drivers
[i
] == chr
) {
42 void replay_register_char_driver(CharDriverState
*chr
)
44 if (replay_mode
== REPLAY_MODE_NONE
) {
47 char_drivers
= g_realloc(char_drivers
,
48 sizeof(*char_drivers
) * (drivers_count
+ 1));
49 char_drivers
[drivers_count
++] = chr
;
52 void replay_chr_be_write(CharDriverState
*s
, uint8_t *buf
, int len
)
54 CharEvent
*event
= g_malloc0(sizeof(CharEvent
));
56 event
->id
= find_char_driver(s
);
58 fprintf(stderr
, "Replay: cannot find char driver\n");
61 event
->buf
= g_malloc(len
);
62 memcpy(event
->buf
, buf
, len
);
65 replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ
, event
, NULL
, 0);
68 void replay_event_char_read_run(void *opaque
)
70 CharEvent
*event
= (CharEvent
*)opaque
;
72 qemu_chr_be_write_impl(char_drivers
[event
->id
], event
->buf
,
79 void replay_event_char_read_save(void *opaque
)
81 CharEvent
*event
= (CharEvent
*)opaque
;
83 replay_put_byte(event
->id
);
84 replay_put_array(event
->buf
, event
->len
);
87 void *replay_event_char_read_load(void)
89 CharEvent
*event
= g_malloc0(sizeof(CharEvent
));
91 event
->id
= replay_get_byte();
92 replay_get_array_alloc(&event
->buf
, &event
->len
);
97 void replay_char_write_event_save(int res
, int offset
)
99 replay_save_instructions();
101 replay_put_event(EVENT_CHAR_WRITE
);
102 replay_put_dword(res
);
103 replay_put_dword(offset
);
104 replay_mutex_unlock();
107 void replay_char_write_event_load(int *res
, int *offset
)
109 replay_account_executed_instructions();
111 if (replay_next_event_is(EVENT_CHAR_WRITE
)) {
112 *res
= replay_get_dword();
113 *offset
= replay_get_dword();
114 replay_finish_event();
115 replay_mutex_unlock();
117 replay_mutex_unlock();
118 error_report("Missing character write event in the replay log");
123 int replay_char_read_all_load(uint8_t *buf
)
126 if (replay_next_event_is(EVENT_CHAR_READ_ALL
)) {
129 replay_get_array(buf
, &size
);
130 replay_finish_event();
131 replay_mutex_unlock();
135 } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR
)) {
136 int res
= replay_get_dword();
137 replay_finish_event();
138 replay_mutex_unlock();
141 replay_mutex_unlock();
142 error_report("Missing character read all event in the replay log");
147 void replay_char_read_all_save_error(int res
)
150 replay_save_instructions();
152 replay_put_event(EVENT_CHAR_READ_ALL_ERROR
);
153 replay_put_dword(res
);
154 replay_mutex_unlock();
157 void replay_char_read_all_save_buf(uint8_t *buf
, int offset
)
159 replay_save_instructions();
161 replay_put_event(EVENT_CHAR_READ_ALL
);
162 replay_put_array(buf
, offset
);
163 replay_mutex_unlock();