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.
16 #include "qemu/osdep.h"
17 #include "qemu/error-report.h"
18 #include "sysemu/replay.h"
19 #include "replay-internal.h"
20 #include "sysemu/sysemu.h"
21 #include "sysemu/char.h"
23 /* Char drivers that generate qemu_chr_be_write events
24 that should be saved into the log. */
25 static CharDriverState
**char_drivers
;
26 static int drivers_count
;
28 /* Char event attributes. */
29 typedef struct CharEvent
{
35 static int find_char_driver(CharDriverState
*chr
)
38 for ( ; i
< drivers_count
; ++i
) {
39 if (char_drivers
[i
] == chr
) {
46 void replay_register_char_driver(CharDriverState
*chr
)
48 if (replay_mode
== REPLAY_MODE_NONE
) {
51 char_drivers
= g_realloc(char_drivers
,
52 sizeof(*char_drivers
) * (drivers_count
+ 1));
53 char_drivers
[drivers_count
++] = chr
;
56 void replay_chr_be_write(CharDriverState
*s
, uint8_t *buf
, int len
)
58 CharEvent
*event
= g_malloc0(sizeof(CharEvent
));
60 event
->id
= find_char_driver(s
);
62 fprintf(stderr
, "Replay: cannot find char driver\n");
65 event
->buf
= g_malloc(len
);
66 memcpy(event
->buf
, buf
, len
);
69 replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ
, event
, NULL
, 0);
72 void replay_event_char_read_run(void *opaque
)
74 CharEvent
*event
= (CharEvent
*)opaque
;
76 qemu_chr_be_write_impl(char_drivers
[event
->id
], event
->buf
,
83 void replay_event_char_read_save(void *opaque
)
85 CharEvent
*event
= (CharEvent
*)opaque
;
87 replay_put_byte(event
->id
);
88 replay_put_array(event
->buf
, event
->len
);
91 void *replay_event_char_read_load(void)
93 CharEvent
*event
= g_malloc0(sizeof(CharEvent
));
95 event
->id
= replay_get_byte();
96 replay_get_array_alloc(&event
->buf
, &event
->len
);
101 void replay_char_write_event_save(int res
, int offset
)
103 replay_save_instructions();
105 replay_put_event(EVENT_CHAR_WRITE
);
106 replay_put_dword(res
);
107 replay_put_dword(offset
);
108 replay_mutex_unlock();
111 void replay_char_write_event_load(int *res
, int *offset
)
113 replay_account_executed_instructions();
115 if (replay_next_event_is(EVENT_CHAR_WRITE
)) {
116 *res
= replay_get_dword();
117 *offset
= replay_get_dword();
118 replay_finish_event();
119 replay_mutex_unlock();
121 replay_mutex_unlock();
122 error_report("Missing character write event in the replay log");
127 int replay_char_read_all_load(uint8_t *buf
)
130 if (replay_next_event_is(EVENT_CHAR_READ_ALL
)) {
133 replay_get_array(buf
, &size
);
134 replay_finish_event();
135 replay_mutex_unlock();
139 } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR
)) {
140 int res
= replay_get_dword();
141 replay_finish_event();
142 replay_mutex_unlock();
145 replay_mutex_unlock();
146 error_report("Missing character read all event in the replay log");
151 void replay_char_read_all_save_error(int res
)
154 replay_save_instructions();
156 replay_put_event(EVENT_CHAR_READ_ALL_ERROR
);
157 replay_put_dword(res
);
158 replay_mutex_unlock();
161 void replay_char_read_all_save_buf(uint8_t *buf
, int offset
)
163 replay_save_instructions();
165 replay_put_event(EVENT_CHAR_READ_ALL
);
166 replay_put_array(buf
, offset
);
167 replay_mutex_unlock();