root / vmstate.c @ feature-archipelago
History | View | Annotate | Download (15.5 kB)
1 | b6fcfa59 | Eduardo Habkost | #include "qemu-common.h" |
---|---|---|---|
2 | b6fcfa59 | Eduardo Habkost | #include "migration/migration.h" |
3 | b6fcfa59 | Eduardo Habkost | #include "migration/qemu-file.h" |
4 | b6fcfa59 | Eduardo Habkost | #include "migration/vmstate.h" |
5 | b6fcfa59 | Eduardo Habkost | #include "qemu/bitops.h" |
6 | b6fcfa59 | Eduardo Habkost | |
7 | b6fcfa59 | Eduardo Habkost | static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, |
8 | b6fcfa59 | Eduardo Habkost | void *opaque);
|
9 | b6fcfa59 | Eduardo Habkost | static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, |
10 | b6fcfa59 | Eduardo Habkost | void *opaque);
|
11 | b6fcfa59 | Eduardo Habkost | |
12 | b6fcfa59 | Eduardo Habkost | int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, |
13 | b6fcfa59 | Eduardo Habkost | void *opaque, int version_id) |
14 | b6fcfa59 | Eduardo Habkost | { |
15 | b6fcfa59 | Eduardo Habkost | VMStateField *field = vmsd->fields; |
16 | b6fcfa59 | Eduardo Habkost | int ret;
|
17 | b6fcfa59 | Eduardo Habkost | |
18 | b6fcfa59 | Eduardo Habkost | if (version_id > vmsd->version_id) {
|
19 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
20 | b6fcfa59 | Eduardo Habkost | } |
21 | b6fcfa59 | Eduardo Habkost | if (version_id < vmsd->minimum_version_id_old) {
|
22 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
23 | b6fcfa59 | Eduardo Habkost | } |
24 | b6fcfa59 | Eduardo Habkost | if (version_id < vmsd->minimum_version_id) {
|
25 | b6fcfa59 | Eduardo Habkost | return vmsd->load_state_old(f, opaque, version_id);
|
26 | b6fcfa59 | Eduardo Habkost | } |
27 | b6fcfa59 | Eduardo Habkost | if (vmsd->pre_load) {
|
28 | b6fcfa59 | Eduardo Habkost | int ret = vmsd->pre_load(opaque);
|
29 | b6fcfa59 | Eduardo Habkost | if (ret) {
|
30 | b6fcfa59 | Eduardo Habkost | return ret;
|
31 | b6fcfa59 | Eduardo Habkost | } |
32 | b6fcfa59 | Eduardo Habkost | } |
33 | b6fcfa59 | Eduardo Habkost | while (field->name) {
|
34 | b6fcfa59 | Eduardo Habkost | if ((field->field_exists &&
|
35 | b6fcfa59 | Eduardo Habkost | field->field_exists(opaque, version_id)) || |
36 | b6fcfa59 | Eduardo Habkost | (!field->field_exists && |
37 | b6fcfa59 | Eduardo Habkost | field->version_id <= version_id)) { |
38 | b6fcfa59 | Eduardo Habkost | void *base_addr = opaque + field->offset;
|
39 | b6fcfa59 | Eduardo Habkost | int i, n_elems = 1; |
40 | b6fcfa59 | Eduardo Habkost | int size = field->size;
|
41 | b6fcfa59 | Eduardo Habkost | |
42 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_VBUFFER) {
|
43 | b6fcfa59 | Eduardo Habkost | size = *(int32_t *)(opaque+field->size_offset); |
44 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_MULTIPLY) {
|
45 | b6fcfa59 | Eduardo Habkost | size *= field->size; |
46 | b6fcfa59 | Eduardo Habkost | } |
47 | b6fcfa59 | Eduardo Habkost | } |
48 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_ARRAY) {
|
49 | b6fcfa59 | Eduardo Habkost | n_elems = field->num; |
50 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_INT32) { |
51 | b6fcfa59 | Eduardo Habkost | n_elems = *(int32_t *)(opaque+field->num_offset); |
52 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT32) { |
53 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint32_t *)(opaque+field->num_offset); |
54 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT16) { |
55 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint16_t *)(opaque+field->num_offset); |
56 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT8) { |
57 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint8_t *)(opaque+field->num_offset); |
58 | b6fcfa59 | Eduardo Habkost | } |
59 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_POINTER) {
|
60 | b6fcfa59 | Eduardo Habkost | base_addr = *(void **)base_addr + field->start;
|
61 | b6fcfa59 | Eduardo Habkost | } |
62 | b6fcfa59 | Eduardo Habkost | for (i = 0; i < n_elems; i++) { |
63 | b6fcfa59 | Eduardo Habkost | void *addr = base_addr + size * i;
|
64 | b6fcfa59 | Eduardo Habkost | |
65 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_ARRAY_OF_POINTER) {
|
66 | b6fcfa59 | Eduardo Habkost | addr = *(void **)addr;
|
67 | b6fcfa59 | Eduardo Habkost | } |
68 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_STRUCT) {
|
69 | b6fcfa59 | Eduardo Habkost | ret = vmstate_load_state(f, field->vmsd, addr, |
70 | b6fcfa59 | Eduardo Habkost | field->vmsd->version_id); |
71 | b6fcfa59 | Eduardo Habkost | } else {
|
72 | b6fcfa59 | Eduardo Habkost | ret = field->info->get(f, addr, size); |
73 | b6fcfa59 | Eduardo Habkost | |
74 | b6fcfa59 | Eduardo Habkost | } |
75 | b6fcfa59 | Eduardo Habkost | if (ret < 0) { |
76 | b6fcfa59 | Eduardo Habkost | return ret;
|
77 | b6fcfa59 | Eduardo Habkost | } |
78 | b6fcfa59 | Eduardo Habkost | } |
79 | b6fcfa59 | Eduardo Habkost | } |
80 | b6fcfa59 | Eduardo Habkost | field++; |
81 | b6fcfa59 | Eduardo Habkost | } |
82 | b6fcfa59 | Eduardo Habkost | ret = vmstate_subsection_load(f, vmsd, opaque); |
83 | b6fcfa59 | Eduardo Habkost | if (ret != 0) { |
84 | b6fcfa59 | Eduardo Habkost | return ret;
|
85 | b6fcfa59 | Eduardo Habkost | } |
86 | b6fcfa59 | Eduardo Habkost | if (vmsd->post_load) {
|
87 | b6fcfa59 | Eduardo Habkost | return vmsd->post_load(opaque, version_id);
|
88 | b6fcfa59 | Eduardo Habkost | } |
89 | b6fcfa59 | Eduardo Habkost | return 0; |
90 | b6fcfa59 | Eduardo Habkost | } |
91 | b6fcfa59 | Eduardo Habkost | |
92 | b6fcfa59 | Eduardo Habkost | void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, |
93 | b6fcfa59 | Eduardo Habkost | void *opaque)
|
94 | b6fcfa59 | Eduardo Habkost | { |
95 | b6fcfa59 | Eduardo Habkost | VMStateField *field = vmsd->fields; |
96 | b6fcfa59 | Eduardo Habkost | |
97 | b6fcfa59 | Eduardo Habkost | if (vmsd->pre_save) {
|
98 | b6fcfa59 | Eduardo Habkost | vmsd->pre_save(opaque); |
99 | b6fcfa59 | Eduardo Habkost | } |
100 | b6fcfa59 | Eduardo Habkost | while (field->name) {
|
101 | b6fcfa59 | Eduardo Habkost | if (!field->field_exists ||
|
102 | b6fcfa59 | Eduardo Habkost | field->field_exists(opaque, vmsd->version_id)) { |
103 | b6fcfa59 | Eduardo Habkost | void *base_addr = opaque + field->offset;
|
104 | b6fcfa59 | Eduardo Habkost | int i, n_elems = 1; |
105 | b6fcfa59 | Eduardo Habkost | int size = field->size;
|
106 | b6fcfa59 | Eduardo Habkost | |
107 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_VBUFFER) {
|
108 | b6fcfa59 | Eduardo Habkost | size = *(int32_t *)(opaque+field->size_offset); |
109 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_MULTIPLY) {
|
110 | b6fcfa59 | Eduardo Habkost | size *= field->size; |
111 | b6fcfa59 | Eduardo Habkost | } |
112 | b6fcfa59 | Eduardo Habkost | } |
113 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_ARRAY) {
|
114 | b6fcfa59 | Eduardo Habkost | n_elems = field->num; |
115 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_INT32) { |
116 | b6fcfa59 | Eduardo Habkost | n_elems = *(int32_t *)(opaque+field->num_offset); |
117 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT32) { |
118 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint32_t *)(opaque+field->num_offset); |
119 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT16) { |
120 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint16_t *)(opaque+field->num_offset); |
121 | b6fcfa59 | Eduardo Habkost | } else if (field->flags & VMS_VARRAY_UINT8) { |
122 | b6fcfa59 | Eduardo Habkost | n_elems = *(uint8_t *)(opaque+field->num_offset); |
123 | b6fcfa59 | Eduardo Habkost | } |
124 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_POINTER) {
|
125 | b6fcfa59 | Eduardo Habkost | base_addr = *(void **)base_addr + field->start;
|
126 | b6fcfa59 | Eduardo Habkost | } |
127 | b6fcfa59 | Eduardo Habkost | for (i = 0; i < n_elems; i++) { |
128 | b6fcfa59 | Eduardo Habkost | void *addr = base_addr + size * i;
|
129 | b6fcfa59 | Eduardo Habkost | |
130 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_ARRAY_OF_POINTER) {
|
131 | b6fcfa59 | Eduardo Habkost | addr = *(void **)addr;
|
132 | b6fcfa59 | Eduardo Habkost | } |
133 | b6fcfa59 | Eduardo Habkost | if (field->flags & VMS_STRUCT) {
|
134 | b6fcfa59 | Eduardo Habkost | vmstate_save_state(f, field->vmsd, addr); |
135 | b6fcfa59 | Eduardo Habkost | } else {
|
136 | b6fcfa59 | Eduardo Habkost | field->info->put(f, addr, size); |
137 | b6fcfa59 | Eduardo Habkost | } |
138 | b6fcfa59 | Eduardo Habkost | } |
139 | b6fcfa59 | Eduardo Habkost | } |
140 | b6fcfa59 | Eduardo Habkost | field++; |
141 | b6fcfa59 | Eduardo Habkost | } |
142 | b6fcfa59 | Eduardo Habkost | vmstate_subsection_save(f, vmsd, opaque); |
143 | b6fcfa59 | Eduardo Habkost | } |
144 | b6fcfa59 | Eduardo Habkost | |
145 | b6fcfa59 | Eduardo Habkost | static const VMStateDescription * |
146 | b6fcfa59 | Eduardo Habkost | vmstate_get_subsection(const VMStateSubsection *sub, char *idstr) |
147 | b6fcfa59 | Eduardo Habkost | { |
148 | b6fcfa59 | Eduardo Habkost | while (sub && sub->needed) {
|
149 | b6fcfa59 | Eduardo Habkost | if (strcmp(idstr, sub->vmsd->name) == 0) { |
150 | b6fcfa59 | Eduardo Habkost | return sub->vmsd;
|
151 | b6fcfa59 | Eduardo Habkost | } |
152 | b6fcfa59 | Eduardo Habkost | sub++; |
153 | b6fcfa59 | Eduardo Habkost | } |
154 | b6fcfa59 | Eduardo Habkost | return NULL; |
155 | b6fcfa59 | Eduardo Habkost | } |
156 | b6fcfa59 | Eduardo Habkost | |
157 | b6fcfa59 | Eduardo Habkost | static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, |
158 | b6fcfa59 | Eduardo Habkost | void *opaque)
|
159 | b6fcfa59 | Eduardo Habkost | { |
160 | b6fcfa59 | Eduardo Habkost | while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) { |
161 | b6fcfa59 | Eduardo Habkost | char idstr[256]; |
162 | b6fcfa59 | Eduardo Habkost | int ret;
|
163 | b6fcfa59 | Eduardo Habkost | uint8_t version_id, len, size; |
164 | b6fcfa59 | Eduardo Habkost | const VMStateDescription *sub_vmsd;
|
165 | b6fcfa59 | Eduardo Habkost | |
166 | b6fcfa59 | Eduardo Habkost | len = qemu_peek_byte(f, 1);
|
167 | b6fcfa59 | Eduardo Habkost | if (len < strlen(vmsd->name) + 1) { |
168 | b6fcfa59 | Eduardo Habkost | /* subsection name has be be "section_name/a" */
|
169 | b6fcfa59 | Eduardo Habkost | return 0; |
170 | b6fcfa59 | Eduardo Habkost | } |
171 | b6fcfa59 | Eduardo Habkost | size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
|
172 | b6fcfa59 | Eduardo Habkost | if (size != len) {
|
173 | b6fcfa59 | Eduardo Habkost | return 0; |
174 | b6fcfa59 | Eduardo Habkost | } |
175 | b6fcfa59 | Eduardo Habkost | idstr[size] = 0;
|
176 | b6fcfa59 | Eduardo Habkost | |
177 | b6fcfa59 | Eduardo Habkost | if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) { |
178 | b6fcfa59 | Eduardo Habkost | /* it don't have a valid subsection name */
|
179 | b6fcfa59 | Eduardo Habkost | return 0; |
180 | b6fcfa59 | Eduardo Habkost | } |
181 | b6fcfa59 | Eduardo Habkost | sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); |
182 | b6fcfa59 | Eduardo Habkost | if (sub_vmsd == NULL) { |
183 | b6fcfa59 | Eduardo Habkost | return -ENOENT;
|
184 | b6fcfa59 | Eduardo Habkost | } |
185 | b6fcfa59 | Eduardo Habkost | qemu_file_skip(f, 1); /* subsection */ |
186 | b6fcfa59 | Eduardo Habkost | qemu_file_skip(f, 1); /* len */ |
187 | b6fcfa59 | Eduardo Habkost | qemu_file_skip(f, len); /* idstr */
|
188 | b6fcfa59 | Eduardo Habkost | version_id = qemu_get_be32(f); |
189 | b6fcfa59 | Eduardo Habkost | |
190 | b6fcfa59 | Eduardo Habkost | ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); |
191 | b6fcfa59 | Eduardo Habkost | if (ret) {
|
192 | b6fcfa59 | Eduardo Habkost | return ret;
|
193 | b6fcfa59 | Eduardo Habkost | } |
194 | b6fcfa59 | Eduardo Habkost | } |
195 | b6fcfa59 | Eduardo Habkost | return 0; |
196 | b6fcfa59 | Eduardo Habkost | } |
197 | b6fcfa59 | Eduardo Habkost | |
198 | b6fcfa59 | Eduardo Habkost | static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, |
199 | b6fcfa59 | Eduardo Habkost | void *opaque)
|
200 | b6fcfa59 | Eduardo Habkost | { |
201 | b6fcfa59 | Eduardo Habkost | const VMStateSubsection *sub = vmsd->subsections;
|
202 | b6fcfa59 | Eduardo Habkost | |
203 | b6fcfa59 | Eduardo Habkost | while (sub && sub->needed) {
|
204 | b6fcfa59 | Eduardo Habkost | if (sub->needed(opaque)) {
|
205 | b6fcfa59 | Eduardo Habkost | const VMStateDescription *vmsd = sub->vmsd;
|
206 | b6fcfa59 | Eduardo Habkost | uint8_t len; |
207 | b6fcfa59 | Eduardo Habkost | |
208 | b6fcfa59 | Eduardo Habkost | qemu_put_byte(f, QEMU_VM_SUBSECTION); |
209 | b6fcfa59 | Eduardo Habkost | len = strlen(vmsd->name); |
210 | b6fcfa59 | Eduardo Habkost | qemu_put_byte(f, len); |
211 | b6fcfa59 | Eduardo Habkost | qemu_put_buffer(f, (uint8_t *)vmsd->name, len); |
212 | b6fcfa59 | Eduardo Habkost | qemu_put_be32(f, vmsd->version_id); |
213 | b6fcfa59 | Eduardo Habkost | vmstate_save_state(f, vmsd, opaque); |
214 | b6fcfa59 | Eduardo Habkost | } |
215 | b6fcfa59 | Eduardo Habkost | sub++; |
216 | b6fcfa59 | Eduardo Habkost | } |
217 | b6fcfa59 | Eduardo Habkost | } |
218 | b6fcfa59 | Eduardo Habkost | |
219 | b6fcfa59 | Eduardo Habkost | /* bool */
|
220 | b6fcfa59 | Eduardo Habkost | |
221 | b6fcfa59 | Eduardo Habkost | static int get_bool(QEMUFile *f, void *pv, size_t size) |
222 | b6fcfa59 | Eduardo Habkost | { |
223 | b6fcfa59 | Eduardo Habkost | bool *v = pv;
|
224 | b6fcfa59 | Eduardo Habkost | *v = qemu_get_byte(f); |
225 | b6fcfa59 | Eduardo Habkost | return 0; |
226 | b6fcfa59 | Eduardo Habkost | } |
227 | b6fcfa59 | Eduardo Habkost | |
228 | b6fcfa59 | Eduardo Habkost | static void put_bool(QEMUFile *f, void *pv, size_t size) |
229 | b6fcfa59 | Eduardo Habkost | { |
230 | b6fcfa59 | Eduardo Habkost | bool *v = pv;
|
231 | b6fcfa59 | Eduardo Habkost | qemu_put_byte(f, *v); |
232 | b6fcfa59 | Eduardo Habkost | } |
233 | b6fcfa59 | Eduardo Habkost | |
234 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_bool = {
|
235 | b6fcfa59 | Eduardo Habkost | .name = "bool",
|
236 | b6fcfa59 | Eduardo Habkost | .get = get_bool, |
237 | b6fcfa59 | Eduardo Habkost | .put = put_bool, |
238 | b6fcfa59 | Eduardo Habkost | }; |
239 | b6fcfa59 | Eduardo Habkost | |
240 | b6fcfa59 | Eduardo Habkost | /* 8 bit int */
|
241 | b6fcfa59 | Eduardo Habkost | |
242 | b6fcfa59 | Eduardo Habkost | static int get_int8(QEMUFile *f, void *pv, size_t size) |
243 | b6fcfa59 | Eduardo Habkost | { |
244 | b6fcfa59 | Eduardo Habkost | int8_t *v = pv; |
245 | b6fcfa59 | Eduardo Habkost | qemu_get_s8s(f, v); |
246 | b6fcfa59 | Eduardo Habkost | return 0; |
247 | b6fcfa59 | Eduardo Habkost | } |
248 | b6fcfa59 | Eduardo Habkost | |
249 | b6fcfa59 | Eduardo Habkost | static void put_int8(QEMUFile *f, void *pv, size_t size) |
250 | b6fcfa59 | Eduardo Habkost | { |
251 | b6fcfa59 | Eduardo Habkost | int8_t *v = pv; |
252 | b6fcfa59 | Eduardo Habkost | qemu_put_s8s(f, v); |
253 | b6fcfa59 | Eduardo Habkost | } |
254 | b6fcfa59 | Eduardo Habkost | |
255 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int8 = {
|
256 | b6fcfa59 | Eduardo Habkost | .name = "int8",
|
257 | b6fcfa59 | Eduardo Habkost | .get = get_int8, |
258 | b6fcfa59 | Eduardo Habkost | .put = put_int8, |
259 | b6fcfa59 | Eduardo Habkost | }; |
260 | b6fcfa59 | Eduardo Habkost | |
261 | b6fcfa59 | Eduardo Habkost | /* 16 bit int */
|
262 | b6fcfa59 | Eduardo Habkost | |
263 | b6fcfa59 | Eduardo Habkost | static int get_int16(QEMUFile *f, void *pv, size_t size) |
264 | b6fcfa59 | Eduardo Habkost | { |
265 | b6fcfa59 | Eduardo Habkost | int16_t *v = pv; |
266 | b6fcfa59 | Eduardo Habkost | qemu_get_sbe16s(f, v); |
267 | b6fcfa59 | Eduardo Habkost | return 0; |
268 | b6fcfa59 | Eduardo Habkost | } |
269 | b6fcfa59 | Eduardo Habkost | |
270 | b6fcfa59 | Eduardo Habkost | static void put_int16(QEMUFile *f, void *pv, size_t size) |
271 | b6fcfa59 | Eduardo Habkost | { |
272 | b6fcfa59 | Eduardo Habkost | int16_t *v = pv; |
273 | b6fcfa59 | Eduardo Habkost | qemu_put_sbe16s(f, v); |
274 | b6fcfa59 | Eduardo Habkost | } |
275 | b6fcfa59 | Eduardo Habkost | |
276 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int16 = {
|
277 | b6fcfa59 | Eduardo Habkost | .name = "int16",
|
278 | b6fcfa59 | Eduardo Habkost | .get = get_int16, |
279 | b6fcfa59 | Eduardo Habkost | .put = put_int16, |
280 | b6fcfa59 | Eduardo Habkost | }; |
281 | b6fcfa59 | Eduardo Habkost | |
282 | b6fcfa59 | Eduardo Habkost | /* 32 bit int */
|
283 | b6fcfa59 | Eduardo Habkost | |
284 | b6fcfa59 | Eduardo Habkost | static int get_int32(QEMUFile *f, void *pv, size_t size) |
285 | b6fcfa59 | Eduardo Habkost | { |
286 | b6fcfa59 | Eduardo Habkost | int32_t *v = pv; |
287 | b6fcfa59 | Eduardo Habkost | qemu_get_sbe32s(f, v); |
288 | b6fcfa59 | Eduardo Habkost | return 0; |
289 | b6fcfa59 | Eduardo Habkost | } |
290 | b6fcfa59 | Eduardo Habkost | |
291 | b6fcfa59 | Eduardo Habkost | static void put_int32(QEMUFile *f, void *pv, size_t size) |
292 | b6fcfa59 | Eduardo Habkost | { |
293 | b6fcfa59 | Eduardo Habkost | int32_t *v = pv; |
294 | b6fcfa59 | Eduardo Habkost | qemu_put_sbe32s(f, v); |
295 | b6fcfa59 | Eduardo Habkost | } |
296 | b6fcfa59 | Eduardo Habkost | |
297 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int32 = {
|
298 | b6fcfa59 | Eduardo Habkost | .name = "int32",
|
299 | b6fcfa59 | Eduardo Habkost | .get = get_int32, |
300 | b6fcfa59 | Eduardo Habkost | .put = put_int32, |
301 | b6fcfa59 | Eduardo Habkost | }; |
302 | b6fcfa59 | Eduardo Habkost | |
303 | b6fcfa59 | Eduardo Habkost | /* 32 bit int. See that the received value is the same than the one
|
304 | b6fcfa59 | Eduardo Habkost | in the field */
|
305 | b6fcfa59 | Eduardo Habkost | |
306 | b6fcfa59 | Eduardo Habkost | static int get_int32_equal(QEMUFile *f, void *pv, size_t size) |
307 | b6fcfa59 | Eduardo Habkost | { |
308 | b6fcfa59 | Eduardo Habkost | int32_t *v = pv; |
309 | b6fcfa59 | Eduardo Habkost | int32_t v2; |
310 | b6fcfa59 | Eduardo Habkost | qemu_get_sbe32s(f, &v2); |
311 | b6fcfa59 | Eduardo Habkost | |
312 | b6fcfa59 | Eduardo Habkost | if (*v == v2) {
|
313 | b6fcfa59 | Eduardo Habkost | return 0; |
314 | b6fcfa59 | Eduardo Habkost | } |
315 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
316 | b6fcfa59 | Eduardo Habkost | } |
317 | b6fcfa59 | Eduardo Habkost | |
318 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int32_equal = {
|
319 | b6fcfa59 | Eduardo Habkost | .name = "int32 equal",
|
320 | b6fcfa59 | Eduardo Habkost | .get = get_int32_equal, |
321 | b6fcfa59 | Eduardo Habkost | .put = put_int32, |
322 | b6fcfa59 | Eduardo Habkost | }; |
323 | b6fcfa59 | Eduardo Habkost | |
324 | 24a370ef | Dr. David Alan Gilbert | /* 32 bit int. Check that the received value is less than or equal to
|
325 | 24a370ef | Dr. David Alan Gilbert | the one in the field */
|
326 | b6fcfa59 | Eduardo Habkost | |
327 | b6fcfa59 | Eduardo Habkost | static int get_int32_le(QEMUFile *f, void *pv, size_t size) |
328 | b6fcfa59 | Eduardo Habkost | { |
329 | 24a370ef | Dr. David Alan Gilbert | int32_t *cur = pv; |
330 | 24a370ef | Dr. David Alan Gilbert | int32_t loaded; |
331 | 24a370ef | Dr. David Alan Gilbert | qemu_get_sbe32s(f, &loaded); |
332 | b6fcfa59 | Eduardo Habkost | |
333 | 24a370ef | Dr. David Alan Gilbert | if (loaded <= *cur) {
|
334 | 24a370ef | Dr. David Alan Gilbert | *cur = loaded; |
335 | b6fcfa59 | Eduardo Habkost | return 0; |
336 | b6fcfa59 | Eduardo Habkost | } |
337 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
338 | b6fcfa59 | Eduardo Habkost | } |
339 | b6fcfa59 | Eduardo Habkost | |
340 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int32_le = {
|
341 | 24a370ef | Dr. David Alan Gilbert | .name = "int32 le",
|
342 | b6fcfa59 | Eduardo Habkost | .get = get_int32_le, |
343 | b6fcfa59 | Eduardo Habkost | .put = put_int32, |
344 | b6fcfa59 | Eduardo Habkost | }; |
345 | b6fcfa59 | Eduardo Habkost | |
346 | b6fcfa59 | Eduardo Habkost | /* 64 bit int */
|
347 | b6fcfa59 | Eduardo Habkost | |
348 | b6fcfa59 | Eduardo Habkost | static int get_int64(QEMUFile *f, void *pv, size_t size) |
349 | b6fcfa59 | Eduardo Habkost | { |
350 | b6fcfa59 | Eduardo Habkost | int64_t *v = pv; |
351 | b6fcfa59 | Eduardo Habkost | qemu_get_sbe64s(f, v); |
352 | b6fcfa59 | Eduardo Habkost | return 0; |
353 | b6fcfa59 | Eduardo Habkost | } |
354 | b6fcfa59 | Eduardo Habkost | |
355 | b6fcfa59 | Eduardo Habkost | static void put_int64(QEMUFile *f, void *pv, size_t size) |
356 | b6fcfa59 | Eduardo Habkost | { |
357 | b6fcfa59 | Eduardo Habkost | int64_t *v = pv; |
358 | b6fcfa59 | Eduardo Habkost | qemu_put_sbe64s(f, v); |
359 | b6fcfa59 | Eduardo Habkost | } |
360 | b6fcfa59 | Eduardo Habkost | |
361 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_int64 = {
|
362 | b6fcfa59 | Eduardo Habkost | .name = "int64",
|
363 | b6fcfa59 | Eduardo Habkost | .get = get_int64, |
364 | b6fcfa59 | Eduardo Habkost | .put = put_int64, |
365 | b6fcfa59 | Eduardo Habkost | }; |
366 | b6fcfa59 | Eduardo Habkost | |
367 | b6fcfa59 | Eduardo Habkost | /* 8 bit unsigned int */
|
368 | b6fcfa59 | Eduardo Habkost | |
369 | b6fcfa59 | Eduardo Habkost | static int get_uint8(QEMUFile *f, void *pv, size_t size) |
370 | b6fcfa59 | Eduardo Habkost | { |
371 | b6fcfa59 | Eduardo Habkost | uint8_t *v = pv; |
372 | b6fcfa59 | Eduardo Habkost | qemu_get_8s(f, v); |
373 | b6fcfa59 | Eduardo Habkost | return 0; |
374 | b6fcfa59 | Eduardo Habkost | } |
375 | b6fcfa59 | Eduardo Habkost | |
376 | b6fcfa59 | Eduardo Habkost | static void put_uint8(QEMUFile *f, void *pv, size_t size) |
377 | b6fcfa59 | Eduardo Habkost | { |
378 | b6fcfa59 | Eduardo Habkost | uint8_t *v = pv; |
379 | b6fcfa59 | Eduardo Habkost | qemu_put_8s(f, v); |
380 | b6fcfa59 | Eduardo Habkost | } |
381 | b6fcfa59 | Eduardo Habkost | |
382 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint8 = {
|
383 | b6fcfa59 | Eduardo Habkost | .name = "uint8",
|
384 | b6fcfa59 | Eduardo Habkost | .get = get_uint8, |
385 | b6fcfa59 | Eduardo Habkost | .put = put_uint8, |
386 | b6fcfa59 | Eduardo Habkost | }; |
387 | b6fcfa59 | Eduardo Habkost | |
388 | b6fcfa59 | Eduardo Habkost | /* 16 bit unsigned int */
|
389 | b6fcfa59 | Eduardo Habkost | |
390 | b6fcfa59 | Eduardo Habkost | static int get_uint16(QEMUFile *f, void *pv, size_t size) |
391 | b6fcfa59 | Eduardo Habkost | { |
392 | b6fcfa59 | Eduardo Habkost | uint16_t *v = pv; |
393 | b6fcfa59 | Eduardo Habkost | qemu_get_be16s(f, v); |
394 | b6fcfa59 | Eduardo Habkost | return 0; |
395 | b6fcfa59 | Eduardo Habkost | } |
396 | b6fcfa59 | Eduardo Habkost | |
397 | b6fcfa59 | Eduardo Habkost | static void put_uint16(QEMUFile *f, void *pv, size_t size) |
398 | b6fcfa59 | Eduardo Habkost | { |
399 | b6fcfa59 | Eduardo Habkost | uint16_t *v = pv; |
400 | b6fcfa59 | Eduardo Habkost | qemu_put_be16s(f, v); |
401 | b6fcfa59 | Eduardo Habkost | } |
402 | b6fcfa59 | Eduardo Habkost | |
403 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint16 = {
|
404 | b6fcfa59 | Eduardo Habkost | .name = "uint16",
|
405 | b6fcfa59 | Eduardo Habkost | .get = get_uint16, |
406 | b6fcfa59 | Eduardo Habkost | .put = put_uint16, |
407 | b6fcfa59 | Eduardo Habkost | }; |
408 | b6fcfa59 | Eduardo Habkost | |
409 | b6fcfa59 | Eduardo Habkost | /* 32 bit unsigned int */
|
410 | b6fcfa59 | Eduardo Habkost | |
411 | b6fcfa59 | Eduardo Habkost | static int get_uint32(QEMUFile *f, void *pv, size_t size) |
412 | b6fcfa59 | Eduardo Habkost | { |
413 | b6fcfa59 | Eduardo Habkost | uint32_t *v = pv; |
414 | b6fcfa59 | Eduardo Habkost | qemu_get_be32s(f, v); |
415 | b6fcfa59 | Eduardo Habkost | return 0; |
416 | b6fcfa59 | Eduardo Habkost | } |
417 | b6fcfa59 | Eduardo Habkost | |
418 | b6fcfa59 | Eduardo Habkost | static void put_uint32(QEMUFile *f, void *pv, size_t size) |
419 | b6fcfa59 | Eduardo Habkost | { |
420 | b6fcfa59 | Eduardo Habkost | uint32_t *v = pv; |
421 | b6fcfa59 | Eduardo Habkost | qemu_put_be32s(f, v); |
422 | b6fcfa59 | Eduardo Habkost | } |
423 | b6fcfa59 | Eduardo Habkost | |
424 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint32 = {
|
425 | b6fcfa59 | Eduardo Habkost | .name = "uint32",
|
426 | b6fcfa59 | Eduardo Habkost | .get = get_uint32, |
427 | b6fcfa59 | Eduardo Habkost | .put = put_uint32, |
428 | b6fcfa59 | Eduardo Habkost | }; |
429 | b6fcfa59 | Eduardo Habkost | |
430 | b6fcfa59 | Eduardo Habkost | /* 32 bit uint. See that the received value is the same than the one
|
431 | b6fcfa59 | Eduardo Habkost | in the field */
|
432 | b6fcfa59 | Eduardo Habkost | |
433 | b6fcfa59 | Eduardo Habkost | static int get_uint32_equal(QEMUFile *f, void *pv, size_t size) |
434 | b6fcfa59 | Eduardo Habkost | { |
435 | b6fcfa59 | Eduardo Habkost | uint32_t *v = pv; |
436 | b6fcfa59 | Eduardo Habkost | uint32_t v2; |
437 | b6fcfa59 | Eduardo Habkost | qemu_get_be32s(f, &v2); |
438 | b6fcfa59 | Eduardo Habkost | |
439 | b6fcfa59 | Eduardo Habkost | if (*v == v2) {
|
440 | b6fcfa59 | Eduardo Habkost | return 0; |
441 | b6fcfa59 | Eduardo Habkost | } |
442 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
443 | b6fcfa59 | Eduardo Habkost | } |
444 | b6fcfa59 | Eduardo Habkost | |
445 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint32_equal = {
|
446 | b6fcfa59 | Eduardo Habkost | .name = "uint32 equal",
|
447 | b6fcfa59 | Eduardo Habkost | .get = get_uint32_equal, |
448 | b6fcfa59 | Eduardo Habkost | .put = put_uint32, |
449 | b6fcfa59 | Eduardo Habkost | }; |
450 | b6fcfa59 | Eduardo Habkost | |
451 | b6fcfa59 | Eduardo Habkost | /* 64 bit unsigned int */
|
452 | b6fcfa59 | Eduardo Habkost | |
453 | b6fcfa59 | Eduardo Habkost | static int get_uint64(QEMUFile *f, void *pv, size_t size) |
454 | b6fcfa59 | Eduardo Habkost | { |
455 | b6fcfa59 | Eduardo Habkost | uint64_t *v = pv; |
456 | b6fcfa59 | Eduardo Habkost | qemu_get_be64s(f, v); |
457 | b6fcfa59 | Eduardo Habkost | return 0; |
458 | b6fcfa59 | Eduardo Habkost | } |
459 | b6fcfa59 | Eduardo Habkost | |
460 | b6fcfa59 | Eduardo Habkost | static void put_uint64(QEMUFile *f, void *pv, size_t size) |
461 | b6fcfa59 | Eduardo Habkost | { |
462 | b6fcfa59 | Eduardo Habkost | uint64_t *v = pv; |
463 | b6fcfa59 | Eduardo Habkost | qemu_put_be64s(f, v); |
464 | b6fcfa59 | Eduardo Habkost | } |
465 | b6fcfa59 | Eduardo Habkost | |
466 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint64 = {
|
467 | b6fcfa59 | Eduardo Habkost | .name = "uint64",
|
468 | b6fcfa59 | Eduardo Habkost | .get = get_uint64, |
469 | b6fcfa59 | Eduardo Habkost | .put = put_uint64, |
470 | b6fcfa59 | Eduardo Habkost | }; |
471 | b6fcfa59 | Eduardo Habkost | |
472 | b6fcfa59 | Eduardo Habkost | /* 64 bit unsigned int. See that the received value is the same than the one
|
473 | b6fcfa59 | Eduardo Habkost | in the field */
|
474 | b6fcfa59 | Eduardo Habkost | |
475 | b6fcfa59 | Eduardo Habkost | static int get_uint64_equal(QEMUFile *f, void *pv, size_t size) |
476 | b6fcfa59 | Eduardo Habkost | { |
477 | b6fcfa59 | Eduardo Habkost | uint64_t *v = pv; |
478 | b6fcfa59 | Eduardo Habkost | uint64_t v2; |
479 | b6fcfa59 | Eduardo Habkost | qemu_get_be64s(f, &v2); |
480 | b6fcfa59 | Eduardo Habkost | |
481 | b6fcfa59 | Eduardo Habkost | if (*v == v2) {
|
482 | b6fcfa59 | Eduardo Habkost | return 0; |
483 | b6fcfa59 | Eduardo Habkost | } |
484 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
485 | b6fcfa59 | Eduardo Habkost | } |
486 | b6fcfa59 | Eduardo Habkost | |
487 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint64_equal = {
|
488 | b6fcfa59 | Eduardo Habkost | .name = "int64 equal",
|
489 | b6fcfa59 | Eduardo Habkost | .get = get_uint64_equal, |
490 | b6fcfa59 | Eduardo Habkost | .put = put_uint64, |
491 | b6fcfa59 | Eduardo Habkost | }; |
492 | b6fcfa59 | Eduardo Habkost | |
493 | b6fcfa59 | Eduardo Habkost | /* 8 bit int. See that the received value is the same than the one
|
494 | b6fcfa59 | Eduardo Habkost | in the field */
|
495 | b6fcfa59 | Eduardo Habkost | |
496 | b6fcfa59 | Eduardo Habkost | static int get_uint8_equal(QEMUFile *f, void *pv, size_t size) |
497 | b6fcfa59 | Eduardo Habkost | { |
498 | b6fcfa59 | Eduardo Habkost | uint8_t *v = pv; |
499 | b6fcfa59 | Eduardo Habkost | uint8_t v2; |
500 | b6fcfa59 | Eduardo Habkost | qemu_get_8s(f, &v2); |
501 | b6fcfa59 | Eduardo Habkost | |
502 | b6fcfa59 | Eduardo Habkost | if (*v == v2) {
|
503 | b6fcfa59 | Eduardo Habkost | return 0; |
504 | b6fcfa59 | Eduardo Habkost | } |
505 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
506 | b6fcfa59 | Eduardo Habkost | } |
507 | b6fcfa59 | Eduardo Habkost | |
508 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint8_equal = {
|
509 | b6fcfa59 | Eduardo Habkost | .name = "uint8 equal",
|
510 | b6fcfa59 | Eduardo Habkost | .get = get_uint8_equal, |
511 | b6fcfa59 | Eduardo Habkost | .put = put_uint8, |
512 | b6fcfa59 | Eduardo Habkost | }; |
513 | b6fcfa59 | Eduardo Habkost | |
514 | b6fcfa59 | Eduardo Habkost | /* 16 bit unsigned int int. See that the received value is the same than the one
|
515 | b6fcfa59 | Eduardo Habkost | in the field */
|
516 | b6fcfa59 | Eduardo Habkost | |
517 | b6fcfa59 | Eduardo Habkost | static int get_uint16_equal(QEMUFile *f, void *pv, size_t size) |
518 | b6fcfa59 | Eduardo Habkost | { |
519 | b6fcfa59 | Eduardo Habkost | uint16_t *v = pv; |
520 | b6fcfa59 | Eduardo Habkost | uint16_t v2; |
521 | b6fcfa59 | Eduardo Habkost | qemu_get_be16s(f, &v2); |
522 | b6fcfa59 | Eduardo Habkost | |
523 | b6fcfa59 | Eduardo Habkost | if (*v == v2) {
|
524 | b6fcfa59 | Eduardo Habkost | return 0; |
525 | b6fcfa59 | Eduardo Habkost | } |
526 | b6fcfa59 | Eduardo Habkost | return -EINVAL;
|
527 | b6fcfa59 | Eduardo Habkost | } |
528 | b6fcfa59 | Eduardo Habkost | |
529 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_uint16_equal = {
|
530 | b6fcfa59 | Eduardo Habkost | .name = "uint16 equal",
|
531 | b6fcfa59 | Eduardo Habkost | .get = get_uint16_equal, |
532 | b6fcfa59 | Eduardo Habkost | .put = put_uint16, |
533 | b6fcfa59 | Eduardo Habkost | }; |
534 | b6fcfa59 | Eduardo Habkost | |
535 | b6fcfa59 | Eduardo Habkost | /* floating point */
|
536 | b6fcfa59 | Eduardo Habkost | |
537 | b6fcfa59 | Eduardo Habkost | static int get_float64(QEMUFile *f, void *pv, size_t size) |
538 | b6fcfa59 | Eduardo Habkost | { |
539 | b6fcfa59 | Eduardo Habkost | float64 *v = pv; |
540 | b6fcfa59 | Eduardo Habkost | |
541 | b6fcfa59 | Eduardo Habkost | *v = make_float64(qemu_get_be64(f)); |
542 | b6fcfa59 | Eduardo Habkost | return 0; |
543 | b6fcfa59 | Eduardo Habkost | } |
544 | b6fcfa59 | Eduardo Habkost | |
545 | b6fcfa59 | Eduardo Habkost | static void put_float64(QEMUFile *f, void *pv, size_t size) |
546 | b6fcfa59 | Eduardo Habkost | { |
547 | b6fcfa59 | Eduardo Habkost | uint64_t *v = pv; |
548 | b6fcfa59 | Eduardo Habkost | |
549 | b6fcfa59 | Eduardo Habkost | qemu_put_be64(f, float64_val(*v)); |
550 | b6fcfa59 | Eduardo Habkost | } |
551 | b6fcfa59 | Eduardo Habkost | |
552 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_float64 = {
|
553 | b6fcfa59 | Eduardo Habkost | .name = "float64",
|
554 | b6fcfa59 | Eduardo Habkost | .get = get_float64, |
555 | b6fcfa59 | Eduardo Habkost | .put = put_float64, |
556 | b6fcfa59 | Eduardo Habkost | }; |
557 | b6fcfa59 | Eduardo Habkost | |
558 | b6fcfa59 | Eduardo Habkost | /* uint8_t buffers */
|
559 | b6fcfa59 | Eduardo Habkost | |
560 | b6fcfa59 | Eduardo Habkost | static int get_buffer(QEMUFile *f, void *pv, size_t size) |
561 | b6fcfa59 | Eduardo Habkost | { |
562 | b6fcfa59 | Eduardo Habkost | uint8_t *v = pv; |
563 | b6fcfa59 | Eduardo Habkost | qemu_get_buffer(f, v, size); |
564 | b6fcfa59 | Eduardo Habkost | return 0; |
565 | b6fcfa59 | Eduardo Habkost | } |
566 | b6fcfa59 | Eduardo Habkost | |
567 | b6fcfa59 | Eduardo Habkost | static void put_buffer(QEMUFile *f, void *pv, size_t size) |
568 | b6fcfa59 | Eduardo Habkost | { |
569 | b6fcfa59 | Eduardo Habkost | uint8_t *v = pv; |
570 | b6fcfa59 | Eduardo Habkost | qemu_put_buffer(f, v, size); |
571 | b6fcfa59 | Eduardo Habkost | } |
572 | b6fcfa59 | Eduardo Habkost | |
573 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_buffer = {
|
574 | b6fcfa59 | Eduardo Habkost | .name = "buffer",
|
575 | b6fcfa59 | Eduardo Habkost | .get = get_buffer, |
576 | b6fcfa59 | Eduardo Habkost | .put = put_buffer, |
577 | b6fcfa59 | Eduardo Habkost | }; |
578 | b6fcfa59 | Eduardo Habkost | |
579 | b6fcfa59 | Eduardo Habkost | /* unused buffers: space that was used for some fields that are
|
580 | b6fcfa59 | Eduardo Habkost | not useful anymore */
|
581 | b6fcfa59 | Eduardo Habkost | |
582 | b6fcfa59 | Eduardo Habkost | static int get_unused_buffer(QEMUFile *f, void *pv, size_t size) |
583 | b6fcfa59 | Eduardo Habkost | { |
584 | b6fcfa59 | Eduardo Habkost | uint8_t buf[1024];
|
585 | b6fcfa59 | Eduardo Habkost | int block_len;
|
586 | b6fcfa59 | Eduardo Habkost | |
587 | b6fcfa59 | Eduardo Habkost | while (size > 0) { |
588 | b6fcfa59 | Eduardo Habkost | block_len = MIN(sizeof(buf), size);
|
589 | b6fcfa59 | Eduardo Habkost | size -= block_len; |
590 | b6fcfa59 | Eduardo Habkost | qemu_get_buffer(f, buf, block_len); |
591 | b6fcfa59 | Eduardo Habkost | } |
592 | b6fcfa59 | Eduardo Habkost | return 0; |
593 | b6fcfa59 | Eduardo Habkost | } |
594 | b6fcfa59 | Eduardo Habkost | |
595 | b6fcfa59 | Eduardo Habkost | static void put_unused_buffer(QEMUFile *f, void *pv, size_t size) |
596 | b6fcfa59 | Eduardo Habkost | { |
597 | b6fcfa59 | Eduardo Habkost | static const uint8_t buf[1024]; |
598 | b6fcfa59 | Eduardo Habkost | int block_len;
|
599 | b6fcfa59 | Eduardo Habkost | |
600 | b6fcfa59 | Eduardo Habkost | while (size > 0) { |
601 | b6fcfa59 | Eduardo Habkost | block_len = MIN(sizeof(buf), size);
|
602 | b6fcfa59 | Eduardo Habkost | size -= block_len; |
603 | b6fcfa59 | Eduardo Habkost | qemu_put_buffer(f, buf, block_len); |
604 | b6fcfa59 | Eduardo Habkost | } |
605 | b6fcfa59 | Eduardo Habkost | } |
606 | b6fcfa59 | Eduardo Habkost | |
607 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_unused_buffer = {
|
608 | b6fcfa59 | Eduardo Habkost | .name = "unused_buffer",
|
609 | b6fcfa59 | Eduardo Habkost | .get = get_unused_buffer, |
610 | b6fcfa59 | Eduardo Habkost | .put = put_unused_buffer, |
611 | b6fcfa59 | Eduardo Habkost | }; |
612 | b6fcfa59 | Eduardo Habkost | |
613 | b6fcfa59 | Eduardo Habkost | /* bitmaps (as defined by bitmap.h). Note that size here is the size
|
614 | b6fcfa59 | Eduardo Habkost | * of the bitmap in bits. The on-the-wire format of a bitmap is 64
|
615 | b6fcfa59 | Eduardo Habkost | * bit words with the bits in big endian order. The in-memory format
|
616 | b6fcfa59 | Eduardo Habkost | * is an array of 'unsigned long', which may be either 32 or 64 bits.
|
617 | b6fcfa59 | Eduardo Habkost | */
|
618 | b6fcfa59 | Eduardo Habkost | /* This is the number of 64 bit words sent over the wire */
|
619 | b6fcfa59 | Eduardo Habkost | #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64) |
620 | b6fcfa59 | Eduardo Habkost | static int get_bitmap(QEMUFile *f, void *pv, size_t size) |
621 | b6fcfa59 | Eduardo Habkost | { |
622 | b6fcfa59 | Eduardo Habkost | unsigned long *bmp = pv; |
623 | b6fcfa59 | Eduardo Habkost | int i, idx = 0; |
624 | b6fcfa59 | Eduardo Habkost | for (i = 0; i < BITS_TO_U64S(size); i++) { |
625 | b6fcfa59 | Eduardo Habkost | uint64_t w = qemu_get_be64(f); |
626 | b6fcfa59 | Eduardo Habkost | bmp[idx++] = w; |
627 | b6fcfa59 | Eduardo Habkost | if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) { |
628 | b6fcfa59 | Eduardo Habkost | bmp[idx++] = w >> 32;
|
629 | b6fcfa59 | Eduardo Habkost | } |
630 | b6fcfa59 | Eduardo Habkost | } |
631 | b6fcfa59 | Eduardo Habkost | return 0; |
632 | b6fcfa59 | Eduardo Habkost | } |
633 | b6fcfa59 | Eduardo Habkost | |
634 | b6fcfa59 | Eduardo Habkost | static void put_bitmap(QEMUFile *f, void *pv, size_t size) |
635 | b6fcfa59 | Eduardo Habkost | { |
636 | b6fcfa59 | Eduardo Habkost | unsigned long *bmp = pv; |
637 | b6fcfa59 | Eduardo Habkost | int i, idx = 0; |
638 | b6fcfa59 | Eduardo Habkost | for (i = 0; i < BITS_TO_U64S(size); i++) { |
639 | b6fcfa59 | Eduardo Habkost | uint64_t w = bmp[idx++]; |
640 | b6fcfa59 | Eduardo Habkost | if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) { |
641 | b6fcfa59 | Eduardo Habkost | w |= ((uint64_t)bmp[idx++]) << 32;
|
642 | b6fcfa59 | Eduardo Habkost | } |
643 | b6fcfa59 | Eduardo Habkost | qemu_put_be64(f, w); |
644 | b6fcfa59 | Eduardo Habkost | } |
645 | b6fcfa59 | Eduardo Habkost | } |
646 | b6fcfa59 | Eduardo Habkost | |
647 | b6fcfa59 | Eduardo Habkost | const VMStateInfo vmstate_info_bitmap = {
|
648 | b6fcfa59 | Eduardo Habkost | .name = "bitmap",
|
649 | b6fcfa59 | Eduardo Habkost | .get = get_bitmap, |
650 | b6fcfa59 | Eduardo Habkost | .put = put_bitmap, |
651 | b6fcfa59 | Eduardo Habkost | }; |