1ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner/*
2ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * QEMU System Emulator
3ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner *
4ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * Copyright (c) 2003-2008 Fabrice Bellard
5ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner *
6ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * Permission is hereby granted, free of charge, to any person obtaining a copy
7ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * of this software and associated documentation files (the "Software"), to deal
8ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * in the Software without restriction, including without limitation the rights
9ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * copies of the Software, and to permit persons to whom the Software is
11ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * furnished to do so, subject to the following conditions:
12ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner *
13ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * The above copyright notice and this permission notice shall be included in
14ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * all copies or substantial portions of the Software.
15ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner *
16ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner * THE SOFTWARE.
23ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner */
24ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include <stdint.h>
25ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include <stdarg.h>
26ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include <stdlib.h>
27ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifndef _WIN32
28ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include <sys/types.h>
29ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include <sys/mman.h>
30ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
31ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "config.h"
32ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "monitor.h"
33ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "sysemu.h"
34ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "arch_init.h"
35ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "audio/audio.h"
36ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "hw/irq.h"
37ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "hw/pci.h"
38ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "hw/audiodev.h"
39ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "kvm.h"
40ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "migration.h"
41ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "net.h"
42ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "gdbstub.h"
43ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "hw/smbios.h"
44ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
45ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef TARGET_SPARC
46ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_width = 1024;
47ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_height = 768;
48ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_depth = 8;
49ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
50ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_width = 800;
51ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_height = 600;
52ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint graphic_depth = 15;
53ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
54ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
55ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerconst char arch_config_name[] = CONFIG_QEMU_SHAREDIR "/target-" TARGET_ARCH ".conf";
56ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
57ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#if defined(TARGET_ALPHA)
58ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_ALPHA
59ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_ARM)
60ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_ARM
61ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_CRIS)
62ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_CRIS
63ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_I386)
64ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_I386
65ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_M68K)
66ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_M68K
67ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_LM32)
68ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_LM32
69ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_MICROBLAZE)
70ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
71ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_MIPS)
72ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_MIPS
73ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_PPC)
74ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_PPC
75ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_S390X)
76ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_S390X
77ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_SH4)
78ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_SH4
79ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#elif defined(TARGET_SPARC)
80ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define QEMU_ARCH QEMU_ARCH_SPARC
81ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
82ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
83ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerconst uint32_t arch_type = QEMU_ARCH;
84ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
85280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#if 1
86ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner/***********************************************************/
87ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner/* ram save/restore */
88ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
89ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_FULL     0x01 /* Obsolete, not used anymore */
90ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_COMPRESS 0x02
91ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_MEM_SIZE 0x04
92ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_PAGE     0x08
93ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_EOS      0x10
94ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#define RAM_SAVE_FLAG_CONTINUE 0x20
95ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
96ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic int is_dup_page(uint8_t *page, uint8_t ch)
97ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
98ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
99ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint32_t *array = (uint32_t *)page;
100ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int i;
101ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
102ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
103ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (array[i] != val) {
104ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            return 0;
105ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
106ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
107ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
108ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 1;
109ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
110ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
111ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic RAMBlock *last_block;
112ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic ram_addr_t last_offset;
113ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
114ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic int ram_save_block(QEMUFile *f)
115ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
116ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock *block = last_block;
117ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ram_addr_t offset = last_offset;
118ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ram_addr_t current_addr;
119ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int bytes_sent = 0;
120ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
121ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (!block)
122ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        block = QLIST_FIRST(&ram_list.blocks);
123ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
124ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    current_addr = block->offset + offset;
125ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
126ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    do {
127ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
128ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            uint8_t *p;
129ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
130ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
131ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            cpu_physical_memory_reset_dirty(current_addr,
132ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                            current_addr + TARGET_PAGE_SIZE,
133ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                            MIGRATION_DIRTY_FLAG);
134ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
135ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            p = block->host + offset;
136ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
137ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (is_dup_page(p, *p)) {
138ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
139ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (!cont) {
140ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    qemu_put_byte(f, strlen(block->idstr));
141ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    qemu_put_buffer(f, (uint8_t *)block->idstr,
142ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                    strlen(block->idstr));
143ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
144ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                qemu_put_byte(f, *p);
145ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                bytes_sent = 1;
146ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            } else {
147ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
148ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (!cont) {
149ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    qemu_put_byte(f, strlen(block->idstr));
150ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    qemu_put_buffer(f, (uint8_t *)block->idstr,
151ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                    strlen(block->idstr));
152ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
153ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
154ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                bytes_sent = TARGET_PAGE_SIZE;
155ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
156ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
157ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            break;
158ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
159ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
160ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        offset += TARGET_PAGE_SIZE;
161ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (offset >= block->length) {
162ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            offset = 0;
163ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            block = QLIST_NEXT(block, next);
164ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (!block)
165ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                block = QLIST_FIRST(&ram_list.blocks);
166ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
167ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
168ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        current_addr = block->offset + offset;
169ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
170ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    } while (current_addr != last_block->offset + last_offset);
171ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
172ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    last_block = block;
173ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    last_offset = offset;
174ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
175ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return bytes_sent;
176ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
177ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
178ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic uint64_t bytes_transferred;
179ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
180ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic ram_addr_t ram_save_remaining(void)
181ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
182ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock *block;
183ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ram_addr_t count = 0;
184ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
185ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    QLIST_FOREACH(block, &ram_list.blocks, next) {
186ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        ram_addr_t addr;
187ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        for (addr = block->offset; addr < block->offset + block->length;
188ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner             addr += TARGET_PAGE_SIZE) {
189ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
190ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                count++;
191ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
192ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
193ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
194ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
195ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return count;
196ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
197ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
198ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turneruint64_t ram_bytes_remaining(void)
199ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
200ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return ram_save_remaining() * TARGET_PAGE_SIZE;
201ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
202ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
203ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turneruint64_t ram_bytes_transferred(void)
204ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
205ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return bytes_transferred;
206ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
207ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
208ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turneruint64_t ram_bytes_total(void)
209ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
210ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock *block;
211ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint64_t total = 0;
212ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
213ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    QLIST_FOREACH(block, &ram_list.blocks, next)
214ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        total += block->length;
215ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
216ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return total;
217ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
218ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
219ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic int block_compar(const void *a, const void *b)
220ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
221ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock * const *ablock = a;
222ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock * const *bblock = b;
223ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if ((*ablock)->offset < (*bblock)->offset) {
224ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return -1;
225ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    } else if ((*ablock)->offset > (*bblock)->offset) {
226ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return 1;
227ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
228ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
229ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
230ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
231ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic void sort_ram_list(void)
232ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
233ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    RAMBlock *block, *nblock, **blocks;
234ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int n;
235ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    n = 0;
236ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    QLIST_FOREACH(block, &ram_list.blocks, next) {
237ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        ++n;
238ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
239ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    blocks = qemu_malloc(n * sizeof *blocks);
240ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    n = 0;
241ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) {
242ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        blocks[n++] = block;
243ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        QLIST_REMOVE(block, next);
244ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
245ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    qsort(blocks, n, sizeof *blocks, block_compar);
246ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    while (--n >= 0) {
247ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
248ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
249ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    qemu_free(blocks);
250ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
251ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
252280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerint ram_save_live(QEMUFile *f, int stage, void *opaque)
253ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
254ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ram_addr_t addr;
255ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint64_t bytes_transferred_last;
256ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    double bwidth = 0;
257ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint64_t expected_time = 0;
258ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
259ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (stage < 0) {
260ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(0);
261ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return 0;
262ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
263ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
264ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
265ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        qemu_file_set_error(f);
266ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return 0;
267ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
268ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
269ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (stage == 1) {
270ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        RAMBlock *block;
271ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        bytes_transferred = 0;
272ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        last_block = NULL;
273ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        last_offset = 0;
274ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        sort_ram_list();
275ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
276ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        /* Make sure all dirty bits are set */
277ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        QLIST_FOREACH(block, &ram_list.blocks, next) {
278ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            for (addr = block->offset; addr < block->offset + block->length;
279ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                 addr += TARGET_PAGE_SIZE) {
280ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (!cpu_physical_memory_get_dirty(addr,
281ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                                   MIGRATION_DIRTY_FLAG)) {
282ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    cpu_physical_memory_set_dirty(addr);
283ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
284ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
285ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
286ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
287ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        /* Enable dirty memory tracking */
288ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(1);
289ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
290ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
291ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
292ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        QLIST_FOREACH(block, &ram_list.blocks, next) {
293ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            qemu_put_byte(f, strlen(block->idstr));
294ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
295ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            qemu_put_be64(f, block->length);
296ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
297ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
298ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
299ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    bytes_transferred_last = bytes_transferred;
300ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    bwidth = qemu_get_clock_ns(rt_clock);
301ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
302ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    while (!qemu_file_rate_limit(f)) {
303ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        int bytes_sent;
304ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
305ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        bytes_sent = ram_save_block(f);
306ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        bytes_transferred += bytes_sent;
307ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (bytes_sent == 0) { /* no more blocks */
308ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            break;
309ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
310ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
311ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
312ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
313ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
314ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
315ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    /* if we haven't transferred anything this round, force expected_time to a
316ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner     * a very high value, but without crashing */
317ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (bwidth == 0) {
318ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        bwidth = 0.000001;
319ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
320ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
321ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    /* try transferring iterative blocks of memory */
322ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (stage == 3) {
323ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        int bytes_sent;
324ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
325ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        /* flush all remaining blocks regardless of rate limiting */
326ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        while ((bytes_sent = ram_save_block(f)) != 0) {
327ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            bytes_transferred += bytes_sent;
328ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
329ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(0);
330ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
331ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
332ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
333ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
334ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
335ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
336ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return (stage == 2) && (expected_time <= migrate_max_downtime());
337ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
338ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
339ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic inline void *host_from_stream_offset(QEMUFile *f,
340ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                            ram_addr_t offset,
341ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                            int flags)
342ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
343ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    static RAMBlock *block = NULL;
344ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    char id[256];
345ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    uint8_t len;
346ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
347ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (flags & RAM_SAVE_FLAG_CONTINUE) {
348ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (!block) {
349ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            fprintf(stderr, "Ack, bad migration stream!\n");
350ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            return NULL;
351ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
352ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
353ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return block->host + offset;
354ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
355ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
356ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    len = qemu_get_byte(f);
357ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    qemu_get_buffer(f, (uint8_t *)id, len);
358ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    id[len] = 0;
359ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
360ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    QLIST_FOREACH(block, &ram_list.blocks, next) {
361ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (!strncmp(id, block->idstr, sizeof(id)))
362ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            return block->host + offset;
363ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
364ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
365ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    fprintf(stderr, "Can't find block %s!\n", id);
366ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return NULL;
367ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
368ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
369ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint ram_load(QEMUFile *f, void *opaque, int version_id)
370ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
371ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ram_addr_t addr;
372ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int flags;
373ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
374ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (version_id < 3 || version_id > 4) {
375ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return -EINVAL;
376ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
377ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
378ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    do {
379ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        addr = qemu_get_be64(f);
380ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
381ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        flags = addr & ~TARGET_PAGE_MASK;
382ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        addr &= TARGET_PAGE_MASK;
383ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
384ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
385d0e2872813e1d37e8233befdfd13a4d6cb0d7431Vladimir Chtchetkine            if (version_id != 3) {
386ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (addr != ram_bytes_total()) {
387ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    return -EINVAL;
388ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
389ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            } else {
390ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                /* Synchronize RAM block list */
391ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                char id[256];
392ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                ram_addr_t length;
393ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                ram_addr_t total_ram_bytes = addr;
394ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
395ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                while (total_ram_bytes) {
396ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    RAMBlock *block;
397ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    uint8_t len;
398ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
399ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    len = qemu_get_byte(f);
400ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    qemu_get_buffer(f, (uint8_t *)id, len);
401ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    id[len] = 0;
402ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    length = qemu_get_be64(f);
403ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
404ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    QLIST_FOREACH(block, &ram_list.blocks, next) {
405ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                        if (!strncmp(id, block->idstr, sizeof(id))) {
406ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                            if (block->length != length)
407ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                return -EINVAL;
408ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                            break;
409ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                        }
410ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    }
411ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
412ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    if (!block) {
413ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                        fprintf(stderr, "Unknown ramblock \"%s\", cannot "
414ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                                "accept migration\n", id);
415ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                        return -EINVAL;
416ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    }
417ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
418ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    total_ram_bytes -= length;
419ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
420ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
421d0e2872813e1d37e8233befdfd13a4d6cb0d7431Vladimir Chtchetkine        } else if (flags & RAM_SAVE_FLAG_COMPRESS) {
422ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            void *host;
423ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            uint8_t ch;
424ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
425d0e2872813e1d37e8233befdfd13a4d6cb0d7431Vladimir Chtchetkine            if (version_id != 3)
426ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                host = qemu_get_ram_ptr(addr);
427ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            else
428ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                host = host_from_stream_offset(f, addr, flags);
429ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (!host) {
430ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                return -EINVAL;
431ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
432ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
433ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            ch = qemu_get_byte(f);
434ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            memset(host, ch, TARGET_PAGE_SIZE);
435ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifndef _WIN32
436ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (ch == 0 &&
437ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                (!kvm_enabled() || kvm_has_sync_mmu())) {
438ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
439ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
440ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
441ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        } else if (flags & RAM_SAVE_FLAG_PAGE) {
442ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            void *host;
443ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
444d0e2872813e1d37e8233befdfd13a4d6cb0d7431Vladimir Chtchetkine            if (version_id != 3)
445ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                host = qemu_get_ram_ptr(addr);
446ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            else
447ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                host = host_from_stream_offset(f, addr, flags);
448ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
449ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
450ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
451ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (qemu_file_has_error(f)) {
452ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            return -EIO;
453ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
454ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    } while (!(flags & RAM_SAVE_FLAG_EOS));
455ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
456ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
457ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
458ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
459ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
460ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid qemu_service_io(void)
461ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
462ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    qemu_notify_event();
463ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
464ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
465ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef HAS_AUDIO
466ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstruct soundhw {
467ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    const char *name;
468ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    const char *descr;
469ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int enabled;
470ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int isa;
471ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    union {
472ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        int (*init_isa) (qemu_irq *pic);
473ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        int (*init_pci) (PCIBus *bus);
474ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    } init;
475ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner};
476ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
477ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerstatic struct soundhw soundhw[] = {
478ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef HAS_AUDIO_CHOICE
479ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#if defined(TARGET_I386) || defined(TARGET_MIPS)
480ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
481ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "pcspk",
482ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "PC speaker",
483ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
484ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        1,
485ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_isa = pcspk_audio_init }
486ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
487ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
488ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
489ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_SB16
490ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
491ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "sb16",
492ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Creative Sound Blaster 16",
493ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
494ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        1,
495ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_isa = SB16_init }
496ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
497ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
498ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
499ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_CS4231A
500ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
501ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "cs4231a",
502ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "CS4231A",
503ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
504ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        1,
505ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_isa = cs4231a_init }
506ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
507ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
508ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
509ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_ADLIB
510ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
511ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "adlib",
512ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef HAS_YMF262
513ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Yamaha YMF262 (OPL3)",
514ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
515ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Yamaha YM3812 (OPL2)",
516ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
517ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
518ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        1,
519ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_isa = Adlib_init }
520ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
521ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
522ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
523ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_GUS
524ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
525ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "gus",
526ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Gravis Ultrasound GF1",
527ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
528ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        1,
529ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_isa = GUS_init }
530ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
531ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
532ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
533ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_AC97
534ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
535ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "ac97",
536ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Intel 82801AA AC97 Audio",
537ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
538ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
539ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_pci = ac97_init }
540ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
541ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
542ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
543ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_ES1370
544ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
545ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "es1370",
546ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "ENSONIQ AudioPCI ES1370",
547ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
548ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
549ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_pci = es1370_init }
550ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
551ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
552ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
553ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_HDA
554ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    {
555ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "hda",
556ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        "Intel HD Audio",
557ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
558ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        0,
559ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        { .init_pci = intel_hda_and_codec_init }
560ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    },
561ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
562ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
563ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif /* HAS_AUDIO_CHOICE */
564ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
565ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    { NULL, NULL, 0, 0, { NULL } }
566ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner};
567ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
568ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid select_soundhw(const char *optarg)
569ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
570ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    struct soundhw *c;
571ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
572ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (*optarg == '?') {
573ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    show_valid_cards:
574ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
575ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        printf("Valid sound card names (comma separated):\n");
576ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        for (c = soundhw; c->name; ++c) {
577ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            printf ("%-11s %s\n", c->name, c->descr);
578ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
579ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        printf("\n-soundhw all will enable all of the above\n");
580ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        exit(*optarg != '?');
581ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
582ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    else {
583ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        size_t l;
584ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        const char *p;
585ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        char *e;
586ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        int bad_card = 0;
587ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
588ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (!strcmp(optarg, "all")) {
589ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            for (c = soundhw; c->name; ++c) {
590ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                c->enabled = 1;
591ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
592ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            return;
593ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
594ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
595ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        p = optarg;
596ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        while (*p) {
597ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            e = strchr(p, ',');
598ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            l = !e ? strlen(p) : (size_t) (e - p);
599ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
600ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            for (c = soundhw; c->name; ++c) {
601ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (!strncmp(c->name, p, l) && !c->name[l]) {
602ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    c->enabled = 1;
603ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    break;
604ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
605ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
606ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
607ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (!c->name) {
608ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (l > 80) {
609ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    fprintf(stderr,
610ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                            "Unknown sound card name (too big to show)\n");
611ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
612ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                else {
613ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    fprintf(stderr, "Unknown sound card name `%.*s'\n",
614ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                            (int) l, p);
615ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
616ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                bad_card = 1;
617ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
618ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            p += l + (e != NULL);
619ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
620ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
621ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (bad_card) {
622ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            goto show_valid_cards;
623ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
624ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
625ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
626ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
627ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
628ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
629ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    struct soundhw *c;
630ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
631ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    for (c = soundhw; c->name; ++c) {
632ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        if (c->enabled) {
633ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            if (c->isa) {
634ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (isa_pic) {
635ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    c->init.init_isa(isa_pic);
636ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
637ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            } else {
638ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                if (pci_bus) {
639ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                    c->init.init_pci(pci_bus);
640ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                }
641ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner            }
642ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        }
643ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
644ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
645ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
646ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid select_soundhw(const char *optarg)
647ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
648ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
649ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
650ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
651ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
652ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
653ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
654ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint qemu_uuid_parse(const char *str, uint8_t *uuid)
655ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
656ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    int ret;
657ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
658ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (strlen(str) != 36) {
659ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return -1;
660ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
661ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
662ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
663ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
664ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
665ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                 &uuid[15]);
666ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
667ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (ret != 16) {
668ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        return -1;
669ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
670ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef TARGET_I386
671ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
672ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
673ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
674ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
675ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
676ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#if 0
677ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid do_acpitable_option(const char *optarg)
678ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
679ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef TARGET_I386
680ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (acpi_table_add(optarg) < 0) {
681ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        fprintf(stderr, "Wrong acpi table provided\n");
682ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        exit(1);
683ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
684ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
685ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
686ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
687ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
688ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid do_smbios_option(const char *optarg)
689ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
690ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef TARGET_I386
691ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    if (smbios_entry_add(optarg) < 0) {
692ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        fprintf(stderr, "Wrong smbios provided\n");
693ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner        exit(1);
694ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    }
695ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
696ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
697ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
698ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnervoid cpudef_init(void)
699ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
700ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#if defined(cpudef_setup)
701ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    cpudef_setup(); /* parse cpu definitions in target config file */
702ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
703ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
704ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
705ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint audio_available(void)
706ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
707ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef HAS_AUDIO
708ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 1;
709ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
710ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
711ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
712ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
713ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
714ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint kvm_available(void)
715ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
716ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_KVM
717ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 1;
718ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
719ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
720ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
721ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
722ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner
723ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint xen_available(void)
724ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner{
725ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#ifdef CONFIG_XEN
726ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 1;
727ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#else
728ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner    return 0;
729ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#endif
730ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner}
731