Statistics
| Branch: | Revision:

root / vl.c @ 7d294b61

History | View | Annotate | Download (217.9 kB)

1 0824d6fc bellard
/*
2 80cabfad bellard
 * QEMU System Emulator
3 5fafdf24 ths
 *
4 84f2e8ef bellard
 * Copyright (c) 2003-2007 Fabrice Bellard
5 5fafdf24 ths
 *
6 1df912cf bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1df912cf bellard
 * of this software and associated documentation files (the "Software"), to deal
8 1df912cf bellard
 * in the Software without restriction, including without limitation the rights
9 1df912cf bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1df912cf bellard
 * copies of the Software, and to permit persons to whom the Software is
11 1df912cf bellard
 * furnished to do so, subject to the following conditions:
12 1df912cf bellard
 *
13 1df912cf bellard
 * The above copyright notice and this permission notice shall be included in
14 1df912cf bellard
 * all copies or substantial portions of the Software.
15 1df912cf bellard
 *
16 1df912cf bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1df912cf bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1df912cf bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1df912cf bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1df912cf bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1df912cf bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1df912cf bellard
 * THE SOFTWARE.
23 0824d6fc bellard
 */
24 67b915a5 bellard
#include "vl.h"
25 67b915a5 bellard
26 0824d6fc bellard
#include <unistd.h>
27 0824d6fc bellard
#include <fcntl.h>
28 0824d6fc bellard
#include <signal.h>
29 0824d6fc bellard
#include <time.h>
30 0824d6fc bellard
#include <errno.h>
31 67b915a5 bellard
#include <sys/time.h>
32 c88676f8 bellard
#include <zlib.h>
33 67b915a5 bellard
34 67b915a5 bellard
#ifndef _WIN32
35 67b915a5 bellard
#include <sys/times.h>
36 f1510b2c bellard
#include <sys/wait.h>
37 67b915a5 bellard
#include <termios.h>
38 67b915a5 bellard
#include <sys/poll.h>
39 67b915a5 bellard
#include <sys/mman.h>
40 f1510b2c bellard
#include <sys/ioctl.h>
41 f1510b2c bellard
#include <sys/socket.h>
42 c94c8d64 bellard
#include <netinet/in.h>
43 9d728e8c bellard
#include <dirent.h>
44 7c9d8e07 bellard
#include <netdb.h>
45 cb4b976b ths
#include <sys/select.h>
46 cb4b976b ths
#include <arpa/inet.h>
47 7d3505c5 bellard
#ifdef _BSD
48 7d3505c5 bellard
#include <sys/stat.h>
49 83fb7adf bellard
#ifndef __APPLE__
50 7d3505c5 bellard
#include <libutil.h>
51 83fb7adf bellard
#endif
52 5c40d2bd ths
#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
53 5c40d2bd ths
#include <freebsd/stdlib.h>
54 7d3505c5 bellard
#else
55 ec530c81 bellard
#ifndef __sun__
56 f1510b2c bellard
#include <linux/if.h>
57 f1510b2c bellard
#include <linux/if_tun.h>
58 7d3505c5 bellard
#include <pty.h>
59 7d3505c5 bellard
#include <malloc.h>
60 fd872598 bellard
#include <linux/rtc.h>
61 bd494f4c ths
62 bd494f4c ths
/* For the benefit of older linux systems which don't supply it,
63 bd494f4c ths
   we use a local copy of hpet.h. */
64 bd494f4c ths
/* #include <linux/hpet.h> */
65 bd494f4c ths
#include "hpet.h"
66 bd494f4c ths
67 e57a8c0e bellard
#include <linux/ppdev.h>
68 5867c88a ths
#include <linux/parport.h>
69 d5d10bc3 ths
#else
70 d5d10bc3 ths
#include <sys/stat.h>
71 d5d10bc3 ths
#include <sys/ethernet.h>
72 d5d10bc3 ths
#include <sys/sockio.h>
73 d5d10bc3 ths
#include <netinet/arp.h>
74 d5d10bc3 ths
#include <netinet/in.h>
75 d5d10bc3 ths
#include <netinet/in_systm.h>
76 d5d10bc3 ths
#include <netinet/ip.h>
77 d5d10bc3 ths
#include <netinet/ip_icmp.h> // must come after ip.h
78 d5d10bc3 ths
#include <netinet/udp.h>
79 d5d10bc3 ths
#include <netinet/tcp.h>
80 d5d10bc3 ths
#include <net/if.h>
81 d5d10bc3 ths
#include <syslog.h>
82 d5d10bc3 ths
#include <stropts.h>
83 67b915a5 bellard
#endif
84 7d3505c5 bellard
#endif
85 cb4b976b ths
#else
86 cb4b976b ths
#include <winsock2.h>
87 cb4b976b ths
int inet_aton(const char *cp, struct in_addr *ia);
88 ec530c81 bellard
#endif
89 67b915a5 bellard
90 c20709aa bellard
#if defined(CONFIG_SLIRP)
91 c20709aa bellard
#include "libslirp.h"
92 c20709aa bellard
#endif
93 c20709aa bellard
94 67b915a5 bellard
#ifdef _WIN32
95 7d3505c5 bellard
#include <malloc.h>
96 67b915a5 bellard
#include <sys/timeb.h>
97 67b915a5 bellard
#include <windows.h>
98 67b915a5 bellard
#define getopt_long_only getopt_long
99 67b915a5 bellard
#define memalign(align, size) malloc(size)
100 67b915a5 bellard
#endif
101 67b915a5 bellard
102 6ca957f0 bellard
#include "qemu_socket.h"
103 6ca957f0 bellard
104 73332e5c bellard
#ifdef CONFIG_SDL
105 96bcd4f8 bellard
#ifdef __APPLE__
106 83fb7adf bellard
#include <SDL/SDL.h>
107 96bcd4f8 bellard
#endif
108 73332e5c bellard
#endif /* CONFIG_SDL */
109 0824d6fc bellard
110 5b0753e0 bellard
#ifdef CONFIG_COCOA
111 5b0753e0 bellard
#undef main
112 5b0753e0 bellard
#define main qemu_main
113 5b0753e0 bellard
#endif /* CONFIG_COCOA */
114 5b0753e0 bellard
115 0824d6fc bellard
#include "disas.h"
116 fc01f7e7 bellard
117 8a7ddc38 bellard
#include "exec-all.h"
118 0824d6fc bellard
119 5a67135a bellard
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
120 b46a8906 ths
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
121 a14d6c8c pbrook
#ifdef __sun__
122 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
123 a14d6c8c pbrook
#else
124 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sbin/smbd"
125 a14d6c8c pbrook
#endif
126 f1510b2c bellard
127 0824d6fc bellard
//#define DEBUG_UNUSED_IOPORT
128 fd872598 bellard
//#define DEBUG_IOPORT
129 330d0414 bellard
130 bb551faa bellard
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
131 7916e224 bellard
132 77d4bc34 bellard
#ifdef TARGET_PPC
133 77d4bc34 bellard
#define DEFAULT_RAM_SIZE 144
134 77d4bc34 bellard
#else
135 1bfe856e bellard
#define DEFAULT_RAM_SIZE 128
136 77d4bc34 bellard
#endif
137 8a7ddc38 bellard
/* in ms */
138 8a7ddc38 bellard
#define GUI_REFRESH_INTERVAL 30
139 313aa567 bellard
140 0d92ed30 pbrook
/* Max number of USB devices that can be specified on the commandline.  */
141 0d92ed30 pbrook
#define MAX_USB_CMDLINE 8
142 0d92ed30 pbrook
143 7dea1da4 bellard
/* XXX: use a two level table to limit memory usage */
144 7dea1da4 bellard
#define MAX_IOPORTS 65536
145 0824d6fc bellard
146 80cabfad bellard
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
147 1192dad8 j_mayer
const char *bios_name = NULL;
148 0824d6fc bellard
char phys_ram_file[1024];
149 c4b1fcc0 bellard
void *ioport_opaque[MAX_IOPORTS];
150 fc01f7e7 bellard
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
151 fc01f7e7 bellard
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
152 faea38e7 bellard
/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
153 faea38e7 bellard
   to store the VM snapshots */
154 faea38e7 bellard
BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
155 86f55663 j_mayer
BlockDriverState *pflash_table[MAX_PFLASH];
156 a1bb27b1 pbrook
BlockDriverState *sd_bdrv;
157 3e3d5815 balrog
BlockDriverState *mtd_bdrv;
158 faea38e7 bellard
/* point to the block driver where the snapshots are managed */
159 faea38e7 bellard
BlockDriverState *bs_snapshots;
160 313aa567 bellard
int vga_ram_size;
161 313aa567 bellard
static DisplayState display_state;
162 a20dd508 bellard
int nographic;
163 3d11d0eb bellard
const char* keyboard_layout = NULL;
164 313aa567 bellard
int64_t ticks_per_sec;
165 36b486bb bellard
int boot_device = 'c';
166 0ced6589 bellard
int ram_size;
167 80cabfad bellard
int pit_min_timer_count = 0;
168 c4b1fcc0 bellard
int nb_nics;
169 7c9d8e07 bellard
NICInfo nd_table[MAX_NICS];
170 8a7ddc38 bellard
int vm_running;
171 ee22c2f7 bellard
int rtc_utc = 1;
172 1bfe856e bellard
int cirrus_vga_enabled = 1;
173 d34cab9f ths
int vmsvga_enabled = 0;
174 d827220b bellard
#ifdef TARGET_SPARC
175 d827220b bellard
int graphic_width = 1024;
176 d827220b bellard
int graphic_height = 768;
177 eee0b836 blueswir1
int graphic_depth = 8;
178 d827220b bellard
#else
179 1bfe856e bellard
int graphic_width = 800;
180 1bfe856e bellard
int graphic_height = 600;
181 e9b137c2 bellard
int graphic_depth = 15;
182 eee0b836 blueswir1
#endif
183 d63d307f bellard
int full_screen = 0;
184 43523e93 ths
int no_frame = 0;
185 667accab ths
int no_quit = 0;
186 8d11df9e bellard
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
187 6508fe59 bellard
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
188 a09db21f bellard
#ifdef TARGET_I386
189 a09db21f bellard
int win2k_install_hack = 0;
190 a09db21f bellard
#endif
191 bb36d470 bellard
int usb_enabled = 0;
192 7c9d8e07 bellard
static VLANState *first_vlan;
193 6a00d601 bellard
int smp_cpus = 1;
194 73fc9742 ths
const char *vnc_display;
195 d3e9db93 bellard
#if defined(TARGET_SPARC)
196 ba3c64fb bellard
#define MAX_CPUS 16
197 d3e9db93 bellard
#elif defined(TARGET_I386)
198 d3e9db93 bellard
#define MAX_CPUS 255
199 ba3c64fb bellard
#else
200 d3e9db93 bellard
#define MAX_CPUS 1
201 ba3c64fb bellard
#endif
202 6515b203 bellard
int acpi_enabled = 1;
203 52ca8d6a bellard
int fd_bootchk = 1;
204 d1beab82 bellard
int no_reboot = 0;
205 9467cd46 balrog
int cursor_hide = 1;
206 a171fe39 balrog
int graphic_rotate = 0;
207 71e3ceb8 ths
int daemonize = 0;
208 9ae02555 ths
const char *option_rom[MAX_OPTION_ROMS];
209 9ae02555 ths
int nb_option_roms;
210 8e71621f pbrook
int semihosting_enabled = 0;
211 3c07f8e8 pbrook
int autostart = 1;
212 2b8f2d41 balrog
#ifdef TARGET_ARM
213 2b8f2d41 balrog
int old_param = 0;
214 2b8f2d41 balrog
#endif
215 c35734b2 ths
const char *qemu_name;
216 3780e197 ths
int alt_grab = 0;
217 66508601 blueswir1
#ifdef TARGET_SPARC
218 66508601 blueswir1
unsigned int nb_prom_envs = 0;
219 66508601 blueswir1
const char *prom_envs[MAX_PROM_ENVS];
220 66508601 blueswir1
#endif
221 0824d6fc bellard
222 aeb30be6 balrog
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
223 aeb30be6 balrog
224 0824d6fc bellard
/***********************************************************/
225 26aa7d72 bellard
/* x86 ISA bus support */
226 26aa7d72 bellard
227 26aa7d72 bellard
target_phys_addr_t isa_mem_base = 0;
228 3de388f6 bellard
PicState2 *isa_pic;
229 0824d6fc bellard
230 c4b1fcc0 bellard
uint32_t default_ioport_readb(void *opaque, uint32_t address)
231 0824d6fc bellard
{
232 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
233 1196be37 ths
    fprintf(stderr, "unused inb: port=0x%04x\n", address);
234 0824d6fc bellard
#endif
235 fc01f7e7 bellard
    return 0xff;
236 0824d6fc bellard
}
237 0824d6fc bellard
238 c4b1fcc0 bellard
void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
239 0824d6fc bellard
{
240 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
241 1196be37 ths
    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
242 0824d6fc bellard
#endif
243 0824d6fc bellard
}
244 0824d6fc bellard
245 0824d6fc bellard
/* default is to make two byte accesses */
246 c4b1fcc0 bellard
uint32_t default_ioport_readw(void *opaque, uint32_t address)
247 0824d6fc bellard
{
248 0824d6fc bellard
    uint32_t data;
249 db45c29a bellard
    data = ioport_read_table[0][address](ioport_opaque[address], address);
250 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
251 db45c29a bellard
    data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
252 0824d6fc bellard
    return data;
253 0824d6fc bellard
}
254 0824d6fc bellard
255 c4b1fcc0 bellard
void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
256 0824d6fc bellard
{
257 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
258 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
259 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
260 0824d6fc bellard
}
261 0824d6fc bellard
262 c4b1fcc0 bellard
uint32_t default_ioport_readl(void *opaque, uint32_t address)
263 0824d6fc bellard
{
264 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
265 1196be37 ths
    fprintf(stderr, "unused inl: port=0x%04x\n", address);
266 fc01f7e7 bellard
#endif
267 fc01f7e7 bellard
    return 0xffffffff;
268 0824d6fc bellard
}
269 0824d6fc bellard
270 c4b1fcc0 bellard
void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
271 0824d6fc bellard
{
272 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
273 1196be37 ths
    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
274 fc01f7e7 bellard
#endif
275 0824d6fc bellard
}
276 0824d6fc bellard
277 fc01f7e7 bellard
void init_ioports(void)
278 0824d6fc bellard
{
279 0824d6fc bellard
    int i;
280 0824d6fc bellard
281 fc01f7e7 bellard
    for(i = 0; i < MAX_IOPORTS; i++) {
282 fc01f7e7 bellard
        ioport_read_table[0][i] = default_ioport_readb;
283 fc01f7e7 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
284 fc01f7e7 bellard
        ioport_read_table[1][i] = default_ioport_readw;
285 fc01f7e7 bellard
        ioport_write_table[1][i] = default_ioport_writew;
286 fc01f7e7 bellard
        ioport_read_table[2][i] = default_ioport_readl;
287 fc01f7e7 bellard
        ioport_write_table[2][i] = default_ioport_writel;
288 fc01f7e7 bellard
    }
289 0824d6fc bellard
}
290 0824d6fc bellard
291 fc01f7e7 bellard
/* size is the word size in byte */
292 5fafdf24 ths
int register_ioport_read(int start, int length, int size,
293 c4b1fcc0 bellard
                         IOPortReadFunc *func, void *opaque)
294 f1510b2c bellard
{
295 fc01f7e7 bellard
    int i, bsize;
296 f1510b2c bellard
297 c4b1fcc0 bellard
    if (size == 1) {
298 fc01f7e7 bellard
        bsize = 0;
299 c4b1fcc0 bellard
    } else if (size == 2) {
300 fc01f7e7 bellard
        bsize = 1;
301 c4b1fcc0 bellard
    } else if (size == 4) {
302 fc01f7e7 bellard
        bsize = 2;
303 c4b1fcc0 bellard
    } else {
304 c4b1fcc0 bellard
        hw_error("register_ioport_read: invalid size");
305 fc01f7e7 bellard
        return -1;
306 c4b1fcc0 bellard
    }
307 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
308 fc01f7e7 bellard
        ioport_read_table[bsize][i] = func;
309 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
310 c4b1fcc0 bellard
            hw_error("register_ioport_read: invalid opaque");
311 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
312 c4b1fcc0 bellard
    }
313 f1510b2c bellard
    return 0;
314 f1510b2c bellard
}
315 f1510b2c bellard
316 fc01f7e7 bellard
/* size is the word size in byte */
317 5fafdf24 ths
int register_ioport_write(int start, int length, int size,
318 c4b1fcc0 bellard
                          IOPortWriteFunc *func, void *opaque)
319 f1510b2c bellard
{
320 fc01f7e7 bellard
    int i, bsize;
321 f1510b2c bellard
322 c4b1fcc0 bellard
    if (size == 1) {
323 fc01f7e7 bellard
        bsize = 0;
324 c4b1fcc0 bellard
    } else if (size == 2) {
325 fc01f7e7 bellard
        bsize = 1;
326 c4b1fcc0 bellard
    } else if (size == 4) {
327 fc01f7e7 bellard
        bsize = 2;
328 c4b1fcc0 bellard
    } else {
329 c4b1fcc0 bellard
        hw_error("register_ioport_write: invalid size");
330 fc01f7e7 bellard
        return -1;
331 c4b1fcc0 bellard
    }
332 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
333 fc01f7e7 bellard
        ioport_write_table[bsize][i] = func;
334 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
335 52f61fde ths
            hw_error("register_ioport_write: invalid opaque");
336 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
337 c4b1fcc0 bellard
    }
338 f1510b2c bellard
    return 0;
339 f1510b2c bellard
}
340 f1510b2c bellard
341 69b91039 bellard
void isa_unassign_ioport(int start, int length)
342 69b91039 bellard
{
343 69b91039 bellard
    int i;
344 69b91039 bellard
345 69b91039 bellard
    for(i = start; i < start + length; i++) {
346 69b91039 bellard
        ioport_read_table[0][i] = default_ioport_readb;
347 69b91039 bellard
        ioport_read_table[1][i] = default_ioport_readw;
348 69b91039 bellard
        ioport_read_table[2][i] = default_ioport_readl;
349 69b91039 bellard
350 69b91039 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
351 69b91039 bellard
        ioport_write_table[1][i] = default_ioport_writew;
352 69b91039 bellard
        ioport_write_table[2][i] = default_ioport_writel;
353 69b91039 bellard
    }
354 69b91039 bellard
}
355 69b91039 bellard
356 20f32282 bellard
/***********************************************************/
357 20f32282 bellard
358 c45886db bellard
void cpu_outb(CPUState *env, int addr, int val)
359 0824d6fc bellard
{
360 fd872598 bellard
#ifdef DEBUG_IOPORT
361 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
362 fd872598 bellard
        fprintf(logfile, "outb: %04x %02x\n", addr, val);
363 3b46e624 ths
#endif
364 c4b1fcc0 bellard
    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
365 89bfc105 bellard
#ifdef USE_KQEMU
366 89bfc105 bellard
    if (env)
367 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
368 89bfc105 bellard
#endif
369 0824d6fc bellard
}
370 0824d6fc bellard
371 c45886db bellard
void cpu_outw(CPUState *env, int addr, int val)
372 0824d6fc bellard
{
373 fd872598 bellard
#ifdef DEBUG_IOPORT
374 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
375 fd872598 bellard
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
376 3b46e624 ths
#endif
377 c4b1fcc0 bellard
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
378 89bfc105 bellard
#ifdef USE_KQEMU
379 89bfc105 bellard
    if (env)
380 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
381 89bfc105 bellard
#endif
382 0824d6fc bellard
}
383 0824d6fc bellard
384 c45886db bellard
void cpu_outl(CPUState *env, int addr, int val)
385 0824d6fc bellard
{
386 fd872598 bellard
#ifdef DEBUG_IOPORT
387 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
388 fd872598 bellard
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
389 fd872598 bellard
#endif
390 c4b1fcc0 bellard
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
391 89bfc105 bellard
#ifdef USE_KQEMU
392 89bfc105 bellard
    if (env)
393 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
394 89bfc105 bellard
#endif
395 0824d6fc bellard
}
396 0824d6fc bellard
397 c45886db bellard
int cpu_inb(CPUState *env, int addr)
398 0824d6fc bellard
{
399 fd872598 bellard
    int val;
400 fd872598 bellard
    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
401 fd872598 bellard
#ifdef DEBUG_IOPORT
402 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
403 fd872598 bellard
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
404 fd872598 bellard
#endif
405 89bfc105 bellard
#ifdef USE_KQEMU
406 89bfc105 bellard
    if (env)
407 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
408 89bfc105 bellard
#endif
409 fd872598 bellard
    return val;
410 0824d6fc bellard
}
411 0824d6fc bellard
412 c45886db bellard
int cpu_inw(CPUState *env, int addr)
413 0824d6fc bellard
{
414 fd872598 bellard
    int val;
415 fd872598 bellard
    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
416 fd872598 bellard
#ifdef DEBUG_IOPORT
417 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
418 fd872598 bellard
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
419 fd872598 bellard
#endif
420 89bfc105 bellard
#ifdef USE_KQEMU
421 89bfc105 bellard
    if (env)
422 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
423 89bfc105 bellard
#endif
424 fd872598 bellard
    return val;
425 0824d6fc bellard
}
426 0824d6fc bellard
427 c45886db bellard
int cpu_inl(CPUState *env, int addr)
428 0824d6fc bellard
{
429 fd872598 bellard
    int val;
430 fd872598 bellard
    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
431 fd872598 bellard
#ifdef DEBUG_IOPORT
432 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
433 fd872598 bellard
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
434 fd872598 bellard
#endif
435 89bfc105 bellard
#ifdef USE_KQEMU
436 89bfc105 bellard
    if (env)
437 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
438 89bfc105 bellard
#endif
439 fd872598 bellard
    return val;
440 0824d6fc bellard
}
441 0824d6fc bellard
442 0824d6fc bellard
/***********************************************************/
443 0824d6fc bellard
void hw_error(const char *fmt, ...)
444 0824d6fc bellard
{
445 0824d6fc bellard
    va_list ap;
446 6a00d601 bellard
    CPUState *env;
447 0824d6fc bellard
448 0824d6fc bellard
    va_start(ap, fmt);
449 0824d6fc bellard
    fprintf(stderr, "qemu: hardware error: ");
450 0824d6fc bellard
    vfprintf(stderr, fmt, ap);
451 0824d6fc bellard
    fprintf(stderr, "\n");
452 6a00d601 bellard
    for(env = first_cpu; env != NULL; env = env->next_cpu) {
453 6a00d601 bellard
        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
454 0824d6fc bellard
#ifdef TARGET_I386
455 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
456 c45886db bellard
#else
457 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, 0);
458 0824d6fc bellard
#endif
459 6a00d601 bellard
    }
460 0824d6fc bellard
    va_end(ap);
461 0824d6fc bellard
    abort();
462 0824d6fc bellard
}
463 0824d6fc bellard
464 8a7ddc38 bellard
/***********************************************************/
465 63066f4f bellard
/* keyboard/mouse */
466 63066f4f bellard
467 63066f4f bellard
static QEMUPutKBDEvent *qemu_put_kbd_event;
468 63066f4f bellard
static void *qemu_put_kbd_event_opaque;
469 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_head;
470 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_current;
471 63066f4f bellard
472 63066f4f bellard
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
473 63066f4f bellard
{
474 63066f4f bellard
    qemu_put_kbd_event_opaque = opaque;
475 63066f4f bellard
    qemu_put_kbd_event = func;
476 63066f4f bellard
}
477 63066f4f bellard
478 455204eb ths
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
479 455204eb ths
                                                void *opaque, int absolute,
480 455204eb ths
                                                const char *name)
481 63066f4f bellard
{
482 455204eb ths
    QEMUPutMouseEntry *s, *cursor;
483 455204eb ths
484 455204eb ths
    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
485 455204eb ths
    if (!s)
486 455204eb ths
        return NULL;
487 455204eb ths
488 455204eb ths
    s->qemu_put_mouse_event = func;
489 455204eb ths
    s->qemu_put_mouse_event_opaque = opaque;
490 455204eb ths
    s->qemu_put_mouse_event_absolute = absolute;
491 455204eb ths
    s->qemu_put_mouse_event_name = qemu_strdup(name);
492 455204eb ths
    s->next = NULL;
493 455204eb ths
494 455204eb ths
    if (!qemu_put_mouse_event_head) {
495 455204eb ths
        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
496 455204eb ths
        return s;
497 455204eb ths
    }
498 455204eb ths
499 455204eb ths
    cursor = qemu_put_mouse_event_head;
500 455204eb ths
    while (cursor->next != NULL)
501 455204eb ths
        cursor = cursor->next;
502 455204eb ths
503 455204eb ths
    cursor->next = s;
504 455204eb ths
    qemu_put_mouse_event_current = s;
505 455204eb ths
506 455204eb ths
    return s;
507 455204eb ths
}
508 455204eb ths
509 455204eb ths
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
510 455204eb ths
{
511 455204eb ths
    QEMUPutMouseEntry *prev = NULL, *cursor;
512 455204eb ths
513 455204eb ths
    if (!qemu_put_mouse_event_head || entry == NULL)
514 455204eb ths
        return;
515 455204eb ths
516 455204eb ths
    cursor = qemu_put_mouse_event_head;
517 455204eb ths
    while (cursor != NULL && cursor != entry) {
518 455204eb ths
        prev = cursor;
519 455204eb ths
        cursor = cursor->next;
520 455204eb ths
    }
521 455204eb ths
522 455204eb ths
    if (cursor == NULL) // does not exist or list empty
523 455204eb ths
        return;
524 455204eb ths
    else if (prev == NULL) { // entry is head
525 455204eb ths
        qemu_put_mouse_event_head = cursor->next;
526 455204eb ths
        if (qemu_put_mouse_event_current == entry)
527 455204eb ths
            qemu_put_mouse_event_current = cursor->next;
528 455204eb ths
        qemu_free(entry->qemu_put_mouse_event_name);
529 455204eb ths
        qemu_free(entry);
530 455204eb ths
        return;
531 455204eb ths
    }
532 455204eb ths
533 455204eb ths
    prev->next = entry->next;
534 455204eb ths
535 455204eb ths
    if (qemu_put_mouse_event_current == entry)
536 455204eb ths
        qemu_put_mouse_event_current = prev;
537 455204eb ths
538 455204eb ths
    qemu_free(entry->qemu_put_mouse_event_name);
539 455204eb ths
    qemu_free(entry);
540 63066f4f bellard
}
541 63066f4f bellard
542 63066f4f bellard
void kbd_put_keycode(int keycode)
543 63066f4f bellard
{
544 63066f4f bellard
    if (qemu_put_kbd_event) {
545 63066f4f bellard
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
546 63066f4f bellard
    }
547 63066f4f bellard
}
548 63066f4f bellard
549 63066f4f bellard
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
550 63066f4f bellard
{
551 455204eb ths
    QEMUPutMouseEvent *mouse_event;
552 455204eb ths
    void *mouse_event_opaque;
553 a171fe39 balrog
    int width;
554 455204eb ths
555 455204eb ths
    if (!qemu_put_mouse_event_current) {
556 455204eb ths
        return;
557 455204eb ths
    }
558 455204eb ths
559 455204eb ths
    mouse_event =
560 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event;
561 455204eb ths
    mouse_event_opaque =
562 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
563 455204eb ths
564 455204eb ths
    if (mouse_event) {
565 a171fe39 balrog
        if (graphic_rotate) {
566 a171fe39 balrog
            if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
567 a171fe39 balrog
                width = 0x7fff;
568 a171fe39 balrog
            else
569 a171fe39 balrog
                width = graphic_width;
570 a171fe39 balrog
            mouse_event(mouse_event_opaque,
571 a171fe39 balrog
                                 width - dy, dx, dz, buttons_state);
572 a171fe39 balrog
        } else
573 a171fe39 balrog
            mouse_event(mouse_event_opaque,
574 a171fe39 balrog
                                 dx, dy, dz, buttons_state);
575 63066f4f bellard
    }
576 63066f4f bellard
}
577 63066f4f bellard
578 09b26c5e bellard
int kbd_mouse_is_absolute(void)
579 09b26c5e bellard
{
580 455204eb ths
    if (!qemu_put_mouse_event_current)
581 455204eb ths
        return 0;
582 455204eb ths
583 455204eb ths
    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
584 455204eb ths
}
585 455204eb ths
586 455204eb ths
void do_info_mice(void)
587 455204eb ths
{
588 455204eb ths
    QEMUPutMouseEntry *cursor;
589 455204eb ths
    int index = 0;
590 455204eb ths
591 455204eb ths
    if (!qemu_put_mouse_event_head) {
592 455204eb ths
        term_printf("No mouse devices connected\n");
593 455204eb ths
        return;
594 455204eb ths
    }
595 455204eb ths
596 455204eb ths
    term_printf("Mouse devices available:\n");
597 455204eb ths
    cursor = qemu_put_mouse_event_head;
598 455204eb ths
    while (cursor != NULL) {
599 455204eb ths
        term_printf("%c Mouse #%d: %s\n",
600 455204eb ths
                    (cursor == qemu_put_mouse_event_current ? '*' : ' '),
601 455204eb ths
                    index, cursor->qemu_put_mouse_event_name);
602 455204eb ths
        index++;
603 455204eb ths
        cursor = cursor->next;
604 455204eb ths
    }
605 455204eb ths
}
606 455204eb ths
607 455204eb ths
void do_mouse_set(int index)
608 455204eb ths
{
609 455204eb ths
    QEMUPutMouseEntry *cursor;
610 455204eb ths
    int i = 0;
611 455204eb ths
612 455204eb ths
    if (!qemu_put_mouse_event_head) {
613 455204eb ths
        term_printf("No mouse devices connected\n");
614 455204eb ths
        return;
615 455204eb ths
    }
616 455204eb ths
617 455204eb ths
    cursor = qemu_put_mouse_event_head;
618 455204eb ths
    while (cursor != NULL && index != i) {
619 455204eb ths
        i++;
620 455204eb ths
        cursor = cursor->next;
621 455204eb ths
    }
622 455204eb ths
623 455204eb ths
    if (cursor != NULL)
624 455204eb ths
        qemu_put_mouse_event_current = cursor;
625 455204eb ths
    else
626 455204eb ths
        term_printf("Mouse at given index not found\n");
627 09b26c5e bellard
}
628 09b26c5e bellard
629 1dce7c3c bellard
/* compute with 96 bit intermediate result: (a*b)/c */
630 1dce7c3c bellard
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
631 0824d6fc bellard
{
632 1dce7c3c bellard
    union {
633 1dce7c3c bellard
        uint64_t ll;
634 1dce7c3c bellard
        struct {
635 1dce7c3c bellard
#ifdef WORDS_BIGENDIAN
636 1dce7c3c bellard
            uint32_t high, low;
637 1dce7c3c bellard
#else
638 1dce7c3c bellard
            uint32_t low, high;
639 3b46e624 ths
#endif
640 1dce7c3c bellard
        } l;
641 1dce7c3c bellard
    } u, res;
642 1dce7c3c bellard
    uint64_t rl, rh;
643 0824d6fc bellard
644 1dce7c3c bellard
    u.ll = a;
645 1dce7c3c bellard
    rl = (uint64_t)u.l.low * (uint64_t)b;
646 1dce7c3c bellard
    rh = (uint64_t)u.l.high * (uint64_t)b;
647 1dce7c3c bellard
    rh += (rl >> 32);
648 1dce7c3c bellard
    res.l.high = rh / c;
649 1dce7c3c bellard
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
650 1dce7c3c bellard
    return res.ll;
651 34865134 bellard
}
652 34865134 bellard
653 1dce7c3c bellard
/***********************************************************/
654 1dce7c3c bellard
/* real time host monotonic timer */
655 34865134 bellard
656 1dce7c3c bellard
#define QEMU_TIMER_BASE 1000000000LL
657 34865134 bellard
658 1dce7c3c bellard
#ifdef WIN32
659 0824d6fc bellard
660 1dce7c3c bellard
static int64_t clock_freq;
661 1115dde7 bellard
662 1dce7c3c bellard
static void init_get_clock(void)
663 1115dde7 bellard
{
664 a8e5ac33 bellard
    LARGE_INTEGER freq;
665 a8e5ac33 bellard
    int ret;
666 1dce7c3c bellard
    ret = QueryPerformanceFrequency(&freq);
667 1dce7c3c bellard
    if (ret == 0) {
668 1dce7c3c bellard
        fprintf(stderr, "Could not calibrate ticks\n");
669 1dce7c3c bellard
        exit(1);
670 1dce7c3c bellard
    }
671 1dce7c3c bellard
    clock_freq = freq.QuadPart;
672 1115dde7 bellard
}
673 1115dde7 bellard
674 1dce7c3c bellard
static int64_t get_clock(void)
675 b8076a74 bellard
{
676 1dce7c3c bellard
    LARGE_INTEGER ti;
677 1dce7c3c bellard
    QueryPerformanceCounter(&ti);
678 1dce7c3c bellard
    return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
679 b8076a74 bellard
}
680 b8076a74 bellard
681 1dce7c3c bellard
#else
682 90cb9493 bellard
683 1dce7c3c bellard
static int use_rt_clock;
684 1dce7c3c bellard
685 1dce7c3c bellard
static void init_get_clock(void)
686 90cb9493 bellard
{
687 1dce7c3c bellard
    use_rt_clock = 0;
688 1dce7c3c bellard
#if defined(__linux__)
689 1dce7c3c bellard
    {
690 1dce7c3c bellard
        struct timespec ts;
691 1dce7c3c bellard
        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
692 1dce7c3c bellard
            use_rt_clock = 1;
693 1dce7c3c bellard
        }
694 1dce7c3c bellard
    }
695 1dce7c3c bellard
#endif
696 90cb9493 bellard
}
697 90cb9493 bellard
698 1dce7c3c bellard
static int64_t get_clock(void)
699 fdbb4691 bellard
{
700 1dce7c3c bellard
#if defined(__linux__)
701 1dce7c3c bellard
    if (use_rt_clock) {
702 1dce7c3c bellard
        struct timespec ts;
703 1dce7c3c bellard
        clock_gettime(CLOCK_MONOTONIC, &ts);
704 1dce7c3c bellard
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
705 5fafdf24 ths
    } else
706 fdbb4691 bellard
#endif
707 1dce7c3c bellard
    {
708 1dce7c3c bellard
        /* XXX: using gettimeofday leads to problems if the date
709 1dce7c3c bellard
           changes, so it should be avoided. */
710 1dce7c3c bellard
        struct timeval tv;
711 1dce7c3c bellard
        gettimeofday(&tv, NULL);
712 1dce7c3c bellard
        return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
713 1dce7c3c bellard
    }
714 fdbb4691 bellard
}
715 fdbb4691 bellard
716 34865134 bellard
#endif
717 34865134 bellard
718 1dce7c3c bellard
/***********************************************************/
719 1dce7c3c bellard
/* guest cycle counter */
720 1dce7c3c bellard
721 eade0f19 bellard
static int64_t cpu_ticks_prev;
722 34865134 bellard
static int64_t cpu_ticks_offset;
723 1dce7c3c bellard
static int64_t cpu_clock_offset;
724 8a7ddc38 bellard
static int cpu_ticks_enabled;
725 34865134 bellard
726 1dce7c3c bellard
/* return the host CPU cycle counter and handle stop/restart */
727 1dce7c3c bellard
int64_t cpu_get_ticks(void)
728 34865134 bellard
{
729 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
730 8a7ddc38 bellard
        return cpu_ticks_offset;
731 8a7ddc38 bellard
    } else {
732 eade0f19 bellard
        int64_t ticks;
733 eade0f19 bellard
        ticks = cpu_get_real_ticks();
734 eade0f19 bellard
        if (cpu_ticks_prev > ticks) {
735 eade0f19 bellard
            /* Note: non increasing ticks may happen if the host uses
736 eade0f19 bellard
               software suspend */
737 eade0f19 bellard
            cpu_ticks_offset += cpu_ticks_prev - ticks;
738 eade0f19 bellard
        }
739 eade0f19 bellard
        cpu_ticks_prev = ticks;
740 eade0f19 bellard
        return ticks + cpu_ticks_offset;
741 8a7ddc38 bellard
    }
742 34865134 bellard
}
743 34865134 bellard
744 1dce7c3c bellard
/* return the host CPU monotonic timer and handle stop/restart */
745 1dce7c3c bellard
static int64_t cpu_get_clock(void)
746 1dce7c3c bellard
{
747 1dce7c3c bellard
    int64_t ti;
748 1dce7c3c bellard
    if (!cpu_ticks_enabled) {
749 1dce7c3c bellard
        return cpu_clock_offset;
750 1dce7c3c bellard
    } else {
751 1dce7c3c bellard
        ti = get_clock();
752 1dce7c3c bellard
        return ti + cpu_clock_offset;
753 1dce7c3c bellard
    }
754 1dce7c3c bellard
}
755 1dce7c3c bellard
756 34865134 bellard
/* enable cpu_get_ticks() */
757 34865134 bellard
void cpu_enable_ticks(void)
758 34865134 bellard
{
759 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
760 8a7ddc38 bellard
        cpu_ticks_offset -= cpu_get_real_ticks();
761 1dce7c3c bellard
        cpu_clock_offset -= get_clock();
762 8a7ddc38 bellard
        cpu_ticks_enabled = 1;
763 8a7ddc38 bellard
    }
764 34865134 bellard
}
765 34865134 bellard
766 34865134 bellard
/* disable cpu_get_ticks() : the clock is stopped. You must not call
767 34865134 bellard
   cpu_get_ticks() after that.  */
768 34865134 bellard
void cpu_disable_ticks(void)
769 34865134 bellard
{
770 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
771 8a7ddc38 bellard
        cpu_ticks_offset = cpu_get_ticks();
772 1dce7c3c bellard
        cpu_clock_offset = cpu_get_clock();
773 8a7ddc38 bellard
        cpu_ticks_enabled = 0;
774 8a7ddc38 bellard
    }
775 34865134 bellard
}
776 34865134 bellard
777 1dce7c3c bellard
/***********************************************************/
778 1dce7c3c bellard
/* timers */
779 5fafdf24 ths
780 8a7ddc38 bellard
#define QEMU_TIMER_REALTIME 0
781 8a7ddc38 bellard
#define QEMU_TIMER_VIRTUAL  1
782 8a7ddc38 bellard
783 8a7ddc38 bellard
struct QEMUClock {
784 8a7ddc38 bellard
    int type;
785 8a7ddc38 bellard
    /* XXX: add frequency */
786 8a7ddc38 bellard
};
787 8a7ddc38 bellard
788 8a7ddc38 bellard
struct QEMUTimer {
789 8a7ddc38 bellard
    QEMUClock *clock;
790 8a7ddc38 bellard
    int64_t expire_time;
791 8a7ddc38 bellard
    QEMUTimerCB *cb;
792 8a7ddc38 bellard
    void *opaque;
793 8a7ddc38 bellard
    struct QEMUTimer *next;
794 8a7ddc38 bellard
};
795 8a7ddc38 bellard
796 c8994013 ths
struct qemu_alarm_timer {
797 c8994013 ths
    char const *name;
798 efe75411 ths
    unsigned int flags;
799 c8994013 ths
800 c8994013 ths
    int (*start)(struct qemu_alarm_timer *t);
801 c8994013 ths
    void (*stop)(struct qemu_alarm_timer *t);
802 efe75411 ths
    void (*rearm)(struct qemu_alarm_timer *t);
803 c8994013 ths
    void *priv;
804 c8994013 ths
};
805 c8994013 ths
806 efe75411 ths
#define ALARM_FLAG_DYNTICKS  0x1
807 efe75411 ths
808 efe75411 ths
static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
809 efe75411 ths
{
810 efe75411 ths
    return t->flags & ALARM_FLAG_DYNTICKS;
811 efe75411 ths
}
812 efe75411 ths
813 efe75411 ths
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
814 efe75411 ths
{
815 efe75411 ths
    if (!alarm_has_dynticks(t))
816 efe75411 ths
        return;
817 efe75411 ths
818 efe75411 ths
    t->rearm(t);
819 efe75411 ths
}
820 efe75411 ths
821 efe75411 ths
/* TODO: MIN_TIMER_REARM_US should be optimized */
822 efe75411 ths
#define MIN_TIMER_REARM_US 250
823 efe75411 ths
824 c8994013 ths
static struct qemu_alarm_timer *alarm_timer;
825 8a7ddc38 bellard
826 40c3bac3 bellard
#ifdef _WIN32
827 c8994013 ths
828 c8994013 ths
struct qemu_alarm_win32 {
829 c8994013 ths
    MMRESULT timerId;
830 c8994013 ths
    HANDLE host_alarm;
831 c8994013 ths
    unsigned int period;
832 c8994013 ths
} alarm_win32_data = {0, NULL, -1};
833 c8994013 ths
834 c8994013 ths
static int win32_start_timer(struct qemu_alarm_timer *t);
835 c8994013 ths
static void win32_stop_timer(struct qemu_alarm_timer *t);
836 efe75411 ths
static void win32_rearm_timer(struct qemu_alarm_timer *t);
837 c8994013 ths
838 40c3bac3 bellard
#else
839 c8994013 ths
840 c8994013 ths
static int unix_start_timer(struct qemu_alarm_timer *t);
841 c8994013 ths
static void unix_stop_timer(struct qemu_alarm_timer *t);
842 c8994013 ths
843 231c6586 ths
#ifdef __linux__
844 231c6586 ths
845 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t);
846 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
847 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
848 efe75411 ths
849 c40ec5a9 ths
static int hpet_start_timer(struct qemu_alarm_timer *t);
850 c40ec5a9 ths
static void hpet_stop_timer(struct qemu_alarm_timer *t);
851 c40ec5a9 ths
852 c8994013 ths
static int rtc_start_timer(struct qemu_alarm_timer *t);
853 c8994013 ths
static void rtc_stop_timer(struct qemu_alarm_timer *t);
854 c8994013 ths
855 efe75411 ths
#endif /* __linux__ */
856 8a7ddc38 bellard
857 c8994013 ths
#endif /* _WIN32 */
858 c8994013 ths
859 c8994013 ths
static struct qemu_alarm_timer alarm_timers[] = {
860 efe75411 ths
#ifndef _WIN32
861 231c6586 ths
#ifdef __linux__
862 efe75411 ths
    {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
863 efe75411 ths
     dynticks_stop_timer, dynticks_rearm_timer, NULL},
864 c40ec5a9 ths
    /* HPET - if available - is preferred */
865 efe75411 ths
    {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
866 c40ec5a9 ths
    /* ...otherwise try RTC */
867 efe75411 ths
    {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
868 c8994013 ths
#endif
869 efe75411 ths
    {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
870 c8994013 ths
#else
871 efe75411 ths
    {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
872 efe75411 ths
     win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
873 efe75411 ths
    {"win32", 0, win32_start_timer,
874 efe75411 ths
     win32_stop_timer, NULL, &alarm_win32_data},
875 c8994013 ths
#endif
876 c8994013 ths
    {NULL, }
877 c8994013 ths
};
878 c8994013 ths
879 f3dcfada ths
static void show_available_alarms()
880 f3dcfada ths
{
881 f3dcfada ths
    int i;
882 f3dcfada ths
883 f3dcfada ths
    printf("Available alarm timers, in order of precedence:\n");
884 f3dcfada ths
    for (i = 0; alarm_timers[i].name; i++)
885 f3dcfada ths
        printf("%s\n", alarm_timers[i].name);
886 f3dcfada ths
}
887 f3dcfada ths
888 f3dcfada ths
static void configure_alarms(char const *opt)
889 f3dcfada ths
{
890 f3dcfada ths
    int i;
891 f3dcfada ths
    int cur = 0;
892 f3dcfada ths
    int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
893 f3dcfada ths
    char *arg;
894 f3dcfada ths
    char *name;
895 f3dcfada ths
896 f3dcfada ths
    if (!strcmp(opt, "help")) {
897 f3dcfada ths
        show_available_alarms();
898 f3dcfada ths
        exit(0);
899 f3dcfada ths
    }
900 f3dcfada ths
901 f3dcfada ths
    arg = strdup(opt);
902 f3dcfada ths
903 f3dcfada ths
    /* Reorder the array */
904 f3dcfada ths
    name = strtok(arg, ",");
905 f3dcfada ths
    while (name) {
906 f3dcfada ths
        struct qemu_alarm_timer tmp;
907 f3dcfada ths
908 e2b577e5 balrog
        for (i = 0; i < count && alarm_timers[i].name; i++) {
909 f3dcfada ths
            if (!strcmp(alarm_timers[i].name, name))
910 f3dcfada ths
                break;
911 f3dcfada ths
        }
912 f3dcfada ths
913 f3dcfada ths
        if (i == count) {
914 f3dcfada ths
            fprintf(stderr, "Unknown clock %s\n", name);
915 f3dcfada ths
            goto next;
916 f3dcfada ths
        }
917 f3dcfada ths
918 f3dcfada ths
        if (i < cur)
919 f3dcfada ths
            /* Ignore */
920 f3dcfada ths
            goto next;
921 f3dcfada ths
922 f3dcfada ths
        /* Swap */
923 f3dcfada ths
        tmp = alarm_timers[i];
924 f3dcfada ths
        alarm_timers[i] = alarm_timers[cur];
925 f3dcfada ths
        alarm_timers[cur] = tmp;
926 f3dcfada ths
927 f3dcfada ths
        cur++;
928 f3dcfada ths
next:
929 f3dcfada ths
        name = strtok(NULL, ",");
930 f3dcfada ths
    }
931 f3dcfada ths
932 f3dcfada ths
    free(arg);
933 f3dcfada ths
934 f3dcfada ths
    if (cur) {
935 f3dcfada ths
        /* Disable remaining timers */
936 f3dcfada ths
        for (i = cur; i < count; i++)
937 f3dcfada ths
            alarm_timers[i].name = NULL;
938 f3dcfada ths
    }
939 f3dcfada ths
940 f3dcfada ths
    /* debug */
941 f3dcfada ths
    show_available_alarms();
942 f3dcfada ths
}
943 f3dcfada ths
944 c8994013 ths
QEMUClock *rt_clock;
945 c8994013 ths
QEMUClock *vm_clock;
946 c8994013 ths
947 c8994013 ths
static QEMUTimer *active_timers[2];
948 c8994013 ths
949 8a7ddc38 bellard
QEMUClock *qemu_new_clock(int type)
950 8a7ddc38 bellard
{
951 8a7ddc38 bellard
    QEMUClock *clock;
952 8a7ddc38 bellard
    clock = qemu_mallocz(sizeof(QEMUClock));
953 8a7ddc38 bellard
    if (!clock)
954 8a7ddc38 bellard
        return NULL;
955 8a7ddc38 bellard
    clock->type = type;
956 8a7ddc38 bellard
    return clock;
957 8a7ddc38 bellard
}
958 8a7ddc38 bellard
959 8a7ddc38 bellard
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
960 8a7ddc38 bellard
{
961 8a7ddc38 bellard
    QEMUTimer *ts;
962 8a7ddc38 bellard
963 8a7ddc38 bellard
    ts = qemu_mallocz(sizeof(QEMUTimer));
964 8a7ddc38 bellard
    ts->clock = clock;
965 8a7ddc38 bellard
    ts->cb = cb;
966 8a7ddc38 bellard
    ts->opaque = opaque;
967 8a7ddc38 bellard
    return ts;
968 8a7ddc38 bellard
}
969 8a7ddc38 bellard
970 8a7ddc38 bellard
void qemu_free_timer(QEMUTimer *ts)
971 8a7ddc38 bellard
{
972 8a7ddc38 bellard
    qemu_free(ts);
973 8a7ddc38 bellard
}
974 8a7ddc38 bellard
975 8a7ddc38 bellard
/* stop a timer, but do not dealloc it */
976 8a7ddc38 bellard
void qemu_del_timer(QEMUTimer *ts)
977 8a7ddc38 bellard
{
978 8a7ddc38 bellard
    QEMUTimer **pt, *t;
979 8a7ddc38 bellard
980 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
981 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
982 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
983 8a7ddc38 bellard
    for(;;) {
984 8a7ddc38 bellard
        t = *pt;
985 8a7ddc38 bellard
        if (!t)
986 8a7ddc38 bellard
            break;
987 8a7ddc38 bellard
        if (t == ts) {
988 8a7ddc38 bellard
            *pt = t->next;
989 8a7ddc38 bellard
            break;
990 8a7ddc38 bellard
        }
991 8a7ddc38 bellard
        pt = &t->next;
992 8a7ddc38 bellard
    }
993 8a7ddc38 bellard
}
994 8a7ddc38 bellard
995 8a7ddc38 bellard
/* modify the current timer so that it will be fired when current_time
996 8a7ddc38 bellard
   >= expire_time. The corresponding callback will be called. */
997 8a7ddc38 bellard
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
998 8a7ddc38 bellard
{
999 8a7ddc38 bellard
    QEMUTimer **pt, *t;
1000 8a7ddc38 bellard
1001 8a7ddc38 bellard
    qemu_del_timer(ts);
1002 8a7ddc38 bellard
1003 8a7ddc38 bellard
    /* add the timer in the sorted list */
1004 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
1005 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
1006 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
1007 8a7ddc38 bellard
    for(;;) {
1008 8a7ddc38 bellard
        t = *pt;
1009 8a7ddc38 bellard
        if (!t)
1010 8a7ddc38 bellard
            break;
1011 5fafdf24 ths
        if (t->expire_time > expire_time)
1012 8a7ddc38 bellard
            break;
1013 8a7ddc38 bellard
        pt = &t->next;
1014 8a7ddc38 bellard
    }
1015 8a7ddc38 bellard
    ts->expire_time = expire_time;
1016 8a7ddc38 bellard
    ts->next = *pt;
1017 8a7ddc38 bellard
    *pt = ts;
1018 8a7ddc38 bellard
}
1019 8a7ddc38 bellard
1020 8a7ddc38 bellard
int qemu_timer_pending(QEMUTimer *ts)
1021 8a7ddc38 bellard
{
1022 8a7ddc38 bellard
    QEMUTimer *t;
1023 8a7ddc38 bellard
    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1024 8a7ddc38 bellard
        if (t == ts)
1025 8a7ddc38 bellard
            return 1;
1026 8a7ddc38 bellard
    }
1027 8a7ddc38 bellard
    return 0;
1028 8a7ddc38 bellard
}
1029 8a7ddc38 bellard
1030 8a7ddc38 bellard
static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1031 8a7ddc38 bellard
{
1032 8a7ddc38 bellard
    if (!timer_head)
1033 8a7ddc38 bellard
        return 0;
1034 8a7ddc38 bellard
    return (timer_head->expire_time <= current_time);
1035 8a7ddc38 bellard
}
1036 8a7ddc38 bellard
1037 8a7ddc38 bellard
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1038 8a7ddc38 bellard
{
1039 8a7ddc38 bellard
    QEMUTimer *ts;
1040 3b46e624 ths
1041 8a7ddc38 bellard
    for(;;) {
1042 8a7ddc38 bellard
        ts = *ptimer_head;
1043 e95c8d51 bellard
        if (!ts || ts->expire_time > current_time)
1044 8a7ddc38 bellard
            break;
1045 8a7ddc38 bellard
        /* remove timer from the list before calling the callback */
1046 8a7ddc38 bellard
        *ptimer_head = ts->next;
1047 8a7ddc38 bellard
        ts->next = NULL;
1048 3b46e624 ths
1049 8a7ddc38 bellard
        /* run the callback (the timer list can be modified) */
1050 8a7ddc38 bellard
        ts->cb(ts->opaque);
1051 8a7ddc38 bellard
    }
1052 efe75411 ths
    qemu_rearm_alarm_timer(alarm_timer);
1053 8a7ddc38 bellard
}
1054 8a7ddc38 bellard
1055 8a7ddc38 bellard
int64_t qemu_get_clock(QEMUClock *clock)
1056 8a7ddc38 bellard
{
1057 8a7ddc38 bellard
    switch(clock->type) {
1058 8a7ddc38 bellard
    case QEMU_TIMER_REALTIME:
1059 1dce7c3c bellard
        return get_clock() / 1000000;
1060 8a7ddc38 bellard
    default:
1061 8a7ddc38 bellard
    case QEMU_TIMER_VIRTUAL:
1062 1dce7c3c bellard
        return cpu_get_clock();
1063 8a7ddc38 bellard
    }
1064 8a7ddc38 bellard
}
1065 8a7ddc38 bellard
1066 1dce7c3c bellard
static void init_timers(void)
1067 1dce7c3c bellard
{
1068 1dce7c3c bellard
    init_get_clock();
1069 1dce7c3c bellard
    ticks_per_sec = QEMU_TIMER_BASE;
1070 1dce7c3c bellard
    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1071 1dce7c3c bellard
    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1072 1dce7c3c bellard
}
1073 1dce7c3c bellard
1074 8a7ddc38 bellard
/* save a timer */
1075 8a7ddc38 bellard
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1076 8a7ddc38 bellard
{
1077 8a7ddc38 bellard
    uint64_t expire_time;
1078 8a7ddc38 bellard
1079 8a7ddc38 bellard
    if (qemu_timer_pending(ts)) {
1080 8a7ddc38 bellard
        expire_time = ts->expire_time;
1081 8a7ddc38 bellard
    } else {
1082 8a7ddc38 bellard
        expire_time = -1;
1083 8a7ddc38 bellard
    }
1084 8a7ddc38 bellard
    qemu_put_be64(f, expire_time);
1085 8a7ddc38 bellard
}
1086 8a7ddc38 bellard
1087 8a7ddc38 bellard
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1088 8a7ddc38 bellard
{
1089 8a7ddc38 bellard
    uint64_t expire_time;
1090 8a7ddc38 bellard
1091 8a7ddc38 bellard
    expire_time = qemu_get_be64(f);
1092 8a7ddc38 bellard
    if (expire_time != -1) {
1093 8a7ddc38 bellard
        qemu_mod_timer(ts, expire_time);
1094 8a7ddc38 bellard
    } else {
1095 8a7ddc38 bellard
        qemu_del_timer(ts);
1096 8a7ddc38 bellard
    }
1097 8a7ddc38 bellard
}
1098 8a7ddc38 bellard
1099 8a7ddc38 bellard
static void timer_save(QEMUFile *f, void *opaque)
1100 8a7ddc38 bellard
{
1101 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
1102 8a7ddc38 bellard
        hw_error("cannot save state if virtual timers are running");
1103 8a7ddc38 bellard
    }
1104 8a7ddc38 bellard
    qemu_put_be64s(f, &cpu_ticks_offset);
1105 8a7ddc38 bellard
    qemu_put_be64s(f, &ticks_per_sec);
1106 c88676f8 bellard
    qemu_put_be64s(f, &cpu_clock_offset);
1107 8a7ddc38 bellard
}
1108 8a7ddc38 bellard
1109 8a7ddc38 bellard
static int timer_load(QEMUFile *f, void *opaque, int version_id)
1110 8a7ddc38 bellard
{
1111 c88676f8 bellard
    if (version_id != 1 && version_id != 2)
1112 8a7ddc38 bellard
        return -EINVAL;
1113 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
1114 8a7ddc38 bellard
        return -EINVAL;
1115 8a7ddc38 bellard
    }
1116 8a7ddc38 bellard
    qemu_get_be64s(f, &cpu_ticks_offset);
1117 8a7ddc38 bellard
    qemu_get_be64s(f, &ticks_per_sec);
1118 c88676f8 bellard
    if (version_id == 2) {
1119 c88676f8 bellard
        qemu_get_be64s(f, &cpu_clock_offset);
1120 c88676f8 bellard
    }
1121 8a7ddc38 bellard
    return 0;
1122 8a7ddc38 bellard
}
1123 8a7ddc38 bellard
1124 67b915a5 bellard
#ifdef _WIN32
1125 5fafdf24 ths
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1126 67b915a5 bellard
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1127 67b915a5 bellard
#else
1128 8a7ddc38 bellard
static void host_alarm_handler(int host_signum)
1129 67b915a5 bellard
#endif
1130 8a7ddc38 bellard
{
1131 02ba45c5 bellard
#if 0
1132 02ba45c5 bellard
#define DISP_FREQ 1000
1133 02ba45c5 bellard
    {
1134 02ba45c5 bellard
        static int64_t delta_min = INT64_MAX;
1135 02ba45c5 bellard
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
1136 02ba45c5 bellard
        static int count;
1137 02ba45c5 bellard
        ti = qemu_get_clock(vm_clock);
1138 02ba45c5 bellard
        if (last_clock != 0) {
1139 02ba45c5 bellard
            delta = ti - last_clock;
1140 02ba45c5 bellard
            if (delta < delta_min)
1141 02ba45c5 bellard
                delta_min = delta;
1142 02ba45c5 bellard
            if (delta > delta_max)
1143 02ba45c5 bellard
                delta_max = delta;
1144 02ba45c5 bellard
            delta_cum += delta;
1145 02ba45c5 bellard
            if (++count == DISP_FREQ) {
1146 26a76461 bellard
                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
1147 02ba45c5 bellard
                       muldiv64(delta_min, 1000000, ticks_per_sec),
1148 02ba45c5 bellard
                       muldiv64(delta_max, 1000000, ticks_per_sec),
1149 02ba45c5 bellard
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1150 02ba45c5 bellard
                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1151 02ba45c5 bellard
                count = 0;
1152 02ba45c5 bellard
                delta_min = INT64_MAX;
1153 02ba45c5 bellard
                delta_max = 0;
1154 02ba45c5 bellard
                delta_cum = 0;
1155 02ba45c5 bellard
            }
1156 02ba45c5 bellard
        }
1157 02ba45c5 bellard
        last_clock = ti;
1158 02ba45c5 bellard
    }
1159 02ba45c5 bellard
#endif
1160 efe75411 ths
    if (alarm_has_dynticks(alarm_timer) ||
1161 efe75411 ths
        qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1162 8a7ddc38 bellard
                           qemu_get_clock(vm_clock)) ||
1163 8a7ddc38 bellard
        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1164 8a7ddc38 bellard
                           qemu_get_clock(rt_clock))) {
1165 06d9f2f7 bellard
#ifdef _WIN32
1166 c8994013 ths
        struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1167 c8994013 ths
        SetEvent(data->host_alarm);
1168 06d9f2f7 bellard
#endif
1169 6a00d601 bellard
        CPUState *env = cpu_single_env;
1170 6a00d601 bellard
        if (env) {
1171 6a00d601 bellard
            /* stop the currently executing cpu because a timer occured */
1172 6a00d601 bellard
            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
1173 a332e112 bellard
#ifdef USE_KQEMU
1174 6a00d601 bellard
            if (env->kqemu_enabled) {
1175 6a00d601 bellard
                kqemu_cpu_interrupt(env);
1176 6a00d601 bellard
            }
1177 a332e112 bellard
#endif
1178 6a00d601 bellard
        }
1179 8a7ddc38 bellard
    }
1180 8a7ddc38 bellard
}
1181 8a7ddc38 bellard
1182 efe75411 ths
static uint64_t qemu_next_deadline(void)
1183 efe75411 ths
{
1184 49a9b725 balrog
    int64_t nearest_delta_us = INT64_MAX;
1185 efe75411 ths
    int64_t vmdelta_us;
1186 efe75411 ths
1187 efe75411 ths
    if (active_timers[QEMU_TIMER_REALTIME])
1188 efe75411 ths
        nearest_delta_us = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
1189 efe75411 ths
                            qemu_get_clock(rt_clock))*1000;
1190 efe75411 ths
1191 efe75411 ths
    if (active_timers[QEMU_TIMER_VIRTUAL]) {
1192 efe75411 ths
        /* round up */
1193 efe75411 ths
        vmdelta_us = (active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1194 efe75411 ths
                      qemu_get_clock(vm_clock)+999)/1000;
1195 efe75411 ths
        if (vmdelta_us < nearest_delta_us)
1196 efe75411 ths
            nearest_delta_us = vmdelta_us;
1197 efe75411 ths
    }
1198 efe75411 ths
1199 efe75411 ths
    /* Avoid arming the timer to negative, zero, or too low values */
1200 efe75411 ths
    if (nearest_delta_us <= MIN_TIMER_REARM_US)
1201 efe75411 ths
        nearest_delta_us = MIN_TIMER_REARM_US;
1202 efe75411 ths
1203 efe75411 ths
    return nearest_delta_us;
1204 efe75411 ths
}
1205 efe75411 ths
1206 fd872598 bellard
#ifndef _WIN32
1207 fd872598 bellard
1208 829309c7 bellard
#if defined(__linux__)
1209 829309c7 bellard
1210 fd872598 bellard
#define RTC_FREQ 1024
1211 fd872598 bellard
1212 c8994013 ths
static void enable_sigio_timer(int fd)
1213 c8994013 ths
{
1214 c8994013 ths
    struct sigaction act;
1215 c8994013 ths
1216 c8994013 ths
    /* timer signal */
1217 c8994013 ths
    sigfillset(&act.sa_mask);
1218 c8994013 ths
    act.sa_flags = 0;
1219 c8994013 ths
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
1220 c8994013 ths
    act.sa_flags |= SA_ONSTACK;
1221 c8994013 ths
#endif
1222 c8994013 ths
    act.sa_handler = host_alarm_handler;
1223 c8994013 ths
1224 c8994013 ths
    sigaction(SIGIO, &act, NULL);
1225 c8994013 ths
    fcntl(fd, F_SETFL, O_ASYNC);
1226 c8994013 ths
    fcntl(fd, F_SETOWN, getpid());
1227 c8994013 ths
}
1228 829309c7 bellard
1229 c40ec5a9 ths
static int hpet_start_timer(struct qemu_alarm_timer *t)
1230 c40ec5a9 ths
{
1231 c40ec5a9 ths
    struct hpet_info info;
1232 c40ec5a9 ths
    int r, fd;
1233 c40ec5a9 ths
1234 c40ec5a9 ths
    fd = open("/dev/hpet", O_RDONLY);
1235 c40ec5a9 ths
    if (fd < 0)
1236 c40ec5a9 ths
        return -1;
1237 c40ec5a9 ths
1238 c40ec5a9 ths
    /* Set frequency */
1239 c40ec5a9 ths
    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1240 c40ec5a9 ths
    if (r < 0) {
1241 c40ec5a9 ths
        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1242 c40ec5a9 ths
                "error, but for better emulation accuracy type:\n"
1243 c40ec5a9 ths
                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1244 c40ec5a9 ths
        goto fail;
1245 c40ec5a9 ths
    }
1246 c40ec5a9 ths
1247 c40ec5a9 ths
    /* Check capabilities */
1248 c40ec5a9 ths
    r = ioctl(fd, HPET_INFO, &info);
1249 c40ec5a9 ths
    if (r < 0)
1250 c40ec5a9 ths
        goto fail;
1251 c40ec5a9 ths
1252 c40ec5a9 ths
    /* Enable periodic mode */
1253 c40ec5a9 ths
    r = ioctl(fd, HPET_EPI, 0);
1254 c40ec5a9 ths
    if (info.hi_flags && (r < 0))
1255 c40ec5a9 ths
        goto fail;
1256 c40ec5a9 ths
1257 c40ec5a9 ths
    /* Enable interrupt */
1258 c40ec5a9 ths
    r = ioctl(fd, HPET_IE_ON, 0);
1259 c40ec5a9 ths
    if (r < 0)
1260 c40ec5a9 ths
        goto fail;
1261 c40ec5a9 ths
1262 c40ec5a9 ths
    enable_sigio_timer(fd);
1263 fcdc2129 pbrook
    t->priv = (void *)(long)fd;
1264 c40ec5a9 ths
1265 c40ec5a9 ths
    return 0;
1266 c40ec5a9 ths
fail:
1267 c40ec5a9 ths
    close(fd);
1268 c40ec5a9 ths
    return -1;
1269 c40ec5a9 ths
}
1270 c40ec5a9 ths
1271 c40ec5a9 ths
static void hpet_stop_timer(struct qemu_alarm_timer *t)
1272 c40ec5a9 ths
{
1273 fcdc2129 pbrook
    int fd = (long)t->priv;
1274 c40ec5a9 ths
1275 c40ec5a9 ths
    close(fd);
1276 c40ec5a9 ths
}
1277 c40ec5a9 ths
1278 c8994013 ths
static int rtc_start_timer(struct qemu_alarm_timer *t)
1279 fd872598 bellard
{
1280 c8994013 ths
    int rtc_fd;
1281 c8994013 ths
1282 aeb30be6 balrog
    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
1283 fd872598 bellard
    if (rtc_fd < 0)
1284 fd872598 bellard
        return -1;
1285 fd872598 bellard
    if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
1286 fd872598 bellard
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1287 fd872598 bellard
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1288 fd872598 bellard
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1289 fd872598 bellard
        goto fail;
1290 fd872598 bellard
    }
1291 fd872598 bellard
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1292 fd872598 bellard
    fail:
1293 fd872598 bellard
        close(rtc_fd);
1294 fd872598 bellard
        return -1;
1295 fd872598 bellard
    }
1296 c8994013 ths
1297 c8994013 ths
    enable_sigio_timer(rtc_fd);
1298 c8994013 ths
1299 fcdc2129 pbrook
    t->priv = (void *)(long)rtc_fd;
1300 c8994013 ths
1301 fd872598 bellard
    return 0;
1302 fd872598 bellard
}
1303 fd872598 bellard
1304 c8994013 ths
static void rtc_stop_timer(struct qemu_alarm_timer *t)
1305 829309c7 bellard
{
1306 fcdc2129 pbrook
    int rtc_fd = (long)t->priv;
1307 c8994013 ths
1308 c8994013 ths
    close(rtc_fd);
1309 829309c7 bellard
}
1310 829309c7 bellard
1311 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t)
1312 efe75411 ths
{
1313 efe75411 ths
    struct sigevent ev;
1314 efe75411 ths
    timer_t host_timer;
1315 efe75411 ths
    struct sigaction act;
1316 efe75411 ths
1317 efe75411 ths
    sigfillset(&act.sa_mask);
1318 efe75411 ths
    act.sa_flags = 0;
1319 efe75411 ths
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
1320 efe75411 ths
    act.sa_flags |= SA_ONSTACK;
1321 efe75411 ths
#endif
1322 efe75411 ths
    act.sa_handler = host_alarm_handler;
1323 efe75411 ths
1324 efe75411 ths
    sigaction(SIGALRM, &act, NULL);
1325 efe75411 ths
1326 efe75411 ths
    ev.sigev_value.sival_int = 0;
1327 efe75411 ths
    ev.sigev_notify = SIGEV_SIGNAL;
1328 efe75411 ths
    ev.sigev_signo = SIGALRM;
1329 efe75411 ths
1330 efe75411 ths
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1331 efe75411 ths
        perror("timer_create");
1332 efe75411 ths
1333 efe75411 ths
        /* disable dynticks */
1334 efe75411 ths
        fprintf(stderr, "Dynamic Ticks disabled\n");
1335 efe75411 ths
1336 efe75411 ths
        return -1;
1337 efe75411 ths
    }
1338 efe75411 ths
1339 efe75411 ths
    t->priv = (void *)host_timer;
1340 efe75411 ths
1341 efe75411 ths
    return 0;
1342 efe75411 ths
}
1343 efe75411 ths
1344 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1345 efe75411 ths
{
1346 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1347 efe75411 ths
1348 efe75411 ths
    timer_delete(host_timer);
1349 efe75411 ths
}
1350 efe75411 ths
1351 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1352 efe75411 ths
{
1353 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1354 efe75411 ths
    struct itimerspec timeout;
1355 efe75411 ths
    int64_t nearest_delta_us = INT64_MAX;
1356 efe75411 ths
    int64_t current_us;
1357 efe75411 ths
1358 efe75411 ths
    if (!active_timers[QEMU_TIMER_REALTIME] &&
1359 efe75411 ths
                !active_timers[QEMU_TIMER_VIRTUAL])
1360 efe75411 ths
            return;
1361 efe75411 ths
1362 efe75411 ths
    nearest_delta_us = qemu_next_deadline();
1363 efe75411 ths
1364 efe75411 ths
    /* check whether a timer is already running */
1365 efe75411 ths
    if (timer_gettime(host_timer, &timeout)) {
1366 efe75411 ths
        perror("gettime");
1367 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1368 efe75411 ths
        exit(1);
1369 efe75411 ths
    }
1370 efe75411 ths
    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1371 efe75411 ths
    if (current_us && current_us <= nearest_delta_us)
1372 efe75411 ths
        return;
1373 efe75411 ths
1374 efe75411 ths
    timeout.it_interval.tv_sec = 0;
1375 efe75411 ths
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1376 efe75411 ths
    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;
1377 efe75411 ths
    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1378 efe75411 ths
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1379 efe75411 ths
        perror("settime");
1380 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1381 efe75411 ths
        exit(1);
1382 efe75411 ths
    }
1383 efe75411 ths
}
1384 efe75411 ths
1385 70744b3a ths
#endif /* defined(__linux__) */
1386 231c6586 ths
1387 c8994013 ths
static int unix_start_timer(struct qemu_alarm_timer *t)
1388 c8994013 ths
{
1389 c8994013 ths
    struct sigaction act;
1390 c8994013 ths
    struct itimerval itv;
1391 c8994013 ths
    int err;
1392 c8994013 ths
1393 c8994013 ths
    /* timer signal */
1394 c8994013 ths
    sigfillset(&act.sa_mask);
1395 c8994013 ths
    act.sa_flags = 0;
1396 c8994013 ths
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
1397 c8994013 ths
    act.sa_flags |= SA_ONSTACK;
1398 c8994013 ths
#endif
1399 c8994013 ths
    act.sa_handler = host_alarm_handler;
1400 c8994013 ths
1401 c8994013 ths
    sigaction(SIGALRM, &act, NULL);
1402 c8994013 ths
1403 c8994013 ths
    itv.it_interval.tv_sec = 0;
1404 c8994013 ths
    /* for i386 kernel 2.6 to get 1 ms */
1405 c8994013 ths
    itv.it_interval.tv_usec = 999;
1406 c8994013 ths
    itv.it_value.tv_sec = 0;
1407 c8994013 ths
    itv.it_value.tv_usec = 10 * 1000;
1408 c8994013 ths
1409 c8994013 ths
    err = setitimer(ITIMER_REAL, &itv, NULL);
1410 c8994013 ths
    if (err)
1411 c8994013 ths
        return -1;
1412 c8994013 ths
1413 c8994013 ths
    return 0;
1414 c8994013 ths
}
1415 c8994013 ths
1416 c8994013 ths
static void unix_stop_timer(struct qemu_alarm_timer *t)
1417 c8994013 ths
{
1418 c8994013 ths
    struct itimerval itv;
1419 c8994013 ths
1420 c8994013 ths
    memset(&itv, 0, sizeof(itv));
1421 c8994013 ths
    setitimer(ITIMER_REAL, &itv, NULL);
1422 c8994013 ths
}
1423 c8994013 ths
1424 829309c7 bellard
#endif /* !defined(_WIN32) */
1425 fd872598 bellard
1426 c8994013 ths
#ifdef _WIN32
1427 c8994013 ths
1428 c8994013 ths
static int win32_start_timer(struct qemu_alarm_timer *t)
1429 c8994013 ths
{
1430 c8994013 ths
    TIMECAPS tc;
1431 c8994013 ths
    struct qemu_alarm_win32 *data = t->priv;
1432 efe75411 ths
    UINT flags;
1433 c8994013 ths
1434 c8994013 ths
    data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1435 c8994013 ths
    if (!data->host_alarm) {
1436 c8994013 ths
        perror("Failed CreateEvent");
1437 c396a7f0 ths
        return -1;
1438 c8994013 ths
    }
1439 c8994013 ths
1440 c8994013 ths
    memset(&tc, 0, sizeof(tc));
1441 c8994013 ths
    timeGetDevCaps(&tc, sizeof(tc));
1442 c8994013 ths
1443 c8994013 ths
    if (data->period < tc.wPeriodMin)
1444 c8994013 ths
        data->period = tc.wPeriodMin;
1445 c8994013 ths
1446 c8994013 ths
    timeBeginPeriod(data->period);
1447 c8994013 ths
1448 efe75411 ths
    flags = TIME_CALLBACK_FUNCTION;
1449 efe75411 ths
    if (alarm_has_dynticks(t))
1450 efe75411 ths
        flags |= TIME_ONESHOT;
1451 efe75411 ths
    else
1452 efe75411 ths
        flags |= TIME_PERIODIC;
1453 efe75411 ths
1454 c8994013 ths
    data->timerId = timeSetEvent(1,         // interval (ms)
1455 c8994013 ths
                        data->period,       // resolution
1456 c8994013 ths
                        host_alarm_handler, // function
1457 c8994013 ths
                        (DWORD)t,           // parameter
1458 efe75411 ths
                        flags);
1459 c8994013 ths
1460 c8994013 ths
    if (!data->timerId) {
1461 c8994013 ths
        perror("Failed to initialize win32 alarm timer");
1462 c8994013 ths
1463 c8994013 ths
        timeEndPeriod(data->period);
1464 c8994013 ths
        CloseHandle(data->host_alarm);
1465 c8994013 ths
        return -1;
1466 c8994013 ths
    }
1467 c8994013 ths
1468 c8994013 ths
    qemu_add_wait_object(data->host_alarm, NULL, NULL);
1469 c8994013 ths
1470 c8994013 ths
    return 0;
1471 c8994013 ths
}
1472 c8994013 ths
1473 c8994013 ths
static void win32_stop_timer(struct qemu_alarm_timer *t)
1474 c8994013 ths
{
1475 c8994013 ths
    struct qemu_alarm_win32 *data = t->priv;
1476 c8994013 ths
1477 c8994013 ths
    timeKillEvent(data->timerId);
1478 c8994013 ths
    timeEndPeriod(data->period);
1479 c8994013 ths
1480 c8994013 ths
    CloseHandle(data->host_alarm);
1481 c8994013 ths
}
1482 c8994013 ths
1483 efe75411 ths
static void win32_rearm_timer(struct qemu_alarm_timer *t)
1484 efe75411 ths
{
1485 efe75411 ths
    struct qemu_alarm_win32 *data = t->priv;
1486 efe75411 ths
    uint64_t nearest_delta_us;
1487 efe75411 ths
1488 efe75411 ths
    if (!active_timers[QEMU_TIMER_REALTIME] &&
1489 efe75411 ths
                !active_timers[QEMU_TIMER_VIRTUAL])
1490 efe75411 ths
            return;
1491 efe75411 ths
1492 efe75411 ths
    nearest_delta_us = qemu_next_deadline();
1493 efe75411 ths
    nearest_delta_us /= 1000;
1494 efe75411 ths
1495 efe75411 ths
    timeKillEvent(data->timerId);
1496 efe75411 ths
1497 efe75411 ths
    data->timerId = timeSetEvent(1,
1498 efe75411 ths
                        data->period,
1499 efe75411 ths
                        host_alarm_handler,
1500 efe75411 ths
                        (DWORD)t,
1501 efe75411 ths
                        TIME_ONESHOT | TIME_PERIODIC);
1502 efe75411 ths
1503 efe75411 ths
    if (!data->timerId) {
1504 efe75411 ths
        perror("Failed to re-arm win32 alarm timer");
1505 efe75411 ths
1506 efe75411 ths
        timeEndPeriod(data->period);
1507 efe75411 ths
        CloseHandle(data->host_alarm);
1508 efe75411 ths
        exit(1);
1509 efe75411 ths
    }
1510 efe75411 ths
}
1511 efe75411 ths
1512 c8994013 ths
#endif /* _WIN32 */
1513 c8994013 ths
1514 1dce7c3c bellard
static void init_timer_alarm(void)
1515 8a7ddc38 bellard
{
1516 c8994013 ths
    struct qemu_alarm_timer *t;
1517 c8994013 ths
    int i, err = -1;
1518 c8994013 ths
1519 c8994013 ths
    for (i = 0; alarm_timers[i].name; i++) {
1520 c8994013 ths
        t = &alarm_timers[i];
1521 c8994013 ths
1522 c8994013 ths
        err = t->start(t);
1523 c8994013 ths
        if (!err)
1524 c8994013 ths
            break;
1525 67b915a5 bellard
    }
1526 fd872598 bellard
1527 c8994013 ths
    if (err) {
1528 c8994013 ths
        fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1529 c8994013 ths
        fprintf(stderr, "Terminating\n");
1530 c8994013 ths
        exit(1);
1531 67b915a5 bellard
    }
1532 c8994013 ths
1533 c8994013 ths
    alarm_timer = t;
1534 8a7ddc38 bellard
}
1535 8a7ddc38 bellard
1536 40c3bac3 bellard
void quit_timers(void)
1537 40c3bac3 bellard
{
1538 c8994013 ths
    alarm_timer->stop(alarm_timer);
1539 c8994013 ths
    alarm_timer = NULL;
1540 40c3bac3 bellard
}
1541 40c3bac3 bellard
1542 c4b1fcc0 bellard
/***********************************************************/
1543 82c643ff bellard
/* character device */
1544 313aa567 bellard
1545 e5b0bc44 pbrook
static void qemu_chr_event(CharDriverState *s, int event)
1546 e5b0bc44 pbrook
{
1547 e5b0bc44 pbrook
    if (!s->chr_event)
1548 e5b0bc44 pbrook
        return;
1549 e5b0bc44 pbrook
    s->chr_event(s->handler_opaque, event);
1550 e5b0bc44 pbrook
}
1551 e5b0bc44 pbrook
1552 86e94dea ths
static void qemu_chr_reset_bh(void *opaque)
1553 86e94dea ths
{
1554 86e94dea ths
    CharDriverState *s = opaque;
1555 e5b0bc44 pbrook
    qemu_chr_event(s, CHR_EVENT_RESET);
1556 86e94dea ths
    qemu_bh_delete(s->bh);
1557 86e94dea ths
    s->bh = NULL;
1558 86e94dea ths
}
1559 86e94dea ths
1560 86e94dea ths
void qemu_chr_reset(CharDriverState *s)
1561 86e94dea ths
{
1562 86e94dea ths
    if (s->bh == NULL) {
1563 86e94dea ths
        s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1564 86e94dea ths
        qemu_bh_schedule(s->bh);
1565 86e94dea ths
    }
1566 86e94dea ths
}
1567 86e94dea ths
1568 82c643ff bellard
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
1569 82c643ff bellard
{
1570 82c643ff bellard
    return s->chr_write(s, buf, len);
1571 82c643ff bellard
}
1572 67b915a5 bellard
1573 e57a8c0e bellard
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
1574 f8d179e3 bellard
{
1575 e57a8c0e bellard
    if (!s->chr_ioctl)
1576 e57a8c0e bellard
        return -ENOTSUP;
1577 e57a8c0e bellard
    return s->chr_ioctl(s, cmd, arg);
1578 f8d179e3 bellard
}
1579 f8d179e3 bellard
1580 e5b0bc44 pbrook
int qemu_chr_can_read(CharDriverState *s)
1581 e5b0bc44 pbrook
{
1582 e5b0bc44 pbrook
    if (!s->chr_can_read)
1583 e5b0bc44 pbrook
        return 0;
1584 e5b0bc44 pbrook
    return s->chr_can_read(s->handler_opaque);
1585 e5b0bc44 pbrook
}
1586 e5b0bc44 pbrook
1587 e5b0bc44 pbrook
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1588 e5b0bc44 pbrook
{
1589 e5b0bc44 pbrook
    s->chr_read(s->handler_opaque, buf, len);
1590 e5b0bc44 pbrook
}
1591 e5b0bc44 pbrook
1592 e5b0bc44 pbrook
1593 82c643ff bellard
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1594 67b915a5 bellard
{
1595 82c643ff bellard
    char buf[4096];
1596 82c643ff bellard
    va_list ap;
1597 82c643ff bellard
    va_start(ap, fmt);
1598 82c643ff bellard
    vsnprintf(buf, sizeof(buf), fmt, ap);
1599 82c643ff bellard
    qemu_chr_write(s, buf, strlen(buf));
1600 82c643ff bellard
    va_end(ap);
1601 67b915a5 bellard
}
1602 67b915a5 bellard
1603 5905b2e5 bellard
void qemu_chr_send_event(CharDriverState *s, int event)
1604 5905b2e5 bellard
{
1605 5905b2e5 bellard
    if (s->chr_send_event)
1606 5905b2e5 bellard
        s->chr_send_event(s, event);
1607 5905b2e5 bellard
}
1608 5905b2e5 bellard
1609 5fafdf24 ths
void qemu_chr_add_handlers(CharDriverState *s,
1610 5fafdf24 ths
                           IOCanRWHandler *fd_can_read,
1611 e5b0bc44 pbrook
                           IOReadHandler *fd_read,
1612 e5b0bc44 pbrook
                           IOEventHandler *fd_event,
1613 e5b0bc44 pbrook
                           void *opaque)
1614 82c643ff bellard
{
1615 e5b0bc44 pbrook
    s->chr_can_read = fd_can_read;
1616 e5b0bc44 pbrook
    s->chr_read = fd_read;
1617 e5b0bc44 pbrook
    s->chr_event = fd_event;
1618 e5b0bc44 pbrook
    s->handler_opaque = opaque;
1619 e5b0bc44 pbrook
    if (s->chr_update_read_handler)
1620 e5b0bc44 pbrook
        s->chr_update_read_handler(s);
1621 82c643ff bellard
}
1622 3b46e624 ths
1623 82c643ff bellard
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1624 313aa567 bellard
{
1625 82c643ff bellard
    return len;
1626 82c643ff bellard
}
1627 82c643ff bellard
1628 52f61fde ths
static CharDriverState *qemu_chr_open_null(void)
1629 82c643ff bellard
{
1630 82c643ff bellard
    CharDriverState *chr;
1631 82c643ff bellard
1632 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1633 82c643ff bellard
    if (!chr)
1634 82c643ff bellard
        return NULL;
1635 82c643ff bellard
    chr->chr_write = null_chr_write;
1636 82c643ff bellard
    return chr;
1637 82c643ff bellard
}
1638 82c643ff bellard
1639 20d8a3ed ths
/* MUX driver for serial I/O splitting */
1640 20d8a3ed ths
static int term_timestamps;
1641 20d8a3ed ths
static int64_t term_timestamps_start;
1642 9c1de612 ths
#define MAX_MUX 4
1643 20d8a3ed ths
typedef struct {
1644 20d8a3ed ths
    IOCanRWHandler *chr_can_read[MAX_MUX];
1645 20d8a3ed ths
    IOReadHandler *chr_read[MAX_MUX];
1646 20d8a3ed ths
    IOEventHandler *chr_event[MAX_MUX];
1647 20d8a3ed ths
    void *ext_opaque[MAX_MUX];
1648 20d8a3ed ths
    CharDriverState *drv;
1649 20d8a3ed ths
    int mux_cnt;
1650 20d8a3ed ths
    int term_got_escape;
1651 20d8a3ed ths
    int max_size;
1652 20d8a3ed ths
} MuxDriver;
1653 20d8a3ed ths
1654 20d8a3ed ths
1655 20d8a3ed ths
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1656 20d8a3ed ths
{
1657 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1658 20d8a3ed ths
    int ret;
1659 20d8a3ed ths
    if (!term_timestamps) {
1660 20d8a3ed ths
        ret = d->drv->chr_write(d->drv, buf, len);
1661 20d8a3ed ths
    } else {
1662 20d8a3ed ths
        int i;
1663 20d8a3ed ths
1664 20d8a3ed ths
        ret = 0;
1665 20d8a3ed ths
        for(i = 0; i < len; i++) {
1666 20d8a3ed ths
            ret += d->drv->chr_write(d->drv, buf+i, 1);
1667 20d8a3ed ths
            if (buf[i] == '\n') {
1668 20d8a3ed ths
                char buf1[64];
1669 20d8a3ed ths
                int64_t ti;
1670 20d8a3ed ths
                int secs;
1671 20d8a3ed ths
1672 20d8a3ed ths
                ti = get_clock();
1673 20d8a3ed ths
                if (term_timestamps_start == -1)
1674 20d8a3ed ths
                    term_timestamps_start = ti;
1675 20d8a3ed ths
                ti -= term_timestamps_start;
1676 20d8a3ed ths
                secs = ti / 1000000000;
1677 20d8a3ed ths
                snprintf(buf1, sizeof(buf1),
1678 20d8a3ed ths
                         "[%02d:%02d:%02d.%03d] ",
1679 20d8a3ed ths
                         secs / 3600,
1680 20d8a3ed ths
                         (secs / 60) % 60,
1681 20d8a3ed ths
                         secs % 60,
1682 20d8a3ed ths
                         (int)((ti / 1000000) % 1000));
1683 20d8a3ed ths
                d->drv->chr_write(d->drv, buf1, strlen(buf1));
1684 20d8a3ed ths
            }
1685 20d8a3ed ths
        }
1686 20d8a3ed ths
    }
1687 20d8a3ed ths
    return ret;
1688 20d8a3ed ths
}
1689 20d8a3ed ths
1690 20d8a3ed ths
static char *mux_help[] = {
1691 20d8a3ed ths
    "% h    print this help\n\r",
1692 20d8a3ed ths
    "% x    exit emulator\n\r",
1693 20d8a3ed ths
    "% s    save disk data back to file (if -snapshot)\n\r",
1694 20d8a3ed ths
    "% t    toggle console timestamps\n\r"
1695 20d8a3ed ths
    "% b    send break (magic sysrq)\n\r",
1696 20d8a3ed ths
    "% c    switch between console and monitor\n\r",
1697 20d8a3ed ths
    "% %  sends %\n\r",
1698 20d8a3ed ths
    NULL
1699 20d8a3ed ths
};
1700 20d8a3ed ths
1701 20d8a3ed ths
static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1702 20d8a3ed ths
static void mux_print_help(CharDriverState *chr)
1703 20d8a3ed ths
{
1704 20d8a3ed ths
    int i, j;
1705 20d8a3ed ths
    char ebuf[15] = "Escape-Char";
1706 20d8a3ed ths
    char cbuf[50] = "\n\r";
1707 20d8a3ed ths
1708 20d8a3ed ths
    if (term_escape_char > 0 && term_escape_char < 26) {
1709 20d8a3ed ths
        sprintf(cbuf,"\n\r");
1710 20d8a3ed ths
        sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
1711 20d8a3ed ths
    } else {
1712 20d8a3ed ths
        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char);
1713 20d8a3ed ths
    }
1714 20d8a3ed ths
    chr->chr_write(chr, cbuf, strlen(cbuf));
1715 20d8a3ed ths
    for (i = 0; mux_help[i] != NULL; i++) {
1716 20d8a3ed ths
        for (j=0; mux_help[i][j] != '\0'; j++) {
1717 20d8a3ed ths
            if (mux_help[i][j] == '%')
1718 20d8a3ed ths
                chr->chr_write(chr, ebuf, strlen(ebuf));
1719 20d8a3ed ths
            else
1720 20d8a3ed ths
                chr->chr_write(chr, &mux_help[i][j], 1);
1721 20d8a3ed ths
        }
1722 20d8a3ed ths
    }
1723 20d8a3ed ths
}
1724 20d8a3ed ths
1725 20d8a3ed ths
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1726 20d8a3ed ths
{
1727 20d8a3ed ths
    if (d->term_got_escape) {
1728 20d8a3ed ths
        d->term_got_escape = 0;
1729 20d8a3ed ths
        if (ch == term_escape_char)
1730 20d8a3ed ths
            goto send_char;
1731 20d8a3ed ths
        switch(ch) {
1732 20d8a3ed ths
        case '?':
1733 20d8a3ed ths
        case 'h':
1734 20d8a3ed ths
            mux_print_help(chr);
1735 20d8a3ed ths
            break;
1736 20d8a3ed ths
        case 'x':
1737 20d8a3ed ths
            {
1738 20d8a3ed ths
                 char *term =  "QEMU: Terminated\n\r";
1739 20d8a3ed ths
                 chr->chr_write(chr,term,strlen(term));
1740 20d8a3ed ths
                 exit(0);
1741 20d8a3ed ths
                 break;
1742 20d8a3ed ths
            }
1743 20d8a3ed ths
        case 's':
1744 20d8a3ed ths
            {
1745 20d8a3ed ths
                int i;
1746 20d8a3ed ths
                for (i = 0; i < MAX_DISKS; i++) {
1747 20d8a3ed ths
                    if (bs_table[i])
1748 20d8a3ed ths
                        bdrv_commit(bs_table[i]);
1749 20d8a3ed ths
                }
1750 2dc7b602 balrog
                if (mtd_bdrv)
1751 2dc7b602 balrog
                    bdrv_commit(mtd_bdrv);
1752 20d8a3ed ths
            }
1753 20d8a3ed ths
            break;
1754 20d8a3ed ths
        case 'b':
1755 36ddb83b balrog
            qemu_chr_event(chr, CHR_EVENT_BREAK);
1756 20d8a3ed ths
            break;
1757 20d8a3ed ths
        case 'c':
1758 20d8a3ed ths
            /* Switch to the next registered device */
1759 20d8a3ed ths
            chr->focus++;
1760 20d8a3ed ths
            if (chr->focus >= d->mux_cnt)
1761 20d8a3ed ths
                chr->focus = 0;
1762 20d8a3ed ths
            break;
1763 20d8a3ed ths
       case 't':
1764 20d8a3ed ths
           term_timestamps = !term_timestamps;
1765 20d8a3ed ths
           term_timestamps_start = -1;
1766 20d8a3ed ths
           break;
1767 20d8a3ed ths
        }
1768 20d8a3ed ths
    } else if (ch == term_escape_char) {
1769 20d8a3ed ths
        d->term_got_escape = 1;
1770 20d8a3ed ths
    } else {
1771 20d8a3ed ths
    send_char:
1772 20d8a3ed ths
        return 1;
1773 20d8a3ed ths
    }
1774 20d8a3ed ths
    return 0;
1775 20d8a3ed ths
}
1776 20d8a3ed ths
1777 20d8a3ed ths
static int mux_chr_can_read(void *opaque)
1778 20d8a3ed ths
{
1779 20d8a3ed ths
    CharDriverState *chr = opaque;
1780 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1781 20d8a3ed ths
    if (d->chr_can_read[chr->focus])
1782 20d8a3ed ths
       return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
1783 20d8a3ed ths
    return 0;
1784 20d8a3ed ths
}
1785 20d8a3ed ths
1786 20d8a3ed ths
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1787 20d8a3ed ths
{
1788 20d8a3ed ths
    CharDriverState *chr = opaque;
1789 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1790 20d8a3ed ths
    int i;
1791 20d8a3ed ths
    for(i = 0; i < size; i++)
1792 20d8a3ed ths
        if (mux_proc_byte(chr, d, buf[i]))
1793 20d8a3ed ths
            d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
1794 20d8a3ed ths
}
1795 20d8a3ed ths
1796 20d8a3ed ths
static void mux_chr_event(void *opaque, int event)
1797 20d8a3ed ths
{
1798 20d8a3ed ths
    CharDriverState *chr = opaque;
1799 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1800 20d8a3ed ths
    int i;
1801 20d8a3ed ths
1802 20d8a3ed ths
    /* Send the event to all registered listeners */
1803 20d8a3ed ths
    for (i = 0; i < d->mux_cnt; i++)
1804 20d8a3ed ths
        if (d->chr_event[i])
1805 20d8a3ed ths
            d->chr_event[i](d->ext_opaque[i], event);
1806 20d8a3ed ths
}
1807 20d8a3ed ths
1808 20d8a3ed ths
static void mux_chr_update_read_handler(CharDriverState *chr)
1809 20d8a3ed ths
{
1810 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1811 20d8a3ed ths
1812 20d8a3ed ths
    if (d->mux_cnt >= MAX_MUX) {
1813 20d8a3ed ths
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
1814 20d8a3ed ths
        return;
1815 20d8a3ed ths
    }
1816 20d8a3ed ths
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
1817 20d8a3ed ths
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
1818 20d8a3ed ths
    d->chr_read[d->mux_cnt] = chr->chr_read;
1819 20d8a3ed ths
    d->chr_event[d->mux_cnt] = chr->chr_event;
1820 20d8a3ed ths
    /* Fix up the real driver with mux routines */
1821 20d8a3ed ths
    if (d->mux_cnt == 0) {
1822 20d8a3ed ths
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
1823 20d8a3ed ths
                              mux_chr_event, chr);
1824 20d8a3ed ths
    }
1825 20d8a3ed ths
    chr->focus = d->mux_cnt;
1826 20d8a3ed ths
    d->mux_cnt++;
1827 20d8a3ed ths
}
1828 20d8a3ed ths
1829 20d8a3ed ths
CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
1830 20d8a3ed ths
{
1831 20d8a3ed ths
    CharDriverState *chr;
1832 20d8a3ed ths
    MuxDriver *d;
1833 20d8a3ed ths
1834 20d8a3ed ths
    chr = qemu_mallocz(sizeof(CharDriverState));
1835 20d8a3ed ths
    if (!chr)
1836 20d8a3ed ths
        return NULL;
1837 20d8a3ed ths
    d = qemu_mallocz(sizeof(MuxDriver));
1838 20d8a3ed ths
    if (!d) {
1839 20d8a3ed ths
        free(chr);
1840 20d8a3ed ths
        return NULL;
1841 20d8a3ed ths
    }
1842 20d8a3ed ths
1843 20d8a3ed ths
    chr->opaque = d;
1844 20d8a3ed ths
    d->drv = drv;
1845 20d8a3ed ths
    chr->focus = -1;
1846 20d8a3ed ths
    chr->chr_write = mux_chr_write;
1847 20d8a3ed ths
    chr->chr_update_read_handler = mux_chr_update_read_handler;
1848 20d8a3ed ths
    return chr;
1849 20d8a3ed ths
}
1850 20d8a3ed ths
1851 20d8a3ed ths
1852 fd1dff4b bellard
#ifdef _WIN32
1853 82c643ff bellard
1854 fd1dff4b bellard
static void socket_cleanup(void)
1855 fd1dff4b bellard
{
1856 fd1dff4b bellard
    WSACleanup();
1857 fd1dff4b bellard
}
1858 82c643ff bellard
1859 fd1dff4b bellard
static int socket_init(void)
1860 fd1dff4b bellard
{
1861 fd1dff4b bellard
    WSADATA Data;
1862 fd1dff4b bellard
    int ret, err;
1863 fd1dff4b bellard
1864 fd1dff4b bellard
    ret = WSAStartup(MAKEWORD(2,2), &Data);
1865 fd1dff4b bellard
    if (ret != 0) {
1866 fd1dff4b bellard
        err = WSAGetLastError();
1867 fd1dff4b bellard
        fprintf(stderr, "WSAStartup: %d\n", err);
1868 fd1dff4b bellard
        return -1;
1869 fd1dff4b bellard
    }
1870 fd1dff4b bellard
    atexit(socket_cleanup);
1871 fd1dff4b bellard
    return 0;
1872 fd1dff4b bellard
}
1873 fd1dff4b bellard
1874 fd1dff4b bellard
static int send_all(int fd, const uint8_t *buf, int len1)
1875 fd1dff4b bellard
{
1876 fd1dff4b bellard
    int ret, len;
1877 3b46e624 ths
1878 fd1dff4b bellard
    len = len1;
1879 fd1dff4b bellard
    while (len > 0) {
1880 fd1dff4b bellard
        ret = send(fd, buf, len, 0);
1881 fd1dff4b bellard
        if (ret < 0) {
1882 fd1dff4b bellard
            int errno;
1883 fd1dff4b bellard
            errno = WSAGetLastError();
1884 fd1dff4b bellard
            if (errno != WSAEWOULDBLOCK) {
1885 fd1dff4b bellard
                return -1;
1886 fd1dff4b bellard
            }
1887 fd1dff4b bellard
        } else if (ret == 0) {
1888 fd1dff4b bellard
            break;
1889 fd1dff4b bellard
        } else {
1890 fd1dff4b bellard
            buf += ret;
1891 fd1dff4b bellard
            len -= ret;
1892 fd1dff4b bellard
        }
1893 fd1dff4b bellard
    }
1894 fd1dff4b bellard
    return len1 - len;
1895 fd1dff4b bellard
}
1896 fd1dff4b bellard
1897 fd1dff4b bellard
void socket_set_nonblock(int fd)
1898 fd1dff4b bellard
{
1899 fd1dff4b bellard
    unsigned long opt = 1;
1900 fd1dff4b bellard
    ioctlsocket(fd, FIONBIO, &opt);
1901 fd1dff4b bellard
}
1902 fd1dff4b bellard
1903 fd1dff4b bellard
#else
1904 fd1dff4b bellard
1905 1d96905d bellard
static int unix_write(int fd, const uint8_t *buf, int len1)
1906 1d96905d bellard
{
1907 1d96905d bellard
    int ret, len;
1908 1d96905d bellard
1909 1d96905d bellard
    len = len1;
1910 1d96905d bellard
    while (len > 0) {
1911 1d96905d bellard
        ret = write(fd, buf, len);
1912 1d96905d bellard
        if (ret < 0) {
1913 1d96905d bellard
            if (errno != EINTR && errno != EAGAIN)
1914 1d96905d bellard
                return -1;
1915 1d96905d bellard
        } else if (ret == 0) {
1916 1d96905d bellard
            break;
1917 1d96905d bellard
        } else {
1918 1d96905d bellard
            buf += ret;
1919 1d96905d bellard
            len -= ret;
1920 1d96905d bellard
        }
1921 1d96905d bellard
    }
1922 1d96905d bellard
    return len1 - len;
1923 1d96905d bellard
}
1924 1d96905d bellard
1925 fd1dff4b bellard
static inline int send_all(int fd, const uint8_t *buf, int len1)
1926 fd1dff4b bellard
{
1927 fd1dff4b bellard
    return unix_write(fd, buf, len1);
1928 fd1dff4b bellard
}
1929 fd1dff4b bellard
1930 fd1dff4b bellard
void socket_set_nonblock(int fd)
1931 fd1dff4b bellard
{
1932 fd1dff4b bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1933 fd1dff4b bellard
}
1934 fd1dff4b bellard
#endif /* !_WIN32 */
1935 fd1dff4b bellard
1936 fd1dff4b bellard
#ifndef _WIN32
1937 fd1dff4b bellard
1938 fd1dff4b bellard
typedef struct {
1939 fd1dff4b bellard
    int fd_in, fd_out;
1940 fd1dff4b bellard
    int max_size;
1941 fd1dff4b bellard
} FDCharDriver;
1942 fd1dff4b bellard
1943 20d8a3ed ths
#define STDIO_MAX_CLIENTS 1
1944 20d8a3ed ths
static int stdio_nb_clients = 0;
1945 fd1dff4b bellard
1946 82c643ff bellard
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1947 82c643ff bellard
{
1948 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1949 1d96905d bellard
    return unix_write(s->fd_out, buf, len);
1950 82c643ff bellard
}
1951 82c643ff bellard
1952 7c9d8e07 bellard
static int fd_chr_read_poll(void *opaque)
1953 7c9d8e07 bellard
{
1954 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1955 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1956 7c9d8e07 bellard
1957 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
1958 7c9d8e07 bellard
    return s->max_size;
1959 7c9d8e07 bellard
}
1960 7c9d8e07 bellard
1961 7c9d8e07 bellard
static void fd_chr_read(void *opaque)
1962 7c9d8e07 bellard
{
1963 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1964 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1965 7c9d8e07 bellard
    int size, len;
1966 7c9d8e07 bellard
    uint8_t buf[1024];
1967 3b46e624 ths
1968 7c9d8e07 bellard
    len = sizeof(buf);
1969 7c9d8e07 bellard
    if (len > s->max_size)
1970 7c9d8e07 bellard
        len = s->max_size;
1971 7c9d8e07 bellard
    if (len == 0)
1972 7c9d8e07 bellard
        return;
1973 7c9d8e07 bellard
    size = read(s->fd_in, buf, len);
1974 188157fe pbrook
    if (size == 0) {
1975 188157fe pbrook
        /* FD has been closed. Remove it from the active list.  */
1976 188157fe pbrook
        qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
1977 188157fe pbrook
        return;
1978 188157fe pbrook
    }
1979 7c9d8e07 bellard
    if (size > 0) {
1980 e5b0bc44 pbrook
        qemu_chr_read(chr, buf, size);
1981 7c9d8e07 bellard
    }
1982 7c9d8e07 bellard
}
1983 7c9d8e07 bellard
1984 e5b0bc44 pbrook
static void fd_chr_update_read_handler(CharDriverState *chr)
1985 82c643ff bellard
{
1986 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1987 82c643ff bellard
1988 f8d179e3 bellard
    if (s->fd_in >= 0) {
1989 f8d179e3 bellard
        if (nographic && s->fd_in == 0) {
1990 f8d179e3 bellard
        } else {
1991 5fafdf24 ths
            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
1992 7c9d8e07 bellard
                                 fd_chr_read, NULL, chr);
1993 f8d179e3 bellard
        }
1994 82c643ff bellard
    }
1995 82c643ff bellard
}
1996 82c643ff bellard
1997 82c643ff bellard
/* open a character device to a unix fd */
1998 52f61fde ths
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
1999 82c643ff bellard
{
2000 82c643ff bellard
    CharDriverState *chr;
2001 82c643ff bellard
    FDCharDriver *s;
2002 82c643ff bellard
2003 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2004 82c643ff bellard
    if (!chr)
2005 82c643ff bellard
        return NULL;
2006 82c643ff bellard
    s = qemu_mallocz(sizeof(FDCharDriver));
2007 82c643ff bellard
    if (!s) {
2008 82c643ff bellard
        free(chr);
2009 82c643ff bellard
        return NULL;
2010 82c643ff bellard
    }
2011 82c643ff bellard
    s->fd_in = fd_in;
2012 82c643ff bellard
    s->fd_out = fd_out;
2013 82c643ff bellard
    chr->opaque = s;
2014 82c643ff bellard
    chr->chr_write = fd_chr_write;
2015 e5b0bc44 pbrook
    chr->chr_update_read_handler = fd_chr_update_read_handler;
2016 86e94dea ths
2017 86e94dea ths
    qemu_chr_reset(chr);
2018 86e94dea ths
2019 82c643ff bellard
    return chr;
2020 82c643ff bellard
}
2021 82c643ff bellard
2022 52f61fde ths
static CharDriverState *qemu_chr_open_file_out(const char *file_out)
2023 f8d179e3 bellard
{
2024 f8d179e3 bellard
    int fd_out;
2025 f8d179e3 bellard
2026 aeb30be6 balrog
    TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
2027 f8d179e3 bellard
    if (fd_out < 0)
2028 f8d179e3 bellard
        return NULL;
2029 f8d179e3 bellard
    return qemu_chr_open_fd(-1, fd_out);
2030 f8d179e3 bellard
}
2031 f8d179e3 bellard
2032 52f61fde ths
static CharDriverState *qemu_chr_open_pipe(const char *filename)
2033 f8d179e3 bellard
{
2034 c26c1c4b ths
    int fd_in, fd_out;
2035 c26c1c4b ths
    char filename_in[256], filename_out[256];
2036 c26c1c4b ths
2037 c26c1c4b ths
    snprintf(filename_in, 256, "%s.in", filename);
2038 c26c1c4b ths
    snprintf(filename_out, 256, "%s.out", filename);
2039 aeb30be6 balrog
    TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2040 aeb30be6 balrog
    TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
2041 c26c1c4b ths
    if (fd_in < 0 || fd_out < 0) {
2042 c26c1c4b ths
        if (fd_in >= 0)
2043 c26c1c4b ths
            close(fd_in);
2044 c26c1c4b ths
        if (fd_out >= 0)
2045 c26c1c4b ths
            close(fd_out);
2046 aeb30be6 balrog
        TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
2047 c26c1c4b ths
        if (fd_in < 0)
2048 c26c1c4b ths
            return NULL;
2049 c26c1c4b ths
    }
2050 c26c1c4b ths
    return qemu_chr_open_fd(fd_in, fd_out);
2051 f8d179e3 bellard
}
2052 f8d179e3 bellard
2053 f8d179e3 bellard
2054 82c643ff bellard
/* for STDIO, we handle the case where several clients use it
2055 82c643ff bellard
   (nographic mode) */
2056 82c643ff bellard
2057 aa0bc6b6 bellard
#define TERM_FIFO_MAX_SIZE 1
2058 aa0bc6b6 bellard
2059 aa0bc6b6 bellard
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
2060 1dce7c3c bellard
static int term_fifo_size;
2061 330d0414 bellard
2062 7c9d8e07 bellard
static int stdio_read_poll(void *opaque)
2063 82c643ff bellard
{
2064 20d8a3ed ths
    CharDriverState *chr = opaque;
2065 aa0bc6b6 bellard
2066 20d8a3ed ths
    /* try to flush the queue if needed */
2067 20d8a3ed ths
    if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2068 20d8a3ed ths
        qemu_chr_read(chr, term_fifo, 1);
2069 20d8a3ed ths
        term_fifo_size = 0;
2070 aa0bc6b6 bellard
    }
2071 20d8a3ed ths
    /* see if we can absorb more chars */
2072 20d8a3ed ths
    if (term_fifo_size == 0)
2073 20d8a3ed ths
        return 1;
2074 20d8a3ed ths
    else
2075 20d8a3ed ths
        return 0;
2076 82c643ff bellard
}
2077 82c643ff bellard
2078 7c9d8e07 bellard
static void stdio_read(void *opaque)
2079 82c643ff bellard
{
2080 7c9d8e07 bellard
    int size;
2081 7c9d8e07 bellard
    uint8_t buf[1];
2082 20d8a3ed ths
    CharDriverState *chr = opaque;
2083 20d8a3ed ths
2084 7c9d8e07 bellard
    size = read(0, buf, 1);
2085 519945df pbrook
    if (size == 0) {
2086 519945df pbrook
        /* stdin has been closed. Remove it from the active list.  */
2087 519945df pbrook
        qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2088 519945df pbrook
        return;
2089 519945df pbrook
    }
2090 20d8a3ed ths
    if (size > 0) {
2091 20d8a3ed ths
        if (qemu_chr_can_read(chr) > 0) {
2092 20d8a3ed ths
            qemu_chr_read(chr, buf, 1);
2093 20d8a3ed ths
        } else if (term_fifo_size == 0) {
2094 20d8a3ed ths
            term_fifo[term_fifo_size++] = buf[0];
2095 1dce7c3c bellard
        }
2096 1dce7c3c bellard
    }
2097 1dce7c3c bellard
}
2098 1dce7c3c bellard
2099 8d11df9e bellard
/* init terminal so that we can grab keys */
2100 8d11df9e bellard
static struct termios oldtty;
2101 8d11df9e bellard
static int old_fd0_flags;
2102 8d11df9e bellard
2103 8d11df9e bellard
static void term_exit(void)
2104 8d11df9e bellard
{
2105 8d11df9e bellard
    tcsetattr (0, TCSANOW, &oldtty);
2106 8d11df9e bellard
    fcntl(0, F_SETFL, old_fd0_flags);
2107 8d11df9e bellard
}
2108 8d11df9e bellard
2109 8d11df9e bellard
static void term_init(void)
2110 8d11df9e bellard
{
2111 8d11df9e bellard
    struct termios tty;
2112 8d11df9e bellard
2113 8d11df9e bellard
    tcgetattr (0, &tty);
2114 8d11df9e bellard
    oldtty = tty;
2115 8d11df9e bellard
    old_fd0_flags = fcntl(0, F_GETFL);
2116 8d11df9e bellard
2117 8d11df9e bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2118 8d11df9e bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2119 8d11df9e bellard
    tty.c_oflag |= OPOST;
2120 8d11df9e bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2121 8d11df9e bellard
    /* if graphical mode, we allow Ctrl-C handling */
2122 8d11df9e bellard
    if (nographic)
2123 8d11df9e bellard
        tty.c_lflag &= ~ISIG;
2124 8d11df9e bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
2125 8d11df9e bellard
    tty.c_cflag |= CS8;
2126 8d11df9e bellard
    tty.c_cc[VMIN] = 1;
2127 8d11df9e bellard
    tty.c_cc[VTIME] = 0;
2128 3b46e624 ths
2129 8d11df9e bellard
    tcsetattr (0, TCSANOW, &tty);
2130 8d11df9e bellard
2131 8d11df9e bellard
    atexit(term_exit);
2132 8d11df9e bellard
2133 8d11df9e bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
2134 8d11df9e bellard
}
2135 8d11df9e bellard
2136 52f61fde ths
static CharDriverState *qemu_chr_open_stdio(void)
2137 82c643ff bellard
{
2138 82c643ff bellard
    CharDriverState *chr;
2139 82c643ff bellard
2140 20d8a3ed ths
    if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2141 20d8a3ed ths
        return NULL;
2142 20d8a3ed ths
    chr = qemu_chr_open_fd(0, 1);
2143 20d8a3ed ths
    qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2144 20d8a3ed ths
    stdio_nb_clients++;
2145 20d8a3ed ths
    term_init();
2146 20d8a3ed ths
2147 82c643ff bellard
    return chr;
2148 82c643ff bellard
}
2149 82c643ff bellard
2150 aec62507 ths
#if defined(__linux__) || defined(__sun__)
2151 52f61fde ths
static CharDriverState *qemu_chr_open_pty(void)
2152 82c643ff bellard
{
2153 91fc2119 bellard
    struct termios tty;
2154 82c643ff bellard
    char slave_name[1024];
2155 82c643ff bellard
    int master_fd, slave_fd;
2156 3b46e624 ths
2157 aec62507 ths
#if defined(__linux__)
2158 82c643ff bellard
    /* Not satisfying */
2159 82c643ff bellard
    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
2160 82c643ff bellard
        return NULL;
2161 82c643ff bellard
    }
2162 aec62507 ths
#endif
2163 3b46e624 ths
2164 91fc2119 bellard
    /* Disabling local echo and line-buffered output */
2165 91fc2119 bellard
    tcgetattr (master_fd, &tty);
2166 91fc2119 bellard
    tty.c_lflag &= ~(ECHO|ICANON|ISIG);
2167 91fc2119 bellard
    tty.c_cc[VMIN] = 1;
2168 91fc2119 bellard
    tty.c_cc[VTIME] = 0;
2169 91fc2119 bellard
    tcsetattr (master_fd, TCSAFLUSH, &tty);
2170 91fc2119 bellard
2171 82c643ff bellard
    fprintf(stderr, "char device redirected to %s\n", slave_name);
2172 82c643ff bellard
    return qemu_chr_open_fd(master_fd, master_fd);
2173 82c643ff bellard
}
2174 f8d179e3 bellard
2175 5fafdf24 ths
static void tty_serial_init(int fd, int speed,
2176 f8d179e3 bellard
                            int parity, int data_bits, int stop_bits)
2177 f8d179e3 bellard
{
2178 f8d179e3 bellard
    struct termios tty;
2179 f8d179e3 bellard
    speed_t spd;
2180 f8d179e3 bellard
2181 e57a8c0e bellard
#if 0
2182 5fafdf24 ths
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
2183 e57a8c0e bellard
           speed, parity, data_bits, stop_bits);
2184 e57a8c0e bellard
#endif
2185 e57a8c0e bellard
    tcgetattr (fd, &tty);
2186 f8d179e3 bellard
2187 f8d179e3 bellard
    switch(speed) {
2188 f8d179e3 bellard
    case 50:
2189 f8d179e3 bellard
        spd = B50;
2190 f8d179e3 bellard
        break;
2191 f8d179e3 bellard
    case 75:
2192 f8d179e3 bellard
        spd = B75;
2193 f8d179e3 bellard
        break;
2194 f8d179e3 bellard
    case 300:
2195 f8d179e3 bellard
        spd = B300;
2196 f8d179e3 bellard
        break;
2197 f8d179e3 bellard
    case 600:
2198 f8d179e3 bellard
        spd = B600;
2199 f8d179e3 bellard
        break;
2200 f8d179e3 bellard
    case 1200:
2201 f8d179e3 bellard
        spd = B1200;
2202 f8d179e3 bellard
        break;
2203 f8d179e3 bellard
    case 2400:
2204 f8d179e3 bellard
        spd = B2400;
2205 f8d179e3 bellard
        break;
2206 f8d179e3 bellard
    case 4800:
2207 f8d179e3 bellard
        spd = B4800;
2208 f8d179e3 bellard
        break;
2209 f8d179e3 bellard
    case 9600:
2210 f8d179e3 bellard
        spd = B9600;
2211 f8d179e3 bellard
        break;
2212 f8d179e3 bellard
    case 19200:
2213 f8d179e3 bellard
        spd = B19200;
2214 f8d179e3 bellard
        break;
2215 f8d179e3 bellard
    case 38400:
2216 f8d179e3 bellard
        spd = B38400;
2217 f8d179e3 bellard
        break;
2218 f8d179e3 bellard
    case 57600:
2219 f8d179e3 bellard
        spd = B57600;
2220 f8d179e3 bellard
        break;
2221 f8d179e3 bellard
    default:
2222 f8d179e3 bellard
    case 115200:
2223 f8d179e3 bellard
        spd = B115200;
2224 f8d179e3 bellard
        break;
2225 f8d179e3 bellard
    }
2226 f8d179e3 bellard
2227 f8d179e3 bellard
    cfsetispeed(&tty, spd);
2228 f8d179e3 bellard
    cfsetospeed(&tty, spd);
2229 f8d179e3 bellard
2230 f8d179e3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2231 f8d179e3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2232 f8d179e3 bellard
    tty.c_oflag |= OPOST;
2233 f8d179e3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
2234 094eed6c bellard
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
2235 f8d179e3 bellard
    switch(data_bits) {
2236 f8d179e3 bellard
    default:
2237 f8d179e3 bellard
    case 8:
2238 f8d179e3 bellard
        tty.c_cflag |= CS8;
2239 f8d179e3 bellard
        break;
2240 f8d179e3 bellard
    case 7:
2241 f8d179e3 bellard
        tty.c_cflag |= CS7;
2242 f8d179e3 bellard
        break;
2243 f8d179e3 bellard
    case 6:
2244 f8d179e3 bellard
        tty.c_cflag |= CS6;
2245 f8d179e3 bellard
        break;
2246 f8d179e3 bellard
    case 5:
2247 f8d179e3 bellard
        tty.c_cflag |= CS5;
2248 f8d179e3 bellard
        break;
2249 f8d179e3 bellard
    }
2250 f8d179e3 bellard
    switch(parity) {
2251 f8d179e3 bellard
    default:
2252 f8d179e3 bellard
    case 'N':
2253 f8d179e3 bellard
        break;
2254 f8d179e3 bellard
    case 'E':
2255 f8d179e3 bellard
        tty.c_cflag |= PARENB;
2256 f8d179e3 bellard
        break;
2257 f8d179e3 bellard
    case 'O':
2258 f8d179e3 bellard
        tty.c_cflag |= PARENB | PARODD;
2259 f8d179e3 bellard
        break;
2260 f8d179e3 bellard
    }
2261 094eed6c bellard
    if (stop_bits == 2)
2262 094eed6c bellard
        tty.c_cflag |= CSTOPB;
2263 3b46e624 ths
2264 f8d179e3 bellard
    tcsetattr (fd, TCSANOW, &tty);
2265 f8d179e3 bellard
}
2266 f8d179e3 bellard
2267 e57a8c0e bellard
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
2268 f8d179e3 bellard
{
2269 f8d179e3 bellard
    FDCharDriver *s = chr->opaque;
2270 3b46e624 ths
2271 e57a8c0e bellard
    switch(cmd) {
2272 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_PARAMS:
2273 e57a8c0e bellard
        {
2274 e57a8c0e bellard
            QEMUSerialSetParams *ssp = arg;
2275 5fafdf24 ths
            tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
2276 e57a8c0e bellard
                            ssp->data_bits, ssp->stop_bits);
2277 e57a8c0e bellard
        }
2278 e57a8c0e bellard
        break;
2279 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_BREAK:
2280 e57a8c0e bellard
        {
2281 e57a8c0e bellard
            int enable = *(int *)arg;
2282 e57a8c0e bellard
            if (enable)
2283 e57a8c0e bellard
                tcsendbreak(s->fd_in, 1);
2284 e57a8c0e bellard
        }
2285 e57a8c0e bellard
        break;
2286 e57a8c0e bellard
    default:
2287 e57a8c0e bellard
        return -ENOTSUP;
2288 e57a8c0e bellard
    }
2289 e57a8c0e bellard
    return 0;
2290 f8d179e3 bellard
}
2291 f8d179e3 bellard
2292 52f61fde ths
static CharDriverState *qemu_chr_open_tty(const char *filename)
2293 f8d179e3 bellard
{
2294 f8d179e3 bellard
    CharDriverState *chr;
2295 f8d179e3 bellard
    int fd;
2296 f8d179e3 bellard
2297 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
2298 f8d179e3 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
2299 f8d179e3 bellard
    tty_serial_init(fd, 115200, 'N', 8, 1);
2300 f8d179e3 bellard
    chr = qemu_chr_open_fd(fd, fd);
2301 aeb30be6 balrog
    if (!chr) {
2302 aeb30be6 balrog
        close(fd);
2303 f8d179e3 bellard
        return NULL;
2304 aeb30be6 balrog
    }
2305 e57a8c0e bellard
    chr->chr_ioctl = tty_serial_ioctl;
2306 86e94dea ths
    qemu_chr_reset(chr);
2307 e57a8c0e bellard
    return chr;
2308 e57a8c0e bellard
}
2309 aec62507 ths
#else  /* ! __linux__ && ! __sun__ */
2310 aec62507 ths
static CharDriverState *qemu_chr_open_pty(void)
2311 aec62507 ths
{
2312 aec62507 ths
    return NULL;
2313 aec62507 ths
}
2314 aec62507 ths
#endif /* __linux__ || __sun__ */
2315 e57a8c0e bellard
2316 aec62507 ths
#if defined(__linux__)
2317 5867c88a ths
typedef struct {
2318 5867c88a ths
    int fd;
2319 5867c88a ths
    int mode;
2320 5867c88a ths
} ParallelCharDriver;
2321 5867c88a ths
2322 5867c88a ths
static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2323 5867c88a ths
{
2324 5867c88a ths
    if (s->mode != mode) {
2325 5867c88a ths
        int m = mode;
2326 5867c88a ths
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
2327 5867c88a ths
            return 0;
2328 5867c88a ths
        s->mode = mode;
2329 5867c88a ths
    }
2330 5867c88a ths
    return 1;
2331 5867c88a ths
}
2332 5867c88a ths
2333 e57a8c0e bellard
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2334 e57a8c0e bellard
{
2335 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2336 5867c88a ths
    int fd = drv->fd;
2337 e57a8c0e bellard
    uint8_t b;
2338 e57a8c0e bellard
2339 e57a8c0e bellard
    switch(cmd) {
2340 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_DATA:
2341 e57a8c0e bellard
        if (ioctl(fd, PPRDATA, &b) < 0)
2342 e57a8c0e bellard
            return -ENOTSUP;
2343 e57a8c0e bellard
        *(uint8_t *)arg = b;
2344 e57a8c0e bellard
        break;
2345 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_DATA:
2346 e57a8c0e bellard
        b = *(uint8_t *)arg;
2347 e57a8c0e bellard
        if (ioctl(fd, PPWDATA, &b) < 0)
2348 e57a8c0e bellard
            return -ENOTSUP;
2349 e57a8c0e bellard
        break;
2350 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_CONTROL:
2351 e57a8c0e bellard
        if (ioctl(fd, PPRCONTROL, &b) < 0)
2352 e57a8c0e bellard
            return -ENOTSUP;
2353 5867c88a ths
        /* Linux gives only the lowest bits, and no way to know data
2354 5867c88a ths
           direction! For better compatibility set the fixed upper
2355 5867c88a ths
           bits. */
2356 5867c88a ths
        *(uint8_t *)arg = b | 0xc0;
2357 e57a8c0e bellard
        break;
2358 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_CONTROL:
2359 e57a8c0e bellard
        b = *(uint8_t *)arg;
2360 e57a8c0e bellard
        if (ioctl(fd, PPWCONTROL, &b) < 0)
2361 e57a8c0e bellard
            return -ENOTSUP;
2362 e57a8c0e bellard
        break;
2363 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_STATUS:
2364 e57a8c0e bellard
        if (ioctl(fd, PPRSTATUS, &b) < 0)
2365 e57a8c0e bellard
            return -ENOTSUP;
2366 e57a8c0e bellard
        *(uint8_t *)arg = b;
2367 e57a8c0e bellard
        break;
2368 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ_ADDR:
2369 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2370 5867c88a ths
            struct ParallelIOArg *parg = arg;
2371 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2372 5867c88a ths
            if (n != parg->count) {
2373 5867c88a ths
                return -EIO;
2374 5867c88a ths
            }
2375 5867c88a ths
        }
2376 5867c88a ths
        break;
2377 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ:
2378 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2379 5867c88a ths
            struct ParallelIOArg *parg = arg;
2380 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2381 5867c88a ths
            if (n != parg->count) {
2382 5867c88a ths
                return -EIO;
2383 5867c88a ths
            }
2384 5867c88a ths
        }
2385 5867c88a ths
        break;
2386 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2387 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2388 5867c88a ths
            struct ParallelIOArg *parg = arg;
2389 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2390 5867c88a ths
            if (n != parg->count) {
2391 5867c88a ths
                return -EIO;
2392 5867c88a ths
            }
2393 5867c88a ths
        }
2394 5867c88a ths
        break;
2395 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE:
2396 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2397 5867c88a ths
            struct ParallelIOArg *parg = arg;
2398 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2399 5867c88a ths
            if (n != parg->count) {
2400 5867c88a ths
                return -EIO;
2401 5867c88a ths
            }
2402 5867c88a ths
        }
2403 5867c88a ths
        break;
2404 e57a8c0e bellard
    default:
2405 e57a8c0e bellard
        return -ENOTSUP;
2406 e57a8c0e bellard
    }
2407 e57a8c0e bellard
    return 0;
2408 e57a8c0e bellard
}
2409 e57a8c0e bellard
2410 5867c88a ths
static void pp_close(CharDriverState *chr)
2411 5867c88a ths
{
2412 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2413 5867c88a ths
    int fd = drv->fd;
2414 5867c88a ths
2415 5867c88a ths
    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2416 5867c88a ths
    ioctl(fd, PPRELEASE);
2417 5867c88a ths
    close(fd);
2418 5867c88a ths
    qemu_free(drv);
2419 5867c88a ths
}
2420 5867c88a ths
2421 52f61fde ths
static CharDriverState *qemu_chr_open_pp(const char *filename)
2422 e57a8c0e bellard
{
2423 e57a8c0e bellard
    CharDriverState *chr;
2424 5867c88a ths
    ParallelCharDriver *drv;
2425 e57a8c0e bellard
    int fd;
2426 e57a8c0e bellard
2427 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR));
2428 e57a8c0e bellard
    if (fd < 0)
2429 e57a8c0e bellard
        return NULL;
2430 e57a8c0e bellard
2431 e57a8c0e bellard
    if (ioctl(fd, PPCLAIM) < 0) {
2432 e57a8c0e bellard
        close(fd);
2433 e57a8c0e bellard
        return NULL;
2434 e57a8c0e bellard
    }
2435 e57a8c0e bellard
2436 5867c88a ths
    drv = qemu_mallocz(sizeof(ParallelCharDriver));
2437 5867c88a ths
    if (!drv) {
2438 5867c88a ths
        close(fd);
2439 5867c88a ths
        return NULL;
2440 5867c88a ths
    }
2441 5867c88a ths
    drv->fd = fd;
2442 5867c88a ths
    drv->mode = IEEE1284_MODE_COMPAT;
2443 5867c88a ths
2444 e57a8c0e bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2445 e57a8c0e bellard
    if (!chr) {
2446 5867c88a ths
        qemu_free(drv);
2447 e57a8c0e bellard
        close(fd);
2448 e57a8c0e bellard
        return NULL;
2449 e57a8c0e bellard
    }
2450 e57a8c0e bellard
    chr->chr_write = null_chr_write;
2451 e57a8c0e bellard
    chr->chr_ioctl = pp_ioctl;
2452 5867c88a ths
    chr->chr_close = pp_close;
2453 5867c88a ths
    chr->opaque = drv;
2454 86e94dea ths
2455 86e94dea ths
    qemu_chr_reset(chr);
2456 86e94dea ths
2457 f8d179e3 bellard
    return chr;
2458 f8d179e3 bellard
}
2459 aec62507 ths
#endif /* __linux__ */
2460 f8d179e3 bellard
2461 aec62507 ths
#else /* _WIN32 */
2462 82c643ff bellard
2463 f331110f bellard
typedef struct {
2464 f331110f bellard
    int max_size;
2465 f331110f bellard
    HANDLE hcom, hrecv, hsend;
2466 f331110f bellard
    OVERLAPPED orecv, osend;
2467 f331110f bellard
    BOOL fpipe;
2468 f331110f bellard
    DWORD len;
2469 f331110f bellard
} WinCharState;
2470 f331110f bellard
2471 f331110f bellard
#define NSENDBUF 2048
2472 f331110f bellard
#define NRECVBUF 2048
2473 f331110f bellard
#define MAXCONNECT 1
2474 f331110f bellard
#define NTIMEOUT 5000
2475 f331110f bellard
2476 f331110f bellard
static int win_chr_poll(void *opaque);
2477 f331110f bellard
static int win_chr_pipe_poll(void *opaque);
2478 f331110f bellard
2479 087f4ae0 ths
static void win_chr_close(CharDriverState *chr)
2480 f331110f bellard
{
2481 087f4ae0 ths
    WinCharState *s = chr->opaque;
2482 087f4ae0 ths
2483 f331110f bellard
    if (s->hsend) {
2484 f331110f bellard
        CloseHandle(s->hsend);
2485 f331110f bellard
        s->hsend = NULL;
2486 f331110f bellard
    }
2487 f331110f bellard
    if (s->hrecv) {
2488 f331110f bellard
        CloseHandle(s->hrecv);
2489 f331110f bellard
        s->hrecv = NULL;
2490 f331110f bellard
    }
2491 f331110f bellard
    if (s->hcom) {
2492 f331110f bellard
        CloseHandle(s->hcom);
2493 f331110f bellard
        s->hcom = NULL;
2494 f331110f bellard
    }
2495 f331110f bellard
    if (s->fpipe)
2496 087f4ae0 ths
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
2497 f331110f bellard
    else
2498 087f4ae0 ths
        qemu_del_polling_cb(win_chr_poll, chr);
2499 f331110f bellard
}
2500 f331110f bellard
2501 087f4ae0 ths
static int win_chr_init(CharDriverState *chr, const char *filename)
2502 f331110f bellard
{
2503 f331110f bellard
    WinCharState *s = chr->opaque;
2504 f331110f bellard
    COMMCONFIG comcfg;
2505 f331110f bellard
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2506 f331110f bellard
    COMSTAT comstat;
2507 f331110f bellard
    DWORD size;
2508 f331110f bellard
    DWORD err;
2509 3b46e624 ths
2510 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2511 f331110f bellard
    if (!s->hsend) {
2512 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2513 f331110f bellard
        goto fail;
2514 f331110f bellard
    }
2515 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2516 f331110f bellard
    if (!s->hrecv) {
2517 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2518 f331110f bellard
        goto fail;
2519 f331110f bellard
    }
2520 f331110f bellard
2521 f331110f bellard
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2522 f331110f bellard
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2523 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2524 f331110f bellard
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2525 f331110f bellard
        s->hcom = NULL;
2526 f331110f bellard
        goto fail;
2527 f331110f bellard
    }
2528 3b46e624 ths
2529 f331110f bellard
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
2530 f331110f bellard
        fprintf(stderr, "Failed SetupComm\n");
2531 f331110f bellard
        goto fail;
2532 f331110f bellard
    }
2533 3b46e624 ths
2534 f331110f bellard
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2535 f331110f bellard
    size = sizeof(COMMCONFIG);
2536 f331110f bellard
    GetDefaultCommConfig(filename, &comcfg, &size);
2537 f331110f bellard
    comcfg.dcb.DCBlength = sizeof(DCB);
2538 f331110f bellard
    CommConfigDialog(filename, NULL, &comcfg);
2539 f331110f bellard
2540 f331110f bellard
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
2541 f331110f bellard
        fprintf(stderr, "Failed SetCommState\n");
2542 f331110f bellard
        goto fail;
2543 f331110f bellard
    }
2544 f331110f bellard
2545 f331110f bellard
    if (!SetCommMask(s->hcom, EV_ERR)) {
2546 f331110f bellard
        fprintf(stderr, "Failed SetCommMask\n");
2547 f331110f bellard
        goto fail;
2548 f331110f bellard
    }
2549 f331110f bellard
2550 f331110f bellard
    cto.ReadIntervalTimeout = MAXDWORD;
2551 f331110f bellard
    if (!SetCommTimeouts(s->hcom, &cto)) {
2552 f331110f bellard
        fprintf(stderr, "Failed SetCommTimeouts\n");
2553 f331110f bellard
        goto fail;
2554 f331110f bellard
    }
2555 3b46e624 ths
2556 f331110f bellard
    if (!ClearCommError(s->hcom, &err, &comstat)) {
2557 f331110f bellard
        fprintf(stderr, "Failed ClearCommError\n");
2558 f331110f bellard
        goto fail;
2559 f331110f bellard
    }
2560 087f4ae0 ths
    qemu_add_polling_cb(win_chr_poll, chr);
2561 f331110f bellard
    return 0;
2562 f331110f bellard
2563 f331110f bellard
 fail:
2564 087f4ae0 ths
    win_chr_close(chr);
2565 f331110f bellard
    return -1;
2566 f331110f bellard
}
2567 f331110f bellard
2568 f331110f bellard
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
2569 f331110f bellard
{
2570 f331110f bellard
    WinCharState *s = chr->opaque;
2571 f331110f bellard
    DWORD len, ret, size, err;
2572 f331110f bellard
2573 f331110f bellard
    len = len1;
2574 f331110f bellard
    ZeroMemory(&s->osend, sizeof(s->osend));
2575 f331110f bellard
    s->osend.hEvent = s->hsend;
2576 f331110f bellard
    while (len > 0) {
2577 f331110f bellard
        if (s->hsend)
2578 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2579 f331110f bellard
        else
2580 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
2581 f331110f bellard
        if (!ret) {
2582 f331110f bellard
            err = GetLastError();
2583 f331110f bellard
            if (err == ERROR_IO_PENDING) {
2584 f331110f bellard
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2585 f331110f bellard
                if (ret) {
2586 f331110f bellard
                    buf += size;
2587 f331110f bellard
                    len -= size;
2588 f331110f bellard
                } else {
2589 f331110f bellard
                    break;
2590 f331110f bellard
                }
2591 f331110f bellard
            } else {
2592 f331110f bellard
                break;
2593 f331110f bellard
            }
2594 f331110f bellard
        } else {
2595 f331110f bellard
            buf += size;
2596 f331110f bellard
            len -= size;
2597 f331110f bellard
        }
2598 f331110f bellard
    }
2599 f331110f bellard
    return len1 - len;
2600 f331110f bellard
}
2601 f331110f bellard
2602 087f4ae0 ths
static int win_chr_read_poll(CharDriverState *chr)
2603 f331110f bellard
{
2604 087f4ae0 ths
    WinCharState *s = chr->opaque;
2605 087f4ae0 ths
2606 087f4ae0 ths
    s->max_size = qemu_chr_can_read(chr);
2607 f331110f bellard
    return s->max_size;
2608 f331110f bellard
}
2609 e5b0bc44 pbrook
2610 087f4ae0 ths
static void win_chr_readfile(CharDriverState *chr)
2611 f331110f bellard
{
2612 087f4ae0 ths
    WinCharState *s = chr->opaque;
2613 f331110f bellard
    int ret, err;
2614 f331110f bellard
    uint8_t buf[1024];
2615 f331110f bellard
    DWORD size;
2616 3b46e624 ths
2617 f331110f bellard
    ZeroMemory(&s->orecv, sizeof(s->orecv));
2618 f331110f bellard
    s->orecv.hEvent = s->hrecv;
2619 f331110f bellard
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2620 f331110f bellard
    if (!ret) {
2621 f331110f bellard
        err = GetLastError();
2622 f331110f bellard
        if (err == ERROR_IO_PENDING) {
2623 f331110f bellard
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2624 f331110f bellard
        }
2625 f331110f bellard
    }
2626 f331110f bellard
2627 f331110f bellard
    if (size > 0) {
2628 087f4ae0 ths
        qemu_chr_read(chr, buf, size);
2629 f331110f bellard
    }
2630 f331110f bellard
}
2631 f331110f bellard
2632 087f4ae0 ths
static void win_chr_read(CharDriverState *chr)
2633 f331110f bellard
{
2634 087f4ae0 ths
    WinCharState *s = chr->opaque;
2635 087f4ae0 ths
2636 f331110f bellard
    if (s->len > s->max_size)
2637 f331110f bellard
        s->len = s->max_size;
2638 f331110f bellard
    if (s->len == 0)
2639 f331110f bellard
        return;
2640 3b46e624 ths
2641 087f4ae0 ths
    win_chr_readfile(chr);
2642 f331110f bellard
}
2643 f331110f bellard
2644 f331110f bellard
static int win_chr_poll(void *opaque)
2645 f331110f bellard
{
2646 087f4ae0 ths
    CharDriverState *chr = opaque;
2647 087f4ae0 ths
    WinCharState *s = chr->opaque;
2648 f331110f bellard
    COMSTAT status;
2649 f331110f bellard
    DWORD comerr;
2650 3b46e624 ths
2651 f331110f bellard
    ClearCommError(s->hcom, &comerr, &status);
2652 f331110f bellard
    if (status.cbInQue > 0) {
2653 f331110f bellard
        s->len = status.cbInQue;
2654 087f4ae0 ths
        win_chr_read_poll(chr);
2655 087f4ae0 ths
        win_chr_read(chr);
2656 f331110f bellard
        return 1;
2657 f331110f bellard
    }
2658 f331110f bellard
    return 0;
2659 f331110f bellard
}
2660 f331110f bellard
2661 52f61fde ths
static CharDriverState *qemu_chr_open_win(const char *filename)
2662 f331110f bellard
{
2663 f331110f bellard
    CharDriverState *chr;
2664 f331110f bellard
    WinCharState *s;
2665 3b46e624 ths
2666 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2667 f331110f bellard
    if (!chr)
2668 f331110f bellard
        return NULL;
2669 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2670 f331110f bellard
    if (!s) {
2671 f331110f bellard
        free(chr);
2672 f331110f bellard
        return NULL;
2673 f331110f bellard
    }
2674 f331110f bellard
    chr->opaque = s;
2675 f331110f bellard
    chr->chr_write = win_chr_write;
2676 f331110f bellard
    chr->chr_close = win_chr_close;
2677 f331110f bellard
2678 087f4ae0 ths
    if (win_chr_init(chr, filename) < 0) {
2679 f331110f bellard
        free(s);
2680 f331110f bellard
        free(chr);
2681 f331110f bellard
        return NULL;
2682 f331110f bellard
    }
2683 86e94dea ths
    qemu_chr_reset(chr);
2684 f331110f bellard
    return chr;
2685 f331110f bellard
}
2686 f331110f bellard
2687 f331110f bellard
static int win_chr_pipe_poll(void *opaque)
2688 f331110f bellard
{
2689 087f4ae0 ths
    CharDriverState *chr = opaque;
2690 087f4ae0 ths
    WinCharState *s = chr->opaque;
2691 f331110f bellard
    DWORD size;
2692 f331110f bellard
2693 f331110f bellard
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2694 f331110f bellard
    if (size > 0) {
2695 f331110f bellard
        s->len = size;
2696 087f4ae0 ths
        win_chr_read_poll(chr);
2697 087f4ae0 ths
        win_chr_read(chr);
2698 f331110f bellard
        return 1;
2699 f331110f bellard
    }
2700 f331110f bellard
    return 0;
2701 f331110f bellard
}
2702 f331110f bellard
2703 087f4ae0 ths
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
2704 f331110f bellard
{
2705 087f4ae0 ths
    WinCharState *s = chr->opaque;
2706 f331110f bellard
    OVERLAPPED ov;
2707 f331110f bellard
    int ret;
2708 f331110f bellard
    DWORD size;
2709 f331110f bellard
    char openname[256];
2710 3b46e624 ths
2711 f331110f bellard
    s->fpipe = TRUE;
2712 f331110f bellard
2713 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2714 f331110f bellard
    if (!s->hsend) {
2715 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2716 f331110f bellard
        goto fail;
2717 f331110f bellard
    }
2718 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2719 f331110f bellard
    if (!s->hrecv) {
2720 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2721 f331110f bellard
        goto fail;
2722 f331110f bellard
    }
2723 3b46e624 ths
2724 f331110f bellard
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
2725 f331110f bellard
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2726 f331110f bellard
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2727 f331110f bellard
                              PIPE_WAIT,
2728 f331110f bellard
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2729 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2730 f331110f bellard
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
2731 f331110f bellard
        s->hcom = NULL;
2732 f331110f bellard
        goto fail;
2733 f331110f bellard
    }
2734 f331110f bellard
2735 f331110f bellard
    ZeroMemory(&ov, sizeof(ov));
2736 f331110f bellard
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2737 f331110f bellard
    ret = ConnectNamedPipe(s->hcom, &ov);
2738 f331110f bellard
    if (ret) {
2739 f331110f bellard
        fprintf(stderr, "Failed ConnectNamedPipe\n");
2740 f331110f bellard
        goto fail;
2741 f331110f bellard
    }
2742 f331110f bellard
2743 f331110f bellard
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2744 f331110f bellard
    if (!ret) {
2745 f331110f bellard
        fprintf(stderr, "Failed GetOverlappedResult\n");
2746 f331110f bellard
        if (ov.hEvent) {
2747 f331110f bellard
            CloseHandle(ov.hEvent);
2748 f331110f bellard
            ov.hEvent = NULL;
2749 f331110f bellard
        }
2750 f331110f bellard
        goto fail;
2751 f331110f bellard
    }
2752 f331110f bellard
2753 f331110f bellard
    if (ov.hEvent) {
2754 f331110f bellard
        CloseHandle(ov.hEvent);
2755 f331110f bellard
        ov.hEvent = NULL;
2756 f331110f bellard
    }
2757 087f4ae0 ths
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
2758 f331110f bellard
    return 0;
2759 f331110f bellard
2760 f331110f bellard
 fail:
2761 087f4ae0 ths
    win_chr_close(chr);
2762 f331110f bellard
    return -1;
2763 f331110f bellard
}
2764 f331110f bellard
2765 f331110f bellard
2766 52f61fde ths
static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
2767 f331110f bellard
{
2768 f331110f bellard
    CharDriverState *chr;
2769 f331110f bellard
    WinCharState *s;
2770 f331110f bellard
2771 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2772 f331110f bellard
    if (!chr)
2773 f331110f bellard
        return NULL;
2774 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2775 f331110f bellard
    if (!s) {
2776 f331110f bellard
        free(chr);
2777 f331110f bellard
        return NULL;
2778 f331110f bellard
    }
2779 f331110f bellard
    chr->opaque = s;
2780 f331110f bellard
    chr->chr_write = win_chr_write;
2781 f331110f bellard
    chr->chr_close = win_chr_close;
2782 3b46e624 ths
2783 087f4ae0 ths
    if (win_chr_pipe_init(chr, filename) < 0) {
2784 f331110f bellard
        free(s);
2785 f331110f bellard
        free(chr);
2786 f331110f bellard
        return NULL;
2787 f331110f bellard
    }
2788 86e94dea ths
    qemu_chr_reset(chr);
2789 f331110f bellard
    return chr;
2790 f331110f bellard
}
2791 f331110f bellard
2792 52f61fde ths
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
2793 f331110f bellard
{
2794 f331110f bellard
    CharDriverState *chr;
2795 f331110f bellard
    WinCharState *s;
2796 f331110f bellard
2797 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2798 f331110f bellard
    if (!chr)
2799 f331110f bellard
        return NULL;
2800 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2801 f331110f bellard
    if (!s) {
2802 f331110f bellard
        free(chr);
2803 f331110f bellard
        return NULL;
2804 f331110f bellard
    }
2805 f331110f bellard
    s->hcom = fd_out;
2806 f331110f bellard
    chr->opaque = s;
2807 f331110f bellard
    chr->chr_write = win_chr_write;
2808 86e94dea ths
    qemu_chr_reset(chr);
2809 f331110f bellard
    return chr;
2810 f331110f bellard
}
2811 72d46479 ths
2812 72d46479 ths
static CharDriverState *qemu_chr_open_win_con(const char *filename)
2813 72d46479 ths
{
2814 72d46479 ths
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
2815 72d46479 ths
}
2816 72d46479 ths
2817 52f61fde ths
static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
2818 f331110f bellard
{
2819 f331110f bellard
    HANDLE fd_out;
2820 3b46e624 ths
2821 f331110f bellard
    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
2822 f331110f bellard
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2823 f331110f bellard
    if (fd_out == INVALID_HANDLE_VALUE)
2824 f331110f bellard
        return NULL;
2825 f331110f bellard
2826 f331110f bellard
    return qemu_chr_open_win_file(fd_out);
2827 f331110f bellard
}
2828 aec62507 ths
#endif /* !_WIN32 */
2829 f331110f bellard
2830 0bab00f3 bellard
/***********************************************************/
2831 0bab00f3 bellard
/* UDP Net console */
2832 0bab00f3 bellard
2833 0bab00f3 bellard
typedef struct {
2834 0bab00f3 bellard
    int fd;
2835 0bab00f3 bellard
    struct sockaddr_in daddr;
2836 0bab00f3 bellard
    char buf[1024];
2837 0bab00f3 bellard
    int bufcnt;
2838 0bab00f3 bellard
    int bufptr;
2839 0bab00f3 bellard
    int max_size;
2840 0bab00f3 bellard
} NetCharDriver;
2841 0bab00f3 bellard
2842 0bab00f3 bellard
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2843 0bab00f3 bellard
{
2844 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2845 0bab00f3 bellard
2846 0bab00f3 bellard
    return sendto(s->fd, buf, len, 0,
2847 0bab00f3 bellard
                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
2848 0bab00f3 bellard
}
2849 0bab00f3 bellard
2850 0bab00f3 bellard
static int udp_chr_read_poll(void *opaque)
2851 0bab00f3 bellard
{
2852 0bab00f3 bellard
    CharDriverState *chr = opaque;
2853 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2854 0bab00f3 bellard
2855 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2856 0bab00f3 bellard
2857 0bab00f3 bellard
    /* If there were any stray characters in the queue process them
2858 0bab00f3 bellard
     * first
2859 0bab00f3 bellard
     */
2860 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2861 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2862 0bab00f3 bellard
        s->bufptr++;
2863 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2864 0bab00f3 bellard
    }
2865 0bab00f3 bellard
    return s->max_size;
2866 0bab00f3 bellard
}
2867 0bab00f3 bellard
2868 0bab00f3 bellard
static void udp_chr_read(void *opaque)
2869 0bab00f3 bellard
{
2870 0bab00f3 bellard
    CharDriverState *chr = opaque;
2871 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2872 0bab00f3 bellard
2873 0bab00f3 bellard
    if (s->max_size == 0)
2874 0bab00f3 bellard
        return;
2875 0bab00f3 bellard
    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
2876 0bab00f3 bellard
    s->bufptr = s->bufcnt;
2877 0bab00f3 bellard
    if (s->bufcnt <= 0)
2878 0bab00f3 bellard
        return;
2879 0bab00f3 bellard
2880 0bab00f3 bellard
    s->bufptr = 0;
2881 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2882 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2883 0bab00f3 bellard
        s->bufptr++;
2884 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2885 0bab00f3 bellard
    }
2886 0bab00f3 bellard
}
2887 0bab00f3 bellard
2888 e5b0bc44 pbrook
static void udp_chr_update_read_handler(CharDriverState *chr)
2889 0bab00f3 bellard
{
2890 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2891 0bab00f3 bellard
2892 0bab00f3 bellard
    if (s->fd >= 0) {
2893 0bab00f3 bellard
        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
2894 0bab00f3 bellard
                             udp_chr_read, NULL, chr);
2895 0bab00f3 bellard
    }
2896 0bab00f3 bellard
}
2897 0bab00f3 bellard
2898 0bab00f3 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str);
2899 52f61fde ths
#ifndef _WIN32
2900 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
2901 52f61fde ths
#endif
2902 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
2903 951f1351 bellard
                        struct sockaddr_in *saddr,
2904 951f1351 bellard
                        const char *str);
2905 0bab00f3 bellard
2906 52f61fde ths
static CharDriverState *qemu_chr_open_udp(const char *def)
2907 0bab00f3 bellard
{
2908 0bab00f3 bellard
    CharDriverState *chr = NULL;
2909 0bab00f3 bellard
    NetCharDriver *s = NULL;
2910 0bab00f3 bellard
    int fd = -1;
2911 951f1351 bellard
    struct sockaddr_in saddr;
2912 0bab00f3 bellard
2913 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2914 0bab00f3 bellard
    if (!chr)
2915 0bab00f3 bellard
        goto return_err;
2916 0bab00f3 bellard
    s = qemu_mallocz(sizeof(NetCharDriver));
2917 0bab00f3 bellard
    if (!s)
2918 0bab00f3 bellard
        goto return_err;
2919 0bab00f3 bellard
2920 0bab00f3 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
2921 0bab00f3 bellard
    if (fd < 0) {
2922 0bab00f3 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
2923 0bab00f3 bellard
        goto return_err;
2924 0bab00f3 bellard
    }
2925 0bab00f3 bellard
2926 951f1351 bellard
    if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
2927 951f1351 bellard
        printf("Could not parse: %s\n", def);
2928 951f1351 bellard
        goto return_err;
2929 0bab00f3 bellard
    }
2930 0bab00f3 bellard
2931 951f1351 bellard
    if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
2932 0bab00f3 bellard
    {
2933 0bab00f3 bellard
        perror("bind");
2934 0bab00f3 bellard
        goto return_err;
2935 0bab00f3 bellard
    }
2936 0bab00f3 bellard
2937 0bab00f3 bellard
    s->fd = fd;
2938 0bab00f3 bellard
    s->bufcnt = 0;
2939 0bab00f3 bellard
    s->bufptr = 0;
2940 0bab00f3 bellard
    chr->opaque = s;
2941 0bab00f3 bellard
    chr->chr_write = udp_chr_write;
2942 e5b0bc44 pbrook
    chr->chr_update_read_handler = udp_chr_update_read_handler;
2943 0bab00f3 bellard
    return chr;
2944 0bab00f3 bellard
2945 0bab00f3 bellard
return_err:
2946 0bab00f3 bellard
    if (chr)
2947 0bab00f3 bellard
        free(chr);
2948 0bab00f3 bellard
    if (s)
2949 0bab00f3 bellard
        free(s);
2950 0bab00f3 bellard
    if (fd >= 0)
2951 0bab00f3 bellard
        closesocket(fd);
2952 0bab00f3 bellard
    return NULL;
2953 0bab00f3 bellard
}
2954 0bab00f3 bellard
2955 0bab00f3 bellard
/***********************************************************/
2956 0bab00f3 bellard
/* TCP Net console */
2957 0bab00f3 bellard
2958 0bab00f3 bellard
typedef struct {
2959 0bab00f3 bellard
    int fd, listen_fd;
2960 0bab00f3 bellard
    int connected;
2961 0bab00f3 bellard
    int max_size;
2962 951f1351 bellard
    int do_telnetopt;
2963 e5b0bc44 pbrook
    int do_nodelay;
2964 ffd843bc ths
    int is_unix;
2965 0bab00f3 bellard
} TCPCharDriver;
2966 0bab00f3 bellard
2967 0bab00f3 bellard
static void tcp_chr_accept(void *opaque);
2968 0bab00f3 bellard
2969 0bab00f3 bellard
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2970 0bab00f3 bellard
{
2971 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2972 0bab00f3 bellard
    if (s->connected) {
2973 0bab00f3 bellard
        return send_all(s->fd, buf, len);
2974 0bab00f3 bellard
    } else {
2975 0bab00f3 bellard
        /* XXX: indicate an error ? */
2976 0bab00f3 bellard
        return len;
2977 0bab00f3 bellard
    }
2978 0bab00f3 bellard
}
2979 0bab00f3 bellard
2980 0bab00f3 bellard
static int tcp_chr_read_poll(void *opaque)
2981 0bab00f3 bellard
{
2982 0bab00f3 bellard
    CharDriverState *chr = opaque;
2983 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2984 0bab00f3 bellard
    if (!s->connected)
2985 0bab00f3 bellard
        return 0;
2986 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2987 0bab00f3 bellard
    return s->max_size;
2988 0bab00f3 bellard
}
2989 0bab00f3 bellard
2990 951f1351 bellard
#define IAC 255
2991 951f1351 bellard
#define IAC_BREAK 243
2992 951f1351 bellard
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2993 951f1351 bellard
                                      TCPCharDriver *s,
2994 951f1351 bellard
                                      char *buf, int *size)
2995 951f1351 bellard
{
2996 951f1351 bellard
    /* Handle any telnet client's basic IAC options to satisfy char by
2997 951f1351 bellard
     * char mode with no echo.  All IAC options will be removed from
2998 951f1351 bellard
     * the buf and the do_telnetopt variable will be used to track the
2999 951f1351 bellard
     * state of the width of the IAC information.
3000 951f1351 bellard
     *
3001 951f1351 bellard
     * IAC commands come in sets of 3 bytes with the exception of the
3002 951f1351 bellard
     * "IAC BREAK" command and the double IAC.
3003 951f1351 bellard
     */
3004 951f1351 bellard
3005 951f1351 bellard
    int i;
3006 951f1351 bellard
    int j = 0;
3007 951f1351 bellard
3008 951f1351 bellard
    for (i = 0; i < *size; i++) {
3009 951f1351 bellard
        if (s->do_telnetopt > 1) {
3010 951f1351 bellard
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3011 951f1351 bellard
                /* Double IAC means send an IAC */
3012 951f1351 bellard
                if (j != i)
3013 951f1351 bellard
                    buf[j] = buf[i];
3014 951f1351 bellard
                j++;
3015 951f1351 bellard
                s->do_telnetopt = 1;
3016 951f1351 bellard
            } else {
3017 951f1351 bellard
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3018 951f1351 bellard
                    /* Handle IAC break commands by sending a serial break */
3019 e5b0bc44 pbrook
                    qemu_chr_event(chr, CHR_EVENT_BREAK);
3020 951f1351 bellard
                    s->do_telnetopt++;
3021 951f1351 bellard
                }
3022 951f1351 bellard
                s->do_telnetopt++;
3023 951f1351 bellard
            }
3024 951f1351 bellard
            if (s->do_telnetopt >= 4) {
3025 951f1351 bellard
                s->do_telnetopt = 1;
3026 951f1351 bellard
            }
3027 951f1351 bellard
        } else {
3028 951f1351 bellard
            if ((unsigned char)buf[i] == IAC) {
3029 951f1351 bellard
                s->do_telnetopt = 2;
3030 951f1351 bellard
            } else {
3031 951f1351 bellard
                if (j != i)
3032 951f1351 bellard
                    buf[j] = buf[i];
3033 951f1351 bellard
                j++;
3034 951f1351 bellard
            }
3035 951f1351 bellard
        }
3036 951f1351 bellard
    }
3037 951f1351 bellard
    *size = j;
3038 951f1351 bellard
}
3039 951f1351 bellard
3040 0bab00f3 bellard
static void tcp_chr_read(void *opaque)
3041 0bab00f3 bellard
{
3042 0bab00f3 bellard
    CharDriverState *chr = opaque;
3043 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3044 0bab00f3 bellard
    uint8_t buf[1024];
3045 0bab00f3 bellard
    int len, size;
3046 0bab00f3 bellard
3047 0bab00f3 bellard
    if (!s->connected || s->max_size <= 0)
3048 0bab00f3 bellard
        return;
3049 0bab00f3 bellard
    len = sizeof(buf);
3050 0bab00f3 bellard
    if (len > s->max_size)
3051 0bab00f3 bellard
        len = s->max_size;
3052 0bab00f3 bellard
    size = recv(s->fd, buf, len, 0);
3053 0bab00f3 bellard
    if (size == 0) {
3054 0bab00f3 bellard
        /* connection closed */
3055 0bab00f3 bellard
        s->connected = 0;
3056 0bab00f3 bellard
        if (s->listen_fd >= 0) {
3057 0bab00f3 bellard
            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3058 0bab00f3 bellard
        }
3059 0bab00f3 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3060 0bab00f3 bellard
        closesocket(s->fd);
3061 0bab00f3 bellard
        s->fd = -1;
3062 0bab00f3 bellard
    } else if (size > 0) {
3063 951f1351 bellard
        if (s->do_telnetopt)
3064 951f1351 bellard
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3065 951f1351 bellard
        if (size > 0)
3066 e5b0bc44 pbrook
            qemu_chr_read(chr, buf, size);
3067 0bab00f3 bellard
    }
3068 0bab00f3 bellard
}
3069 0bab00f3 bellard
3070 0bab00f3 bellard
static void tcp_chr_connect(void *opaque)
3071 0bab00f3 bellard
{
3072 0bab00f3 bellard
    CharDriverState *chr = opaque;
3073 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3074 0bab00f3 bellard
3075 0bab00f3 bellard
    s->connected = 1;
3076 0bab00f3 bellard
    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3077 0bab00f3 bellard
                         tcp_chr_read, NULL, chr);
3078 86e94dea ths
    qemu_chr_reset(chr);
3079 0bab00f3 bellard
}
3080 0bab00f3 bellard
3081 951f1351 bellard
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3082 951f1351 bellard
static void tcp_chr_telnet_init(int fd)
3083 951f1351 bellard
{
3084 951f1351 bellard
    char buf[3];
3085 951f1351 bellard
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3086 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
3087 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3088 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
3089 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3090 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
3091 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3092 951f1351 bellard
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
3093 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3094 951f1351 bellard
}
3095 951f1351 bellard
3096 f7499989 pbrook
static void socket_set_nodelay(int fd)
3097 f7499989 pbrook
{
3098 f7499989 pbrook
    int val = 1;
3099 f7499989 pbrook
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3100 f7499989 pbrook
}
3101 f7499989 pbrook
3102 0bab00f3 bellard
static void tcp_chr_accept(void *opaque)
3103 0bab00f3 bellard
{
3104 0bab00f3 bellard
    CharDriverState *chr = opaque;
3105 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3106 0bab00f3 bellard
    struct sockaddr_in saddr;
3107 ffd843bc ths
#ifndef _WIN32
3108 ffd843bc ths
    struct sockaddr_un uaddr;
3109 ffd843bc ths
#endif
3110 ffd843bc ths
    struct sockaddr *addr;
3111 0bab00f3 bellard
    socklen_t len;
3112 0bab00f3 bellard
    int fd;
3113 0bab00f3 bellard
3114 0bab00f3 bellard
    for(;;) {
3115 ffd843bc ths
#ifndef _WIN32
3116 ffd843bc ths
        if (s->is_unix) {
3117 ffd843bc ths
            len = sizeof(uaddr);
3118 ffd843bc ths
            addr = (struct sockaddr *)&uaddr;
3119 ffd843bc ths
        } else
3120 ffd843bc ths
#endif
3121 ffd843bc ths
        {
3122 ffd843bc ths
            len = sizeof(saddr);
3123 ffd843bc ths
            addr = (struct sockaddr *)&saddr;
3124 ffd843bc ths
        }
3125 ffd843bc ths
        fd = accept(s->listen_fd, addr, &len);
3126 0bab00f3 bellard
        if (fd < 0 && errno != EINTR) {
3127 0bab00f3 bellard
            return;
3128 0bab00f3 bellard
        } else if (fd >= 0) {
3129 951f1351 bellard
            if (s->do_telnetopt)
3130 951f1351 bellard
                tcp_chr_telnet_init(fd);
3131 0bab00f3 bellard
            break;
3132 0bab00f3 bellard
        }
3133 0bab00f3 bellard
    }
3134 0bab00f3 bellard
    socket_set_nonblock(fd);
3135 f7499989 pbrook
    if (s->do_nodelay)
3136 f7499989 pbrook
        socket_set_nodelay(fd);
3137 0bab00f3 bellard
    s->fd = fd;
3138 0bab00f3 bellard
    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3139 0bab00f3 bellard
    tcp_chr_connect(chr);
3140 0bab00f3 bellard
}
3141 0bab00f3 bellard
3142 0bab00f3 bellard
static void tcp_chr_close(CharDriverState *chr)
3143 0bab00f3 bellard
{
3144 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3145 0bab00f3 bellard
    if (s->fd >= 0)
3146 0bab00f3 bellard
        closesocket(s->fd);
3147 0bab00f3 bellard
    if (s->listen_fd >= 0)
3148 0bab00f3 bellard
        closesocket(s->listen_fd);
3149 0bab00f3 bellard
    qemu_free(s);
3150 0bab00f3 bellard
}
3151 0bab00f3 bellard
3152 5fafdf24 ths
static CharDriverState *qemu_chr_open_tcp(const char *host_str,
3153 ffd843bc ths
                                          int is_telnet,
3154 ffd843bc ths
                                          int is_unix)
3155 0bab00f3 bellard
{
3156 0bab00f3 bellard
    CharDriverState *chr = NULL;
3157 0bab00f3 bellard
    TCPCharDriver *s = NULL;
3158 0bab00f3 bellard
    int fd = -1, ret, err, val;
3159 951f1351 bellard
    int is_listen = 0;
3160 951f1351 bellard
    int is_waitconnect = 1;
3161 f7499989 pbrook
    int do_nodelay = 0;
3162 951f1351 bellard
    const char *ptr;
3163 0bab00f3 bellard
    struct sockaddr_in saddr;
3164 ffd843bc ths
#ifndef _WIN32
3165 ffd843bc ths
    struct sockaddr_un uaddr;
3166 ffd843bc ths
#endif
3167 ffd843bc ths
    struct sockaddr *addr;
3168 ffd843bc ths
    socklen_t addrlen;
3169 0bab00f3 bellard
3170 ffd843bc ths
#ifndef _WIN32
3171 ffd843bc ths
    if (is_unix) {
3172 ffd843bc ths
        addr = (struct sockaddr *)&uaddr;
3173 ffd843bc ths
        addrlen = sizeof(uaddr);
3174 ffd843bc ths
        if (parse_unix_path(&uaddr, host_str) < 0)
3175 ffd843bc ths
            goto fail;
3176 ffd843bc ths
    } else
3177 ffd843bc ths
#endif
3178 ffd843bc ths
    {
3179 ffd843bc ths
        addr = (struct sockaddr *)&saddr;
3180 ffd843bc ths
        addrlen = sizeof(saddr);
3181 ffd843bc ths
        if (parse_host_port(&saddr, host_str) < 0)
3182 ffd843bc ths
            goto fail;
3183 ffd843bc ths
    }
3184 0bab00f3 bellard
3185 951f1351 bellard
    ptr = host_str;
3186 951f1351 bellard
    while((ptr = strchr(ptr,','))) {
3187 951f1351 bellard
        ptr++;
3188 951f1351 bellard
        if (!strncmp(ptr,"server",6)) {
3189 951f1351 bellard
            is_listen = 1;
3190 951f1351 bellard
        } else if (!strncmp(ptr,"nowait",6)) {
3191 951f1351 bellard
            is_waitconnect = 0;
3192 f7499989 pbrook
        } else if (!strncmp(ptr,"nodelay",6)) {
3193 f7499989 pbrook
            do_nodelay = 1;
3194 951f1351 bellard
        } else {
3195 951f1351 bellard
            printf("Unknown option: %s\n", ptr);
3196 951f1351 bellard
            goto fail;
3197 951f1351 bellard
        }
3198 951f1351 bellard
    }
3199 951f1351 bellard
    if (!is_listen)
3200 951f1351 bellard
        is_waitconnect = 0;
3201 951f1351 bellard
3202 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
3203 0bab00f3 bellard
    if (!chr)
3204 0bab00f3 bellard
        goto fail;
3205 0bab00f3 bellard
    s = qemu_mallocz(sizeof(TCPCharDriver));
3206 0bab00f3 bellard
    if (!s)
3207 0bab00f3 bellard
        goto fail;
3208 ffd843bc ths
3209 ffd843bc ths
#ifndef _WIN32
3210 ffd843bc ths
    if (is_unix)
3211 ffd843bc ths
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
3212 ffd843bc ths
    else
3213 ffd843bc ths
#endif
3214 ffd843bc ths
        fd = socket(PF_INET, SOCK_STREAM, 0);
3215 5fafdf24 ths
3216 5fafdf24 ths
    if (fd < 0)
3217 0bab00f3 bellard
        goto fail;
3218 951f1351 bellard
3219 951f1351 bellard
    if (!is_waitconnect)
3220 951f1351 bellard
        socket_set_nonblock(fd);
3221 0bab00f3 bellard
3222 0bab00f3 bellard
    s->connected = 0;
3223 0bab00f3 bellard
    s->fd = -1;
3224 0bab00f3 bellard
    s->listen_fd = -1;
3225 ffd843bc ths
    s->is_unix = is_unix;
3226 f7499989 pbrook
    s->do_nodelay = do_nodelay && !is_unix;
3227 ffd843bc ths
3228 ffd843bc ths
    chr->opaque = s;
3229 ffd843bc ths
    chr->chr_write = tcp_chr_write;
3230 ffd843bc ths
    chr->chr_close = tcp_chr_close;
3231 ffd843bc ths
3232 0bab00f3 bellard
    if (is_listen) {
3233 0bab00f3 bellard
        /* allow fast reuse */
3234 ffd843bc ths
#ifndef _WIN32
3235 ffd843bc ths
        if (is_unix) {
3236 ffd843bc ths
            char path[109];
3237 ffd843bc ths
            strncpy(path, uaddr.sun_path, 108);
3238 ffd843bc ths
            path[108] = 0;
3239 ffd843bc ths
            unlink(path);
3240 ffd843bc ths
        } else
3241 ffd843bc ths
#endif
3242 ffd843bc ths
        {
3243 ffd843bc ths
            val = 1;
3244 ffd843bc ths
            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3245 ffd843bc ths
        }
3246 3b46e624 ths
3247 ffd843bc ths
        ret = bind(fd, addr, addrlen);
3248 ffd843bc ths
        if (ret < 0)
3249 0bab00f3 bellard
            goto fail;
3250 ffd843bc ths
3251 0bab00f3 bellard
        ret = listen(fd, 0);
3252 0bab00f3 bellard
        if (ret < 0)
3253 0bab00f3 bellard
            goto fail;
3254 ffd843bc ths
3255 0bab00f3 bellard
        s->listen_fd = fd;
3256 0bab00f3 bellard
        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3257 951f1351 bellard
        if (is_telnet)
3258 951f1351 bellard
            s->do_telnetopt = 1;
3259 0bab00f3 bellard
    } else {
3260 0bab00f3 bellard
        for(;;) {
3261 ffd843bc ths
            ret = connect(fd, addr, addrlen);
3262 0bab00f3 bellard
            if (ret < 0) {
3263 0bab00f3 bellard
                err = socket_error();
3264 0bab00f3 bellard
                if (err == EINTR || err == EWOULDBLOCK) {
3265 0bab00f3 bellard
                } else if (err == EINPROGRESS) {
3266 0bab00f3 bellard
                    break;
3267 f5b12268 ths
#ifdef _WIN32
3268 f5b12268 ths
                } else if (err == WSAEALREADY) {
3269 f5b12268 ths
                    break;
3270 f5b12268 ths
#endif
3271 0bab00f3 bellard
                } else {
3272 0bab00f3 bellard
                    goto fail;
3273 0bab00f3 bellard
                }
3274 0bab00f3 bellard
            } else {
3275 0bab00f3 bellard
                s->connected = 1;
3276 0bab00f3 bellard
                break;
3277 0bab00f3 bellard
            }
3278 0bab00f3 bellard
        }
3279 0bab00f3 bellard
        s->fd = fd;
3280 f7499989 pbrook
        socket_set_nodelay(fd);
3281 0bab00f3 bellard
        if (s->connected)
3282 0bab00f3 bellard
            tcp_chr_connect(chr);
3283 0bab00f3 bellard
        else
3284 0bab00f3 bellard
            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3285 0bab00f3 bellard
    }
3286 3b46e624 ths
3287 951f1351 bellard
    if (is_listen && is_waitconnect) {
3288 951f1351 bellard
        printf("QEMU waiting for connection on: %s\n", host_str);
3289 951f1351 bellard
        tcp_chr_accept(chr);
3290 951f1351 bellard
        socket_set_nonblock(s->listen_fd);
3291 951f1351 bellard
    }
3292 951f1351 bellard
3293 0bab00f3 bellard
    return chr;
3294 0bab00f3 bellard
 fail:
3295 0bab00f3 bellard
    if (fd >= 0)
3296 0bab00f3 bellard
        closesocket(fd);
3297 0bab00f3 bellard
    qemu_free(s);
3298 0bab00f3 bellard
    qemu_free(chr);
3299 0bab00f3 bellard
    return NULL;
3300 0bab00f3 bellard
}
3301 0bab00f3 bellard
3302 82c643ff bellard
CharDriverState *qemu_chr_open(const char *filename)
3303 82c643ff bellard
{
3304 f8d179e3 bellard
    const char *p;
3305 fd1dff4b bellard
3306 82c643ff bellard
    if (!strcmp(filename, "vc")) {
3307 af3a9031 ths
        return text_console_init(&display_state, 0);
3308 af3a9031 ths
    } else if (strstart(filename, "vc:", &p)) {
3309 af3a9031 ths
        return text_console_init(&display_state, p);
3310 82c643ff bellard
    } else if (!strcmp(filename, "null")) {
3311 82c643ff bellard
        return qemu_chr_open_null();
3312 5fafdf24 ths
    } else
3313 0bab00f3 bellard
    if (strstart(filename, "tcp:", &p)) {
3314 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 0);
3315 0bab00f3 bellard
    } else
3316 951f1351 bellard
    if (strstart(filename, "telnet:", &p)) {
3317 ffd843bc ths
        return qemu_chr_open_tcp(p, 1, 0);
3318 0bab00f3 bellard
    } else
3319 0bab00f3 bellard
    if (strstart(filename, "udp:", &p)) {
3320 0bab00f3 bellard
        return qemu_chr_open_udp(p);
3321 0bab00f3 bellard
    } else
3322 20d8a3ed ths
    if (strstart(filename, "mon:", &p)) {
3323 20d8a3ed ths
        CharDriverState *drv = qemu_chr_open(p);
3324 20d8a3ed ths
        if (drv) {
3325 20d8a3ed ths
            drv = qemu_chr_open_mux(drv);
3326 20d8a3ed ths
            monitor_init(drv, !nographic);
3327 20d8a3ed ths
            return drv;
3328 20d8a3ed ths
        }
3329 20d8a3ed ths
        printf("Unable to open driver: %s\n", p);
3330 20d8a3ed ths
        return 0;
3331 20d8a3ed ths
    } else
3332 7664728b bellard
#ifndef _WIN32
3333 ffd843bc ths
    if (strstart(filename, "unix:", &p)) {
3334 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 1);
3335 ffd843bc ths
    } else if (strstart(filename, "file:", &p)) {
3336 f8d179e3 bellard
        return qemu_chr_open_file_out(p);
3337 f8d179e3 bellard
    } else if (strstart(filename, "pipe:", &p)) {
3338 f8d179e3 bellard
        return qemu_chr_open_pipe(p);
3339 7664728b bellard
    } else if (!strcmp(filename, "pty")) {
3340 82c643ff bellard
        return qemu_chr_open_pty();
3341 82c643ff bellard
    } else if (!strcmp(filename, "stdio")) {
3342 82c643ff bellard
        return qemu_chr_open_stdio();
3343 5fafdf24 ths
    } else
3344 f8d179e3 bellard
#if defined(__linux__)
3345 e57a8c0e bellard
    if (strstart(filename, "/dev/parport", NULL)) {
3346 e57a8c0e bellard
        return qemu_chr_open_pp(filename);
3347 5fafdf24 ths
    } else
3348 aec62507 ths
#endif
3349 3fda388a ths
#if defined(__linux__) || defined(__sun__)
3350 f8d179e3 bellard
    if (strstart(filename, "/dev/", NULL)) {
3351 f8d179e3 bellard
        return qemu_chr_open_tty(filename);
3352 3fda388a ths
    } else
3353 3fda388a ths
#endif
3354 aec62507 ths
#else /* !_WIN32 */
3355 f331110f bellard
    if (strstart(filename, "COM", NULL)) {
3356 f331110f bellard
        return qemu_chr_open_win(filename);
3357 f331110f bellard
    } else
3358 f331110f bellard
    if (strstart(filename, "pipe:", &p)) {
3359 f331110f bellard
        return qemu_chr_open_win_pipe(p);
3360 f331110f bellard
    } else
3361 72d46479 ths
    if (strstart(filename, "con:", NULL)) {
3362 72d46479 ths
        return qemu_chr_open_win_con(filename);
3363 72d46479 ths
    } else
3364 f331110f bellard
    if (strstart(filename, "file:", &p)) {
3365 f331110f bellard
        return qemu_chr_open_win_file_out(p);
3366 f331110f bellard
    }
3367 f331110f bellard
#endif
3368 82c643ff bellard
    {
3369 82c643ff bellard
        return NULL;
3370 82c643ff bellard
    }
3371 82c643ff bellard
}
3372 82c643ff bellard
3373 f331110f bellard
void qemu_chr_close(CharDriverState *chr)
3374 f331110f bellard
{
3375 f331110f bellard
    if (chr->chr_close)
3376 f331110f bellard
        chr->chr_close(chr);
3377 f331110f bellard
}
3378 f331110f bellard
3379 80cabfad bellard
/***********************************************************/
3380 7c9d8e07 bellard
/* network device redirectors */
3381 330d0414 bellard
3382 c20709aa bellard
void hex_dump(FILE *f, const uint8_t *buf, int size)
3383 c20709aa bellard
{
3384 c20709aa bellard
    int len, i, j, c;
3385 c20709aa bellard
3386 c20709aa bellard
    for(i=0;i<size;i+=16) {
3387 c20709aa bellard
        len = size - i;
3388 c20709aa bellard
        if (len > 16)
3389 c20709aa bellard
            len = 16;
3390 c20709aa bellard
        fprintf(f, "%08x ", i);
3391 c20709aa bellard
        for(j=0;j<16;j++) {
3392 c20709aa bellard
            if (j < len)
3393 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
3394 c20709aa bellard
            else
3395 c20709aa bellard
                fprintf(f, "   ");
3396 c20709aa bellard
        }
3397 c20709aa bellard
        fprintf(f, " ");
3398 c20709aa bellard
        for(j=0;j<len;j++) {
3399 c20709aa bellard
            c = buf[i+j];
3400 c20709aa bellard
            if (c < ' ' || c > '~')
3401 c20709aa bellard
                c = '.';
3402 c20709aa bellard
            fprintf(f, "%c", c);
3403 c20709aa bellard
        }
3404 c20709aa bellard
        fprintf(f, "\n");
3405 c20709aa bellard
    }
3406 c20709aa bellard
}
3407 c20709aa bellard
3408 7c9d8e07 bellard
static int parse_macaddr(uint8_t *macaddr, const char *p)
3409 c20709aa bellard
{
3410 7c9d8e07 bellard
    int i;
3411 7c9d8e07 bellard
    for(i = 0; i < 6; i++) {
3412 7c9d8e07 bellard
        macaddr[i] = strtol(p, (char **)&p, 16);
3413 7c9d8e07 bellard
        if (i == 5) {
3414 5fafdf24 ths
            if (*p != '\0')
3415 7c9d8e07 bellard
                return -1;
3416 7c9d8e07 bellard
        } else {
3417 5fafdf24 ths
            if (*p != ':')
3418 7c9d8e07 bellard
                return -1;
3419 7c9d8e07 bellard
            p++;
3420 7c9d8e07 bellard
        }
3421 7c9d8e07 bellard
    }
3422 7c9d8e07 bellard
    return 0;
3423 c20709aa bellard
}
3424 67b915a5 bellard
3425 7c9d8e07 bellard
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3426 67b915a5 bellard
{
3427 7c9d8e07 bellard
    const char *p, *p1;
3428 7c9d8e07 bellard
    int len;
3429 7c9d8e07 bellard
    p = *pp;
3430 7c9d8e07 bellard
    p1 = strchr(p, sep);
3431 7c9d8e07 bellard
    if (!p1)
3432 7c9d8e07 bellard
        return -1;
3433 7c9d8e07 bellard
    len = p1 - p;
3434 7c9d8e07 bellard
    p1++;
3435 7c9d8e07 bellard
    if (buf_size > 0) {
3436 7c9d8e07 bellard
        if (len > buf_size - 1)
3437 7c9d8e07 bellard
            len = buf_size - 1;
3438 7c9d8e07 bellard
        memcpy(buf, p, len);
3439 7c9d8e07 bellard
        buf[len] = '\0';
3440 7c9d8e07 bellard
    }
3441 7c9d8e07 bellard
    *pp = p1;
3442 7c9d8e07 bellard
    return 0;
3443 c20709aa bellard
}
3444 c20709aa bellard
3445 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
3446 951f1351 bellard
                        struct sockaddr_in *saddr,
3447 951f1351 bellard
                        const char *input_str)
3448 951f1351 bellard
{
3449 951f1351 bellard
    char *str = strdup(input_str);
3450 951f1351 bellard
    char *host_str = str;
3451 951f1351 bellard
    char *src_str;
3452 951f1351 bellard
    char *ptr;
3453 951f1351 bellard
3454 951f1351 bellard
    /*
3455 951f1351 bellard
     * Chop off any extra arguments at the end of the string which
3456 951f1351 bellard
     * would start with a comma, then fill in the src port information
3457 951f1351 bellard
     * if it was provided else use the "any address" and "any port".
3458 951f1351 bellard
     */
3459 951f1351 bellard
    if ((ptr = strchr(str,',')))
3460 951f1351 bellard
        *ptr = '\0';
3461 951f1351 bellard
3462 951f1351 bellard
    if ((src_str = strchr(input_str,'@'))) {
3463 951f1351 bellard
        *src_str = '\0';
3464 951f1351 bellard
        src_str++;
3465 951f1351 bellard
    }
3466 951f1351 bellard
3467 951f1351 bellard
    if (parse_host_port(haddr, host_str) < 0)
3468 951f1351 bellard
        goto fail;
3469 951f1351 bellard
3470 951f1351 bellard
    if (!src_str || *src_str == '\0')
3471 951f1351 bellard
        src_str = ":0";
3472 951f1351 bellard
3473 951f1351 bellard
    if (parse_host_port(saddr, src_str) < 0)
3474 951f1351 bellard
        goto fail;
3475 951f1351 bellard
3476 951f1351 bellard
    free(str);
3477 951f1351 bellard
    return(0);
3478 951f1351 bellard
3479 951f1351 bellard
fail:
3480 951f1351 bellard
    free(str);
3481 951f1351 bellard
    return -1;
3482 951f1351 bellard
}
3483 951f1351 bellard
3484 7c9d8e07 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str)
3485 7c9d8e07 bellard
{
3486 7c9d8e07 bellard
    char buf[512];
3487 7c9d8e07 bellard
    struct hostent *he;
3488 7c9d8e07 bellard
    const char *p, *r;
3489 7c9d8e07 bellard
    int port;
3490 7c9d8e07 bellard
3491 7c9d8e07 bellard
    p = str;
3492 7c9d8e07 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3493 7c9d8e07 bellard
        return -1;
3494 7c9d8e07 bellard
    saddr->sin_family = AF_INET;
3495 7c9d8e07 bellard
    if (buf[0] == '\0') {
3496 7c9d8e07 bellard
        saddr->sin_addr.s_addr = 0;
3497 7c9d8e07 bellard
    } else {
3498 7c9d8e07 bellard
        if (isdigit(buf[0])) {
3499 7c9d8e07 bellard
            if (!inet_aton(buf, &saddr->sin_addr))
3500 7c9d8e07 bellard
                return -1;
3501 7c9d8e07 bellard
        } else {
3502 7c9d8e07 bellard
            if ((he = gethostbyname(buf)) == NULL)
3503 7c9d8e07 bellard
                return - 1;
3504 7c9d8e07 bellard
            saddr->sin_addr = *(struct in_addr *)he->h_addr;
3505 7c9d8e07 bellard
        }
3506 7c9d8e07 bellard
    }
3507 7c9d8e07 bellard
    port = strtol(p, (char **)&r, 0);
3508 7c9d8e07 bellard
    if (r == p)
3509 7c9d8e07 bellard
        return -1;
3510 7c9d8e07 bellard
    saddr->sin_port = htons(port);
3511 7c9d8e07 bellard
    return 0;
3512 7c9d8e07 bellard
}
3513 c20709aa bellard
3514 52f61fde ths
#ifndef _WIN32
3515 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
3516 ffd843bc ths
{
3517 ffd843bc ths
    const char *p;
3518 ffd843bc ths
    int len;
3519 ffd843bc ths
3520 ffd843bc ths
    len = MIN(108, strlen(str));
3521 ffd843bc ths
    p = strchr(str, ',');
3522 ffd843bc ths
    if (p)
3523 ffd843bc ths
        len = MIN(len, p - str);
3524 ffd843bc ths
3525 ffd843bc ths
    memset(uaddr, 0, sizeof(*uaddr));
3526 ffd843bc ths
3527 ffd843bc ths
    uaddr->sun_family = AF_UNIX;
3528 ffd843bc ths
    memcpy(uaddr->sun_path, str, len);
3529 ffd843bc ths
3530 ffd843bc ths
    return 0;
3531 ffd843bc ths
}
3532 52f61fde ths
#endif
3533 ffd843bc ths
3534 7c9d8e07 bellard
/* find or alloc a new VLAN */
3535 7c9d8e07 bellard
VLANState *qemu_find_vlan(int id)
3536 c20709aa bellard
{
3537 7c9d8e07 bellard
    VLANState **pvlan, *vlan;
3538 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3539 7c9d8e07 bellard
        if (vlan->id == id)
3540 7c9d8e07 bellard
            return vlan;
3541 7c9d8e07 bellard
    }
3542 7c9d8e07 bellard
    vlan = qemu_mallocz(sizeof(VLANState));
3543 7c9d8e07 bellard
    if (!vlan)
3544 7c9d8e07 bellard
        return NULL;
3545 7c9d8e07 bellard
    vlan->id = id;
3546 7c9d8e07 bellard
    vlan->next = NULL;
3547 7c9d8e07 bellard
    pvlan = &first_vlan;
3548 7c9d8e07 bellard
    while (*pvlan != NULL)
3549 7c9d8e07 bellard
        pvlan = &(*pvlan)->next;
3550 7c9d8e07 bellard
    *pvlan = vlan;
3551 7c9d8e07 bellard
    return vlan;
3552 c20709aa bellard
}
3553 c20709aa bellard
3554 7c9d8e07 bellard
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
3555 d861b05e pbrook
                                      IOReadHandler *fd_read,
3556 d861b05e pbrook
                                      IOCanRWHandler *fd_can_read,
3557 d861b05e pbrook
                                      void *opaque)
3558 c20709aa bellard
{
3559 7c9d8e07 bellard
    VLANClientState *vc, **pvc;
3560 7c9d8e07 bellard
    vc = qemu_mallocz(sizeof(VLANClientState));
3561 7c9d8e07 bellard
    if (!vc)
3562 7c9d8e07 bellard
        return NULL;
3563 7c9d8e07 bellard
    vc->fd_read = fd_read;
3564 d861b05e pbrook
    vc->fd_can_read = fd_can_read;
3565 7c9d8e07 bellard
    vc->opaque = opaque;
3566 7c9d8e07 bellard
    vc->vlan = vlan;
3567 7c9d8e07 bellard
3568 7c9d8e07 bellard
    vc->next = NULL;
3569 7c9d8e07 bellard
    pvc = &vlan->first_client;
3570 7c9d8e07 bellard
    while (*pvc != NULL)
3571 7c9d8e07 bellard
        pvc = &(*pvc)->next;
3572 7c9d8e07 bellard
    *pvc = vc;
3573 7c9d8e07 bellard
    return vc;
3574 c20709aa bellard
}
3575 c20709aa bellard
3576 d861b05e pbrook
int qemu_can_send_packet(VLANClientState *vc1)
3577 d861b05e pbrook
{
3578 d861b05e pbrook
    VLANState *vlan = vc1->vlan;
3579 d861b05e pbrook
    VLANClientState *vc;
3580 d861b05e pbrook
3581 d861b05e pbrook
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3582 d861b05e pbrook
        if (vc != vc1) {
3583 fbd1711d balrog
            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
3584 fbd1711d balrog
                return 1;
3585 d861b05e pbrook
        }
3586 d861b05e pbrook
    }
3587 fbd1711d balrog
    return 0;
3588 d861b05e pbrook
}
3589 d861b05e pbrook
3590 7c9d8e07 bellard
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
3591 c20709aa bellard
{
3592 7c9d8e07 bellard
    VLANState *vlan = vc1->vlan;
3593 7c9d8e07 bellard
    VLANClientState *vc;
3594 7c9d8e07 bellard
3595 7c9d8e07 bellard
#if 0
3596 7c9d8e07 bellard
    printf("vlan %d send:\n", vlan->id);
3597 7c9d8e07 bellard
    hex_dump(stdout, buf, size);
3598 7c9d8e07 bellard
#endif
3599 7c9d8e07 bellard
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3600 7c9d8e07 bellard
        if (vc != vc1) {
3601 7c9d8e07 bellard
            vc->fd_read(vc->opaque, buf, size);
3602 7c9d8e07 bellard
        }
3603 7c9d8e07 bellard
    }
3604 67b915a5 bellard
}
3605 67b915a5 bellard
3606 c20709aa bellard
#if defined(CONFIG_SLIRP)
3607 c20709aa bellard
3608 c20709aa bellard
/* slirp network adapter */
3609 c20709aa bellard
3610 c20709aa bellard
static int slirp_inited;
3611 7c9d8e07 bellard
static VLANClientState *slirp_vc;
3612 c20709aa bellard
3613 c20709aa bellard
int slirp_can_output(void)
3614 c20709aa bellard
{
3615 3b7f5d47 pbrook
    return !slirp_vc || qemu_can_send_packet(slirp_vc);
3616 c20709aa bellard
}
3617 c20709aa bellard
3618 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
3619 67b915a5 bellard
{
3620 c20709aa bellard
#if 0
3621 7c9d8e07 bellard
    printf("slirp output:\n");
3622 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
3623 c20709aa bellard
#endif
3624 3b7f5d47 pbrook
    if (!slirp_vc)
3625 3b7f5d47 pbrook
        return;
3626 7c9d8e07 bellard
    qemu_send_packet(slirp_vc, pkt, pkt_len);
3627 67b915a5 bellard
}
3628 67b915a5 bellard
3629 7c9d8e07 bellard
static void slirp_receive(void *opaque, const uint8_t *buf, int size)
3630 c20709aa bellard
{
3631 c20709aa bellard
#if 0
3632 7c9d8e07 bellard
    printf("slirp input:\n");
3633 c20709aa bellard
    hex_dump(stdout, buf, size);
3634 c20709aa bellard
#endif
3635 c20709aa bellard
    slirp_input(buf, size);
3636 c20709aa bellard
}
3637 c20709aa bellard
3638 7c9d8e07 bellard
static int net_slirp_init(VLANState *vlan)
3639 c20709aa bellard
{
3640 c20709aa bellard
    if (!slirp_inited) {
3641 c20709aa bellard
        slirp_inited = 1;
3642 c20709aa bellard
        slirp_init();
3643 c20709aa bellard
    }
3644 5fafdf24 ths
    slirp_vc = qemu_new_vlan_client(vlan,
3645 d861b05e pbrook
                                    slirp_receive, NULL, NULL);
3646 7c9d8e07 bellard
    snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
3647 9bf05444 bellard
    return 0;
3648 9bf05444 bellard
}
3649 9bf05444 bellard
3650 9bf05444 bellard
static void net_slirp_redir(const char *redir_str)
3651 9bf05444 bellard
{
3652 9bf05444 bellard
    int is_udp;
3653 9bf05444 bellard
    char buf[256], *r;
3654 9bf05444 bellard
    const char *p;
3655 9bf05444 bellard
    struct in_addr guest_addr;
3656 9bf05444 bellard
    int host_port, guest_port;
3657 3b46e624 ths
3658 9bf05444 bellard
    if (!slirp_inited) {
3659 9bf05444 bellard
        slirp_inited = 1;
3660 9bf05444 bellard
        slirp_init();
3661 9bf05444 bellard
    }
3662 9bf05444 bellard
3663 9bf05444 bellard
    p = redir_str;
3664 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3665 9bf05444 bellard
        goto fail;
3666 9bf05444 bellard
    if (!strcmp(buf, "tcp")) {
3667 9bf05444 bellard
        is_udp = 0;
3668 9bf05444 bellard
    } else if (!strcmp(buf, "udp")) {
3669 9bf05444 bellard
        is_udp = 1;
3670 9bf05444 bellard
    } else {
3671 9bf05444 bellard
        goto fail;
3672 9bf05444 bellard
    }
3673 9bf05444 bellard
3674 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3675 9bf05444 bellard
        goto fail;
3676 9bf05444 bellard
    host_port = strtol(buf, &r, 0);
3677 9bf05444 bellard
    if (r == buf)
3678 9bf05444 bellard
        goto fail;
3679 9bf05444 bellard
3680 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3681 9bf05444 bellard
        goto fail;
3682 9bf05444 bellard
    if (buf[0] == '\0') {
3683 9bf05444 bellard
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
3684 9bf05444 bellard
    }
3685 9bf05444 bellard
    if (!inet_aton(buf, &guest_addr))
3686 9bf05444 bellard
        goto fail;
3687 3b46e624 ths
3688 9bf05444 bellard
    guest_port = strtol(p, &r, 0);
3689 9bf05444 bellard
    if (r == p)
3690 9bf05444 bellard
        goto fail;
3691 3b46e624 ths
3692 9bf05444 bellard
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
3693 9bf05444 bellard
        fprintf(stderr, "qemu: could not set up redirection\n");
3694 9bf05444 bellard
        exit(1);
3695 9bf05444 bellard
    }
3696 9bf05444 bellard
    return;
3697 9bf05444 bellard
 fail:
3698 9bf05444 bellard
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
3699 9bf05444 bellard
    exit(1);
3700 9bf05444 bellard
}
3701 3b46e624 ths
3702 c94c8d64 bellard
#ifndef _WIN32
3703 c94c8d64 bellard
3704 9d728e8c bellard
char smb_dir[1024];
3705 9d728e8c bellard
3706 9d728e8c bellard
static void smb_exit(void)
3707 9d728e8c bellard
{
3708 9d728e8c bellard
    DIR *d;
3709 9d728e8c bellard
    struct dirent *de;
3710 9d728e8c bellard
    char filename[1024];
3711 9d728e8c bellard
3712 9d728e8c bellard
    /* erase all the files in the directory */
3713 9d728e8c bellard
    d = opendir(smb_dir);
3714 9d728e8c bellard
    for(;;) {
3715 9d728e8c bellard
        de = readdir(d);
3716 9d728e8c bellard
        if (!de)
3717 9d728e8c bellard
            break;
3718 9d728e8c bellard
        if (strcmp(de->d_name, ".") != 0 &&
3719 9d728e8c bellard
            strcmp(de->d_name, "..") != 0) {
3720 5fafdf24 ths
            snprintf(filename, sizeof(filename), "%s/%s",
3721 9d728e8c bellard
                     smb_dir, de->d_name);
3722 9d728e8c bellard
            unlink(filename);
3723 9d728e8c bellard
        }
3724 9d728e8c bellard
    }
3725 03ffbb69 bellard
    closedir(d);
3726 9d728e8c bellard
    rmdir(smb_dir);
3727 9d728e8c bellard
}
3728 9d728e8c bellard
3729 9d728e8c bellard
/* automatic user mode samba server configuration */
3730 9d728e8c bellard
void net_slirp_smb(const char *exported_dir)
3731 9d728e8c bellard
{
3732 9d728e8c bellard
    char smb_conf[1024];
3733 9d728e8c bellard
    char smb_cmdline[1024];
3734 9d728e8c bellard
    FILE *f;
3735 9d728e8c bellard
3736 9d728e8c bellard
    if (!slirp_inited) {
3737 9d728e8c bellard
        slirp_inited = 1;
3738 9d728e8c bellard
        slirp_init();
3739 9d728e8c bellard
    }
3740 9d728e8c bellard
3741 9d728e8c bellard
    /* XXX: better tmp dir construction */
3742 9d728e8c bellard
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
3743 9d728e8c bellard
    if (mkdir(smb_dir, 0700) < 0) {
3744 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
3745 9d728e8c bellard
        exit(1);
3746 9d728e8c bellard
    }
3747 9d728e8c bellard
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
3748 3b46e624 ths
3749 9d728e8c bellard
    f = fopen(smb_conf, "w");
3750 9d728e8c bellard
    if (!f) {
3751 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
3752 9d728e8c bellard
        exit(1);
3753 9d728e8c bellard
    }
3754 5fafdf24 ths
    fprintf(f,
3755 9d728e8c bellard
            "[global]\n"
3756 157777ef bellard
            "private dir=%s\n"
3757 157777ef bellard
            "smb ports=0\n"
3758 157777ef bellard
            "socket address=127.0.0.1\n"
3759 9d728e8c bellard
            "pid directory=%s\n"
3760 9d728e8c bellard
            "lock directory=%s\n"
3761 9d728e8c bellard
            "log file=%s/log.smbd\n"
3762 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
3763 03ffbb69 bellard
            "security = share\n"
3764 9d728e8c bellard
            "[qemu]\n"
3765 9d728e8c bellard
            "path=%s\n"
3766 9d728e8c bellard
            "read only=no\n"
3767 9d728e8c bellard
            "guest ok=yes\n",
3768 9d728e8c bellard
            smb_dir,
3769 157777ef bellard
            smb_dir,
3770 9d728e8c bellard
            smb_dir,
3771 9d728e8c bellard
            smb_dir,
3772 9d728e8c bellard
            smb_dir,
3773 9d728e8c bellard
            exported_dir
3774 9d728e8c bellard
            );
3775 9d728e8c bellard
    fclose(f);
3776 9d728e8c bellard
    atexit(smb_exit);
3777 9d728e8c bellard
3778 a14d6c8c pbrook
    snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
3779 a14d6c8c pbrook
             SMBD_COMMAND, smb_conf);
3780 3b46e624 ths
3781 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
3782 9d728e8c bellard
}
3783 9bf05444 bellard
3784 c94c8d64 bellard
#endif /* !defined(_WIN32) */
3785 c94c8d64 bellard
3786 c20709aa bellard
#endif /* CONFIG_SLIRP */
3787 c20709aa bellard
3788 c20709aa bellard
#if !defined(_WIN32)
3789 7c9d8e07 bellard
3790 7c9d8e07 bellard
typedef struct TAPState {
3791 7c9d8e07 bellard
    VLANClientState *vc;
3792 7c9d8e07 bellard
    int fd;
3793 b46a8906 ths
    char down_script[1024];
3794 7c9d8e07 bellard
} TAPState;
3795 7c9d8e07 bellard
3796 7c9d8e07 bellard
static void tap_receive(void *opaque, const uint8_t *buf, int size)
3797 7c9d8e07 bellard
{
3798 7c9d8e07 bellard
    TAPState *s = opaque;
3799 7c9d8e07 bellard
    int ret;
3800 7c9d8e07 bellard
    for(;;) {
3801 7c9d8e07 bellard
        ret = write(s->fd, buf, size);
3802 7c9d8e07 bellard
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
3803 7c9d8e07 bellard
        } else {
3804 7c9d8e07 bellard
            break;
3805 7c9d8e07 bellard
        }
3806 7c9d8e07 bellard
    }
3807 7c9d8e07 bellard
}
3808 7c9d8e07 bellard
3809 7c9d8e07 bellard
static void tap_send(void *opaque)
3810 7c9d8e07 bellard
{
3811 7c9d8e07 bellard
    TAPState *s = opaque;
3812 7c9d8e07 bellard
    uint8_t buf[4096];
3813 7c9d8e07 bellard
    int size;
3814 7c9d8e07 bellard
3815 d5d10bc3 ths
#ifdef __sun__
3816 d5d10bc3 ths
    struct strbuf sbuf;
3817 d5d10bc3 ths
    int f = 0;
3818 d5d10bc3 ths
    sbuf.maxlen = sizeof(buf);
3819 d5d10bc3 ths
    sbuf.buf = buf;
3820 d5d10bc3 ths
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
3821 d5d10bc3 ths
#else
3822 7c9d8e07 bellard
    size = read(s->fd, buf, sizeof(buf));
3823 d5d10bc3 ths
#endif
3824 7c9d8e07 bellard
    if (size > 0) {
3825 7c9d8e07 bellard
        qemu_send_packet(s->vc, buf, size);
3826 7c9d8e07 bellard
    }
3827 7c9d8e07 bellard
}
3828 7c9d8e07 bellard
3829 7c9d8e07 bellard
/* fd support */
3830 7c9d8e07 bellard
3831 7c9d8e07 bellard
static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
3832 7c9d8e07 bellard
{
3833 7c9d8e07 bellard
    TAPState *s;
3834 7c9d8e07 bellard
3835 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(TAPState));
3836 7c9d8e07 bellard
    if (!s)
3837 7c9d8e07 bellard
        return NULL;
3838 7c9d8e07 bellard
    s->fd = fd;
3839 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
3840 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
3841 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
3842 7c9d8e07 bellard
    return s;
3843 7c9d8e07 bellard
}
3844 7c9d8e07 bellard
3845 5c40d2bd ths
#if defined (_BSD) || defined (__FreeBSD_kernel__)
3846 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3847 7d3505c5 bellard
{
3848 7d3505c5 bellard
    int fd;
3849 7d3505c5 bellard
    char *dev;
3850 7d3505c5 bellard
    struct stat s;
3851 67b915a5 bellard
3852 aeb30be6 balrog
    TFR(fd = open("/dev/tap", O_RDWR));
3853 7d3505c5 bellard
    if (fd < 0) {
3854 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
3855 7d3505c5 bellard
        return -1;
3856 7d3505c5 bellard
    }
3857 7d3505c5 bellard
3858 7d3505c5 bellard
    fstat(fd, &s);
3859 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
3860 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
3861 7d3505c5 bellard
3862 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
3863 7d3505c5 bellard
    return fd;
3864 7d3505c5 bellard
}
3865 ec530c81 bellard
#elif defined(__sun__)
3866 d5d10bc3 ths
#define TUNNEWPPA       (('T'<<16) | 0x0001)
3867 5fafdf24 ths
/*
3868 5fafdf24 ths
 * Allocate TAP device, returns opened fd.
3869 d5d10bc3 ths
 * Stores dev name in the first arg(must be large enough).
3870 3b46e624 ths
 */
3871 d5d10bc3 ths
int tap_alloc(char *dev)
3872 d5d10bc3 ths
{
3873 d5d10bc3 ths
    int tap_fd, if_fd, ppa = -1;
3874 d5d10bc3 ths
    static int ip_fd = 0;
3875 d5d10bc3 ths
    char *ptr;
3876 d5d10bc3 ths
3877 d5d10bc3 ths
    static int arp_fd = 0;
3878 d5d10bc3 ths
    int ip_muxid, arp_muxid;
3879 d5d10bc3 ths
    struct strioctl  strioc_if, strioc_ppa;
3880 d5d10bc3 ths
    int link_type = I_PLINK;;
3881 d5d10bc3 ths
    struct lifreq ifr;
3882 d5d10bc3 ths
    char actual_name[32] = "";
3883 d5d10bc3 ths
3884 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3885 d5d10bc3 ths
3886 d5d10bc3 ths
    if( *dev ){
3887 5fafdf24 ths
       ptr = dev;
3888 5fafdf24 ths
       while( *ptr && !isdigit((int)*ptr) ) ptr++;
3889 d5d10bc3 ths
       ppa = atoi(ptr);
3890 d5d10bc3 ths
    }
3891 d5d10bc3 ths
3892 d5d10bc3 ths
    /* Check if IP device was opened */
3893 d5d10bc3 ths
    if( ip_fd )
3894 d5d10bc3 ths
       close(ip_fd);
3895 d5d10bc3 ths
3896 aeb30be6 balrog
    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
3897 aeb30be6 balrog
    if (ip_fd < 0) {
3898 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
3899 d5d10bc3 ths
       return -1;
3900 d5d10bc3 ths
    }
3901 d5d10bc3 ths
3902 aeb30be6 balrog
    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
3903 aeb30be6 balrog
    if (tap_fd < 0) {
3904 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap");
3905 d5d10bc3 ths
       return -1;
3906 d5d10bc3 ths
    }
3907 d5d10bc3 ths
3908 d5d10bc3 ths
    /* Assign a new PPA and get its unit number. */
3909 d5d10bc3 ths
    strioc_ppa.ic_cmd = TUNNEWPPA;
3910 d5d10bc3 ths
    strioc_ppa.ic_timout = 0;
3911 d5d10bc3 ths
    strioc_ppa.ic_len = sizeof(ppa);
3912 d5d10bc3 ths
    strioc_ppa.ic_dp = (char *)&ppa;
3913 d5d10bc3 ths
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
3914 d5d10bc3 ths
       syslog (LOG_ERR, "Can't assign new interface");
3915 d5d10bc3 ths
3916 aeb30be6 balrog
    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
3917 aeb30be6 balrog
    if (if_fd < 0) {
3918 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
3919 d5d10bc3 ths
       return -1;
3920 d5d10bc3 ths
    }
3921 d5d10bc3 ths
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
3922 d5d10bc3 ths
       syslog(LOG_ERR, "Can't push IP module");
3923 d5d10bc3 ths
       return -1;
3924 d5d10bc3 ths
    }
3925 d5d10bc3 ths
3926 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
3927 d5d10bc3 ths
        syslog(LOG_ERR, "Can't get flags\n");
3928 d5d10bc3 ths
3929 d5d10bc3 ths
    snprintf (actual_name, 32, "tap%d", ppa);
3930 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3931 d5d10bc3 ths
3932 d5d10bc3 ths
    ifr.lifr_ppa = ppa;
3933 d5d10bc3 ths
    /* Assign ppa according to the unit number returned by tun device */
3934 d5d10bc3 ths
3935 d5d10bc3 ths
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
3936 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
3937 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
3938 d5d10bc3 ths
        syslog (LOG_ERR, "Can't get flags\n");
3939 d5d10bc3 ths
    /* Push arp module to if_fd */
3940 d5d10bc3 ths
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
3941 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (2)");
3942 d5d10bc3 ths
3943 d5d10bc3 ths
    /* Push arp module to ip_fd */
3944 d5d10bc3 ths
    if (ioctl (ip_fd, I_POP, NULL) < 0)
3945 d5d10bc3 ths
        syslog (LOG_ERR, "I_POP failed\n");
3946 d5d10bc3 ths
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
3947 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
3948 d5d10bc3 ths
    /* Open arp_fd */
3949 aeb30be6 balrog
    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
3950 aeb30be6 balrog
    if (arp_fd < 0)
3951 d5d10bc3 ths
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
3952 d5d10bc3 ths
3953 d5d10bc3 ths
    /* Set ifname to arp */
3954 d5d10bc3 ths
    strioc_if.ic_cmd = SIOCSLIFNAME;
3955 d5d10bc3 ths
    strioc_if.ic_timout = 0;
3956 d5d10bc3 ths
    strioc_if.ic_len = sizeof(ifr);
3957 d5d10bc3 ths
    strioc_if.ic_dp = (char *)&ifr;
3958 d5d10bc3 ths
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
3959 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set ifname to arp\n");
3960 d5d10bc3 ths
    }
3961 d5d10bc3 ths
3962 d5d10bc3 ths
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
3963 d5d10bc3 ths
       syslog(LOG_ERR, "Can't link TAP device to IP");
3964 d5d10bc3 ths
       return -1;
3965 d5d10bc3 ths
    }
3966 d5d10bc3 ths
3967 d5d10bc3 ths
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
3968 d5d10bc3 ths
        syslog (LOG_ERR, "Can't link TAP device to ARP");
3969 d5d10bc3 ths
3970 d5d10bc3 ths
    close (if_fd);
3971 d5d10bc3 ths
3972 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3973 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3974 d5d10bc3 ths
    ifr.lifr_ip_muxid  = ip_muxid;
3975 d5d10bc3 ths
    ifr.lifr_arp_muxid = arp_muxid;
3976 d5d10bc3 ths
3977 d5d10bc3 ths
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
3978 d5d10bc3 ths
    {
3979 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
3980 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
3981 d5d10bc3 ths
      syslog (LOG_ERR, "Can't set multiplexor id");
3982 d5d10bc3 ths
    }
3983 d5d10bc3 ths
3984 d5d10bc3 ths
    sprintf(dev, "tap%d", ppa);
3985 d5d10bc3 ths
    return tap_fd;
3986 d5d10bc3 ths
}
3987 d5d10bc3 ths
3988 ec530c81 bellard
static int tap_open(char *ifname, int ifname_size)
3989 ec530c81 bellard
{
3990 d5d10bc3 ths
    char  dev[10]="";
3991 d5d10bc3 ths
    int fd;
3992 d5d10bc3 ths
    if( (fd = tap_alloc(dev)) < 0 ){
3993 d5d10bc3 ths
       fprintf(stderr, "Cannot allocate TAP device\n");
3994 d5d10bc3 ths
       return -1;
3995 d5d10bc3 ths
    }
3996 d5d10bc3 ths
    pstrcpy(ifname, ifname_size, dev);
3997 d5d10bc3 ths
    fcntl(fd, F_SETFL, O_NONBLOCK);
3998 d5d10bc3 ths
    return fd;
3999 ec530c81 bellard
}
4000 7d3505c5 bellard
#else
4001 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
4002 330d0414 bellard
{
4003 80cabfad bellard
    struct ifreq ifr;
4004 c4b1fcc0 bellard
    int fd, ret;
4005 3b46e624 ths
4006 aeb30be6 balrog
    TFR(fd = open("/dev/net/tun", O_RDWR));
4007 80cabfad bellard
    if (fd < 0) {
4008 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4009 80cabfad bellard
        return -1;
4010 330d0414 bellard
    }
4011 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
4012 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
4013 7c9d8e07 bellard
    if (ifname[0] != '\0')
4014 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4015 7c9d8e07 bellard
    else
4016 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
4017 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4018 80cabfad bellard
    if (ret != 0) {
4019 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4020 80cabfad bellard
        close(fd);
4021 80cabfad bellard
        return -1;
4022 80cabfad bellard
    }
4023 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
4024 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
4025 c4b1fcc0 bellard
    return fd;
4026 c4b1fcc0 bellard
}
4027 7d3505c5 bellard
#endif
4028 330d0414 bellard
4029 b46a8906 ths
static int launch_script(const char *setup_script, const char *ifname, int fd)
4030 7c9d8e07 bellard
{
4031 b46a8906 ths
    int pid, status;
4032 7c9d8e07 bellard
    char *args[3];
4033 7c9d8e07 bellard
    char **parg;
4034 7c9d8e07 bellard
4035 b46a8906 ths
        /* try to launch network script */
4036 7c9d8e07 bellard
        pid = fork();
4037 7c9d8e07 bellard
        if (pid >= 0) {
4038 7c9d8e07 bellard
            if (pid == 0) {
4039 50d3eeae ths
                int open_max = sysconf (_SC_OPEN_MAX), i;
4040 50d3eeae ths
                for (i = 0; i < open_max; i++)
4041 50d3eeae ths
                    if (i != STDIN_FILENO &&
4042 50d3eeae ths
                        i != STDOUT_FILENO &&
4043 50d3eeae ths
                        i != STDERR_FILENO &&
4044 50d3eeae ths
                        i != fd)
4045 50d3eeae ths
                        close(i);
4046 50d3eeae ths
4047 7c9d8e07 bellard
                parg = args;
4048 7c9d8e07 bellard
                *parg++ = (char *)setup_script;
4049 b46a8906 ths
                *parg++ = (char *)ifname;
4050 7c9d8e07 bellard
                *parg++ = NULL;
4051 7c9d8e07 bellard
                execv(setup_script, args);
4052 4a38940d bellard
                _exit(1);
4053 7c9d8e07 bellard
            }
4054 7c9d8e07 bellard
            while (waitpid(pid, &status, 0) != pid);
4055 7c9d8e07 bellard
            if (!WIFEXITED(status) ||
4056 7c9d8e07 bellard
                WEXITSTATUS(status) != 0) {
4057 7c9d8e07 bellard
                fprintf(stderr, "%s: could not launch network script\n",
4058 7c9d8e07 bellard
                        setup_script);
4059 7c9d8e07 bellard
                return -1;
4060 7c9d8e07 bellard
            }
4061 7c9d8e07 bellard
        }
4062 b46a8906 ths
    return 0;
4063 b46a8906 ths
}
4064 b46a8906 ths
4065 b46a8906 ths
static int net_tap_init(VLANState *vlan, const char *ifname1,
4066 b46a8906 ths
                        const char *setup_script, const char *down_script)
4067 b46a8906 ths
{
4068 b46a8906 ths
    TAPState *s;
4069 b46a8906 ths
    int fd;
4070 b46a8906 ths
    char ifname[128];
4071 b46a8906 ths
4072 b46a8906 ths
    if (ifname1 != NULL)
4073 b46a8906 ths
        pstrcpy(ifname, sizeof(ifname), ifname1);
4074 b46a8906 ths
    else
4075 b46a8906 ths
        ifname[0] = '\0';
4076 b46a8906 ths
    TFR(fd = tap_open(ifname, sizeof(ifname)));
4077 b46a8906 ths
    if (fd < 0)
4078 b46a8906 ths
        return -1;
4079 b46a8906 ths
4080 b46a8906 ths
    if (!setup_script || !strcmp(setup_script, "no"))
4081 b46a8906 ths
        setup_script = "";
4082 b46a8906 ths
    if (setup_script[0] != '\0') {
4083 b46a8906 ths
        if (launch_script(setup_script, ifname, fd))
4084 b46a8906 ths
            return -1;
4085 7c9d8e07 bellard
    }
4086 7c9d8e07 bellard
    s = net_tap_fd_init(vlan, fd);
4087 7c9d8e07 bellard
    if (!s)
4088 7c9d8e07 bellard
        return -1;
4089 5fafdf24 ths
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4090 7c9d8e07 bellard
             "tap: ifname=%s setup_script=%s", ifname, setup_script);
4091 b46a8906 ths
    if (down_script && strcmp(down_script, "no"))
4092 b46a8906 ths
        snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
4093 7c9d8e07 bellard
    return 0;
4094 7c9d8e07 bellard
}
4095 7c9d8e07 bellard
4096 fd1dff4b bellard
#endif /* !_WIN32 */
4097 fd1dff4b bellard
4098 7c9d8e07 bellard
/* network connection */
4099 7c9d8e07 bellard
typedef struct NetSocketState {
4100 7c9d8e07 bellard
    VLANClientState *vc;
4101 7c9d8e07 bellard
    int fd;
4102 7c9d8e07 bellard
    int state; /* 0 = getting length, 1 = getting data */
4103 7c9d8e07 bellard
    int index;
4104 7c9d8e07 bellard
    int packet_len;
4105 7c9d8e07 bellard
    uint8_t buf[4096];
4106 3d830459 bellard
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
4107 7c9d8e07 bellard
} NetSocketState;
4108 7c9d8e07 bellard
4109 7c9d8e07 bellard
typedef struct NetSocketListenState {
4110 7c9d8e07 bellard
    VLANState *vlan;
4111 7c9d8e07 bellard
    int fd;
4112 7c9d8e07 bellard
} NetSocketListenState;
4113 7c9d8e07 bellard
4114 7c9d8e07 bellard
/* XXX: we consider we can send the whole packet without blocking */
4115 7c9d8e07 bellard
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
4116 c20709aa bellard
{
4117 7c9d8e07 bellard
    NetSocketState *s = opaque;
4118 7c9d8e07 bellard
    uint32_t len;
4119 7c9d8e07 bellard
    len = htonl(size);
4120 7c9d8e07 bellard
4121 fd1dff4b bellard
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4122 fd1dff4b bellard
    send_all(s->fd, buf, size);
4123 c20709aa bellard
}
4124 c20709aa bellard
4125 3d830459 bellard
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4126 3d830459 bellard
{
4127 3d830459 bellard
    NetSocketState *s = opaque;
4128 5fafdf24 ths
    sendto(s->fd, buf, size, 0,
4129 3d830459 bellard
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4130 3d830459 bellard
}
4131 3d830459 bellard
4132 7c9d8e07 bellard
static void net_socket_send(void *opaque)
4133 c4b1fcc0 bellard
{
4134 7c9d8e07 bellard
    NetSocketState *s = opaque;
4135 fd1dff4b bellard
    int l, size, err;
4136 7c9d8e07 bellard
    uint8_t buf1[4096];
4137 7c9d8e07 bellard
    const uint8_t *buf;
4138 7c9d8e07 bellard
4139 fd1dff4b bellard
    size = recv(s->fd, buf1, sizeof(buf1), 0);
4140 fd1dff4b bellard
    if (size < 0) {
4141 fd1dff4b bellard
        err = socket_error();
4142 5fafdf24 ths
        if (err != EWOULDBLOCK)
4143 fd1dff4b bellard
            goto eoc;
4144 fd1dff4b bellard
    } else if (size == 0) {
4145 7c9d8e07 bellard
        /* end of connection */
4146 fd1dff4b bellard
    eoc:
4147 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4148 fd1dff4b bellard
        closesocket(s->fd);
4149 7c9d8e07 bellard
        return;
4150 7c9d8e07 bellard
    }
4151 7c9d8e07 bellard
    buf = buf1;
4152 7c9d8e07 bellard
    while (size > 0) {
4153 7c9d8e07 bellard
        /* reassemble a packet from the network */
4154 7c9d8e07 bellard
        switch(s->state) {
4155 7c9d8e07 bellard
        case 0:
4156 7c9d8e07 bellard
            l = 4 - s->index;
4157 7c9d8e07 bellard
            if (l > size)
4158 7c9d8e07 bellard
                l = size;
4159 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4160 7c9d8e07 bellard
            buf += l;
4161 7c9d8e07 bellard
            size -= l;
4162 7c9d8e07 bellard
            s->index += l;
4163 7c9d8e07 bellard
            if (s->index == 4) {
4164 7c9d8e07 bellard
                /* got length */
4165 7c9d8e07 bellard
                s->packet_len = ntohl(*(uint32_t *)s->buf);
4166 7c9d8e07 bellard
                s->index = 0;
4167 7c9d8e07 bellard
                s->state = 1;
4168 7c9d8e07 bellard
            }
4169 7c9d8e07 bellard
            break;
4170 7c9d8e07 bellard
        case 1:
4171 7c9d8e07 bellard
            l = s->packet_len - s->index;
4172 7c9d8e07 bellard
            if (l > size)
4173 7c9d8e07 bellard
                l = size;
4174 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4175 7c9d8e07 bellard
            s->index += l;
4176 7c9d8e07 bellard
            buf += l;
4177 7c9d8e07 bellard
            size -= l;
4178 7c9d8e07 bellard
            if (s->index >= s->packet_len) {
4179 7c9d8e07 bellard
                qemu_send_packet(s->vc, s->buf, s->packet_len);
4180 7c9d8e07 bellard
                s->index = 0;
4181 7c9d8e07 bellard
                s->state = 0;
4182 7c9d8e07 bellard
            }
4183 7c9d8e07 bellard
            break;
4184 7c9d8e07 bellard
        }
4185 7c9d8e07 bellard
    }
4186 c20709aa bellard
}
4187 c20709aa bellard
4188 3d830459 bellard
static void net_socket_send_dgram(void *opaque)
4189 3d830459 bellard
{
4190 3d830459 bellard
    NetSocketState *s = opaque;
4191 3d830459 bellard
    int size;
4192 3d830459 bellard
4193 3d830459 bellard
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
4194 5fafdf24 ths
    if (size < 0)
4195 3d830459 bellard
        return;
4196 3d830459 bellard
    if (size == 0) {
4197 3d830459 bellard
        /* end of connection */
4198 3d830459 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4199 3d830459 bellard
        return;
4200 3d830459 bellard
    }
4201 3d830459 bellard
    qemu_send_packet(s->vc, s->buf, size);
4202 3d830459 bellard
}
4203 3d830459 bellard
4204 3d830459 bellard
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4205 3d830459 bellard
{
4206 3d830459 bellard
    struct ip_mreq imr;
4207 3d830459 bellard
    int fd;
4208 3d830459 bellard
    int val, ret;
4209 3d830459 bellard
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4210 3d830459 bellard
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
4211 5fafdf24 ths
                inet_ntoa(mcastaddr->sin_addr),
4212 fd1dff4b bellard
                (int)ntohl(mcastaddr->sin_addr.s_addr));
4213 3d830459 bellard
        return -1;
4214 3d830459 bellard
4215 3d830459 bellard
    }
4216 3d830459 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
4217 3d830459 bellard
    if (fd < 0) {
4218 3d830459 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
4219 3d830459 bellard
        return -1;
4220 3d830459 bellard
    }
4221 3d830459 bellard
4222 fd1dff4b bellard
    val = 1;
4223 5fafdf24 ths
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
4224 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4225 fd1dff4b bellard
    if (ret < 0) {
4226 fd1dff4b bellard
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4227 fd1dff4b bellard
        goto fail;
4228 fd1dff4b bellard
    }
4229 fd1dff4b bellard
4230 fd1dff4b bellard
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4231 fd1dff4b bellard
    if (ret < 0) {
4232 fd1dff4b bellard
        perror("bind");
4233 fd1dff4b bellard
        goto fail;
4234 fd1dff4b bellard
    }
4235 3b46e624 ths
4236 3d830459 bellard
    /* Add host to multicast group */
4237 3d830459 bellard
    imr.imr_multiaddr = mcastaddr->sin_addr;
4238 3d830459 bellard
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
4239 3d830459 bellard
4240 5fafdf24 ths
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4241 fd1dff4b bellard
                     (const char *)&imr, sizeof(struct ip_mreq));
4242 3d830459 bellard
    if (ret < 0) {
4243 3d830459 bellard
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
4244 3d830459 bellard
        goto fail;
4245 3d830459 bellard
    }
4246 3d830459 bellard
4247 3d830459 bellard
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4248 3d830459 bellard
    val = 1;
4249 5fafdf24 ths
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
4250 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4251 3d830459 bellard
    if (ret < 0) {
4252 3d830459 bellard
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4253 3d830459 bellard
        goto fail;
4254 3d830459 bellard
    }
4255 3d830459 bellard
4256 fd1dff4b bellard
    socket_set_nonblock(fd);
4257 3d830459 bellard
    return fd;
4258 3d830459 bellard
fail:
4259 5fafdf24 ths
    if (fd >= 0)
4260 0bab00f3 bellard
        closesocket(fd);
4261 3d830459 bellard
    return -1;
4262 3d830459 bellard
}
4263 3d830459 bellard
4264 5fafdf24 ths
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
4265 3d830459 bellard
                                          int is_connected)
4266 3d830459 bellard
{
4267 3d830459 bellard
    struct sockaddr_in saddr;
4268 3d830459 bellard
    int newfd;
4269 3d830459 bellard
    socklen_t saddr_len;
4270 3d830459 bellard
    NetSocketState *s;
4271 3d830459 bellard
4272 3d830459 bellard
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
4273 5fafdf24 ths
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
4274 3d830459 bellard
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
4275 3d830459 bellard
     */
4276 3d830459 bellard
4277 3d830459 bellard
    if (is_connected) {
4278 3d830459 bellard
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4279 3d830459 bellard
            /* must be bound */
4280 3d830459 bellard
            if (saddr.sin_addr.s_addr==0) {
4281 3d830459 bellard
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4282 3d830459 bellard
                        fd);
4283 3d830459 bellard
                return NULL;
4284 3d830459 bellard
            }
4285 3d830459 bellard
            /* clone dgram socket */
4286 3d830459 bellard
            newfd = net_socket_mcast_create(&saddr);
4287 3d830459 bellard
            if (newfd < 0) {
4288 3d830459 bellard
                /* error already reported by net_socket_mcast_create() */
4289 3d830459 bellard
                close(fd);
4290 3d830459 bellard
                return NULL;
4291 3d830459 bellard
            }
4292 3d830459 bellard
            /* clone newfd to fd, close newfd */
4293 3d830459 bellard
            dup2(newfd, fd);
4294 3d830459 bellard
            close(newfd);
4295 5fafdf24 ths
4296 3d830459 bellard
        } else {
4297 3d830459 bellard
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4298 3d830459 bellard
                    fd, strerror(errno));
4299 3d830459 bellard
            return NULL;
4300 3d830459 bellard
        }
4301 3d830459 bellard
    }
4302 3d830459 bellard
4303 3d830459 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4304 3d830459 bellard
    if (!s)
4305 3d830459 bellard
        return NULL;
4306 3d830459 bellard
    s->fd = fd;
4307 3d830459 bellard
4308 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
4309 3d830459 bellard
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4310 3d830459 bellard
4311 3d830459 bellard
    /* mcast: save bound address as dst */
4312 3d830459 bellard
    if (is_connected) s->dgram_dst=saddr;
4313 3d830459 bellard
4314 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4315 5fafdf24 ths
            "socket: fd=%d (%s mcast=%s:%d)",
4316 3d830459 bellard
            fd, is_connected? "cloned" : "",
4317 3d830459 bellard
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4318 3d830459 bellard
    return s;
4319 3d830459 bellard
}
4320 3d830459 bellard
4321 7c9d8e07 bellard
static void net_socket_connect(void *opaque)
4322 c20709aa bellard
{
4323 7c9d8e07 bellard
    NetSocketState *s = opaque;
4324 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4325 7c9d8e07 bellard
}
4326 c4b1fcc0 bellard
4327 5fafdf24 ths
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
4328 7c9d8e07 bellard
                                          int is_connected)
4329 7c9d8e07 bellard
{
4330 7c9d8e07 bellard
    NetSocketState *s;
4331 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4332 7c9d8e07 bellard
    if (!s)
4333 7c9d8e07 bellard
        return NULL;
4334 7c9d8e07 bellard
    s->fd = fd;
4335 5fafdf24 ths
    s->vc = qemu_new_vlan_client(vlan,
4336 d861b05e pbrook
                                 net_socket_receive, NULL, s);
4337 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4338 7c9d8e07 bellard
             "socket: fd=%d", fd);
4339 7c9d8e07 bellard
    if (is_connected) {
4340 7c9d8e07 bellard
        net_socket_connect(s);
4341 7c9d8e07 bellard
    } else {
4342 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4343 7c9d8e07 bellard
    }
4344 7c9d8e07 bellard
    return s;
4345 7c9d8e07 bellard
}
4346 c4b1fcc0 bellard
4347 5fafdf24 ths
static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
4348 3d830459 bellard
                                          int is_connected)
4349 3d830459 bellard
{
4350 3d830459 bellard
    int so_type=-1, optlen=sizeof(so_type);
4351 3d830459 bellard
4352 fd1dff4b bellard
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) {
4353 931f03ee ths
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
4354 3d830459 bellard
        return NULL;
4355 3d830459 bellard
    }
4356 3d830459 bellard
    switch(so_type) {
4357 3d830459 bellard
    case SOCK_DGRAM:
4358 3d830459 bellard
        return net_socket_fd_init_dgram(vlan, fd, is_connected);
4359 3d830459 bellard
    case SOCK_STREAM:
4360 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4361 3d830459 bellard
    default:
4362 3d830459 bellard
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4363 3d830459 bellard
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4364 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4365 3d830459 bellard
    }
4366 3d830459 bellard
    return NULL;
4367 3d830459 bellard
}
4368 3d830459 bellard
4369 7c9d8e07 bellard
static void net_socket_accept(void *opaque)
4370 7c9d8e07 bellard
{
4371 3b46e624 ths
    NetSocketListenState *s = opaque;
4372 7c9d8e07 bellard
    NetSocketState *s1;
4373 7c9d8e07 bellard
    struct sockaddr_in saddr;
4374 7c9d8e07 bellard
    socklen_t len;
4375 7c9d8e07 bellard
    int fd;
4376 7c9d8e07 bellard
4377 7c9d8e07 bellard
    for(;;) {
4378 7c9d8e07 bellard
        len = sizeof(saddr);
4379 7c9d8e07 bellard
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4380 7c9d8e07 bellard
        if (fd < 0 && errno != EINTR) {
4381 7c9d8e07 bellard
            return;
4382 7c9d8e07 bellard
        } else if (fd >= 0) {
4383 7c9d8e07 bellard
            break;
4384 80cabfad bellard
        }
4385 330d0414 bellard
    }
4386 5fafdf24 ths
    s1 = net_socket_fd_init(s->vlan, fd, 1);
4387 7c9d8e07 bellard
    if (!s1) {
4388 0bab00f3 bellard
        closesocket(fd);
4389 7c9d8e07 bellard
    } else {
4390 7c9d8e07 bellard
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
4391 5fafdf24 ths
                 "socket: connection from %s:%d",
4392 7c9d8e07 bellard
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4393 7c9d8e07 bellard
    }
4394 7c9d8e07 bellard
}
4395 7c9d8e07 bellard
4396 7c9d8e07 bellard
static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4397 7c9d8e07 bellard
{
4398 7c9d8e07 bellard
    NetSocketListenState *s;
4399 7c9d8e07 bellard
    int fd, val, ret;
4400 7c9d8e07 bellard
    struct sockaddr_in saddr;
4401 7c9d8e07 bellard
4402 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4403 7c9d8e07 bellard
        return -1;
4404 3b46e624 ths
4405 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketListenState));
4406 7c9d8e07 bellard
    if (!s)
4407 7c9d8e07 bellard
        return -1;
4408 7c9d8e07 bellard
4409 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4410 7c9d8e07 bellard
    if (fd < 0) {
4411 7c9d8e07 bellard
        perror("socket");
4412 7c9d8e07 bellard
        return -1;
4413 7c9d8e07 bellard
    }
4414 fd1dff4b bellard
    socket_set_nonblock(fd);
4415 7c9d8e07 bellard
4416 7c9d8e07 bellard
    /* allow fast reuse */
4417 7c9d8e07 bellard
    val = 1;
4418 fd1dff4b bellard
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
4419 3b46e624 ths
4420 7c9d8e07 bellard
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4421 7c9d8e07 bellard
    if (ret < 0) {
4422 7c9d8e07 bellard
        perror("bind");
4423 7c9d8e07 bellard
        return -1;
4424 7c9d8e07 bellard
    }
4425 7c9d8e07 bellard
    ret = listen(fd, 0);
4426 7c9d8e07 bellard
    if (ret < 0) {
4427 7c9d8e07 bellard
        perror("listen");
4428 7c9d8e07 bellard
        return -1;
4429 7c9d8e07 bellard
    }
4430 7c9d8e07 bellard
    s->vlan = vlan;
4431 7c9d8e07 bellard
    s->fd = fd;
4432 7c9d8e07 bellard
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
4433 80cabfad bellard
    return 0;
4434 330d0414 bellard
}
4435 330d0414 bellard
4436 7c9d8e07 bellard
static int net_socket_connect_init(VLANState *vlan, const char *host_str)
4437 330d0414 bellard
{
4438 7c9d8e07 bellard
    NetSocketState *s;
4439 fd1dff4b bellard
    int fd, connected, ret, err;
4440 7c9d8e07 bellard
    struct sockaddr_in saddr;
4441 7c9d8e07 bellard
4442 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4443 7c9d8e07 bellard
        return -1;
4444 7c9d8e07 bellard
4445 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4446 7c9d8e07 bellard
    if (fd < 0) {
4447 7c9d8e07 bellard
        perror("socket");
4448 7c9d8e07 bellard
        return -1;
4449 7c9d8e07 bellard
    }
4450 fd1dff4b bellard
    socket_set_nonblock(fd);
4451 7c9d8e07 bellard
4452 7c9d8e07 bellard
    connected = 0;
4453 7c9d8e07 bellard
    for(;;) {
4454 7c9d8e07 bellard
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4455 7c9d8e07 bellard
        if (ret < 0) {
4456 fd1dff4b bellard
            err = socket_error();
4457 fd1dff4b bellard
            if (err == EINTR || err == EWOULDBLOCK) {
4458 fd1dff4b bellard
            } else if (err == EINPROGRESS) {
4459 7c9d8e07 bellard
                break;
4460 f5b12268 ths
#ifdef _WIN32
4461 f5b12268 ths
            } else if (err == WSAEALREADY) {
4462 f5b12268 ths
                break;
4463 f5b12268 ths
#endif
4464 7c9d8e07 bellard
            } else {
4465 7c9d8e07 bellard
                perror("connect");
4466 fd1dff4b bellard
                closesocket(fd);
4467 7c9d8e07 bellard
                return -1;
4468 7c9d8e07 bellard
            }
4469 7c9d8e07 bellard
        } else {
4470 7c9d8e07 bellard
            connected = 1;
4471 7c9d8e07 bellard
            break;
4472 7c9d8e07 bellard
        }
4473 7c9d8e07 bellard
    }
4474 7c9d8e07 bellard
    s = net_socket_fd_init(vlan, fd, connected);
4475 7c9d8e07 bellard
    if (!s)
4476 7c9d8e07 bellard
        return -1;
4477 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4478 5fafdf24 ths
             "socket: connect to %s:%d",
4479 7c9d8e07 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4480 c20709aa bellard
    return 0;
4481 80cabfad bellard
}
4482 330d0414 bellard
4483 3d830459 bellard
static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
4484 3d830459 bellard
{
4485 3d830459 bellard
    NetSocketState *s;
4486 3d830459 bellard
    int fd;
4487 3d830459 bellard
    struct sockaddr_in saddr;
4488 3d830459 bellard
4489 3d830459 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4490 3d830459 bellard
        return -1;
4491 3d830459 bellard
4492 3d830459 bellard
4493 3d830459 bellard
    fd = net_socket_mcast_create(&saddr);
4494 3d830459 bellard
    if (fd < 0)
4495 3d830459 bellard
        return -1;
4496 3d830459 bellard
4497 3d830459 bellard
    s = net_socket_fd_init(vlan, fd, 0);
4498 3d830459 bellard
    if (!s)
4499 3d830459 bellard
        return -1;
4500 3d830459 bellard
4501 3d830459 bellard
    s->dgram_dst = saddr;
4502 3b46e624 ths
4503 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4504 5fafdf24 ths
             "socket: mcast=%s:%d",
4505 3d830459 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4506 3d830459 bellard
    return 0;
4507 3d830459 bellard
4508 3d830459 bellard
}
4509 3d830459 bellard
4510 7c9d8e07 bellard
static int get_param_value(char *buf, int buf_size,
4511 7c9d8e07 bellard
                           const char *tag, const char *str)
4512 7c9d8e07 bellard
{
4513 7c9d8e07 bellard
    const char *p;
4514 7c9d8e07 bellard
    char *q;
4515 7c9d8e07 bellard
    char option[128];
4516 7c9d8e07 bellard
4517 7c9d8e07 bellard
    p = str;
4518 7c9d8e07 bellard
    for(;;) {
4519 7c9d8e07 bellard
        q = option;
4520 7c9d8e07 bellard
        while (*p != '\0' && *p != '=') {
4521 7c9d8e07 bellard
            if ((q - option) < sizeof(option) - 1)
4522 7c9d8e07 bellard
                *q++ = *p;
4523 7c9d8e07 bellard
            p++;
4524 7c9d8e07 bellard
        }
4525 7c9d8e07 bellard
        *q = '\0';
4526 7c9d8e07 bellard
        if (*p != '=')
4527 7c9d8e07 bellard
            break;
4528 7c9d8e07 bellard
        p++;
4529 7c9d8e07 bellard
        if (!strcmp(tag, option)) {
4530 7c9d8e07 bellard
            q = buf;
4531 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4532 7c9d8e07 bellard
                if ((q - buf) < buf_size - 1)
4533 7c9d8e07 bellard
                    *q++ = *p;
4534 7c9d8e07 bellard
                p++;
4535 7c9d8e07 bellard
            }
4536 7c9d8e07 bellard
            *q = '\0';
4537 7c9d8e07 bellard
            return q - buf;
4538 7c9d8e07 bellard
        } else {
4539 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4540 7c9d8e07 bellard
                p++;
4541 7c9d8e07 bellard
            }
4542 7c9d8e07 bellard
        }
4543 7c9d8e07 bellard
        if (*p != ',')
4544 7c9d8e07 bellard
            break;
4545 7c9d8e07 bellard
        p++;
4546 7c9d8e07 bellard
    }
4547 7c9d8e07 bellard
    return 0;
4548 7c9d8e07 bellard
}
4549 7c9d8e07 bellard
4550 52f61fde ths
static int net_client_init(const char *str)
4551 7c9d8e07 bellard
{
4552 7c9d8e07 bellard
    const char *p;
4553 7c9d8e07 bellard
    char *q;
4554 7c9d8e07 bellard
    char device[64];
4555 7c9d8e07 bellard
    char buf[1024];
4556 7c9d8e07 bellard
    int vlan_id, ret;
4557 7c9d8e07 bellard
    VLANState *vlan;
4558 7c9d8e07 bellard
4559 7c9d8e07 bellard
    p = str;
4560 7c9d8e07 bellard
    q = device;
4561 7c9d8e07 bellard
    while (*p != '\0' && *p != ',') {
4562 7c9d8e07 bellard
        if ((q - device) < sizeof(device) - 1)
4563 7c9d8e07 bellard
            *q++ = *p;
4564 7c9d8e07 bellard
        p++;
4565 7c9d8e07 bellard
    }
4566 7c9d8e07 bellard
    *q = '\0';
4567 7c9d8e07 bellard
    if (*p == ',')
4568 7c9d8e07 bellard
        p++;
4569 7c9d8e07 bellard
    vlan_id = 0;
4570 7c9d8e07 bellard
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
4571 7c9d8e07 bellard
        vlan_id = strtol(buf, NULL, 0);
4572 7c9d8e07 bellard
    }
4573 7c9d8e07 bellard
    vlan = qemu_find_vlan(vlan_id);
4574 7c9d8e07 bellard
    if (!vlan) {
4575 7c9d8e07 bellard
        fprintf(stderr, "Could not create vlan %d\n", vlan_id);
4576 7c9d8e07 bellard
        return -1;
4577 7c9d8e07 bellard
    }
4578 7c9d8e07 bellard
    if (!strcmp(device, "nic")) {
4579 7c9d8e07 bellard
        NICInfo *nd;
4580 7c9d8e07 bellard
        uint8_t *macaddr;
4581 7c9d8e07 bellard
4582 7c9d8e07 bellard
        if (nb_nics >= MAX_NICS) {
4583 7c9d8e07 bellard
            fprintf(stderr, "Too Many NICs\n");
4584 7c9d8e07 bellard
            return -1;
4585 7c9d8e07 bellard
        }
4586 7c9d8e07 bellard
        nd = &nd_table[nb_nics];
4587 7c9d8e07 bellard
        macaddr = nd->macaddr;
4588 7c9d8e07 bellard
        macaddr[0] = 0x52;
4589 7c9d8e07 bellard
        macaddr[1] = 0x54;
4590 7c9d8e07 bellard
        macaddr[2] = 0x00;
4591 7c9d8e07 bellard
        macaddr[3] = 0x12;
4592 7c9d8e07 bellard
        macaddr[4] = 0x34;
4593 7c9d8e07 bellard
        macaddr[5] = 0x56 + nb_nics;
4594 7c9d8e07 bellard
4595 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
4596 7c9d8e07 bellard
            if (parse_macaddr(macaddr, buf) < 0) {
4597 7c9d8e07 bellard
                fprintf(stderr, "invalid syntax for ethernet address\n");
4598 7c9d8e07 bellard
                return -1;
4599 7c9d8e07 bellard
            }
4600 7c9d8e07 bellard
        }
4601 a41b2ff2 pbrook
        if (get_param_value(buf, sizeof(buf), "model", p)) {
4602 a41b2ff2 pbrook
            nd->model = strdup(buf);
4603 a41b2ff2 pbrook
        }
4604 7c9d8e07 bellard
        nd->vlan = vlan;
4605 7c9d8e07 bellard
        nb_nics++;
4606 833c7174 blueswir1
        vlan->nb_guest_devs++;
4607 7c9d8e07 bellard
        ret = 0;
4608 7c9d8e07 bellard
    } else
4609 7c9d8e07 bellard
    if (!strcmp(device, "none")) {
4610 7c9d8e07 bellard
        /* does nothing. It is needed to signal that no network cards
4611 7c9d8e07 bellard
           are wanted */
4612 7c9d8e07 bellard
        ret = 0;
4613 7c9d8e07 bellard
    } else
4614 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
4615 7c9d8e07 bellard
    if (!strcmp(device, "user")) {
4616 115defd1 pbrook
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
4617 3f423c9c bellard
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
4618 115defd1 pbrook
        }
4619 833c7174 blueswir1
        vlan->nb_host_devs++;
4620 7c9d8e07 bellard
        ret = net_slirp_init(vlan);
4621 7c9d8e07 bellard
    } else
4622 7c9d8e07 bellard
#endif
4623 7fb843f8 bellard
#ifdef _WIN32
4624 7fb843f8 bellard
    if (!strcmp(device, "tap")) {
4625 7fb843f8 bellard
        char ifname[64];
4626 7fb843f8 bellard
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4627 7fb843f8 bellard
            fprintf(stderr, "tap: no interface name\n");
4628 7fb843f8 bellard
            return -1;
4629 7fb843f8 bellard
        }
4630 833c7174 blueswir1
        vlan->nb_host_devs++;
4631 7fb843f8 bellard
        ret = tap_win32_init(vlan, ifname);
4632 7fb843f8 bellard
    } else
4633 7fb843f8 bellard
#else
4634 7c9d8e07 bellard
    if (!strcmp(device, "tap")) {
4635 7c9d8e07 bellard
        char ifname[64];
4636 b46a8906 ths
        char setup_script[1024], down_script[1024];
4637 7c9d8e07 bellard
        int fd;
4638 4f01035f pbrook
        vlan->nb_host_devs++;
4639 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4640 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4641 7c9d8e07 bellard
            ret = -1;
4642 7c9d8e07 bellard
            if (net_tap_fd_init(vlan, fd))
4643 7c9d8e07 bellard
                ret = 0;
4644 7c9d8e07 bellard
        } else {
4645 bf8c5342 bellard
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4646 bf8c5342 bellard
                ifname[0] = '\0';
4647 bf8c5342 bellard
            }
4648 7c9d8e07 bellard
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
4649 7c9d8e07 bellard
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
4650 7c9d8e07 bellard
            }
4651 b46a8906 ths
            if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
4652 b46a8906 ths
                pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
4653 b46a8906 ths
            }
4654 b46a8906 ths
            ret = net_tap_init(vlan, ifname, setup_script, down_script);
4655 7c9d8e07 bellard
        }
4656 7c9d8e07 bellard
    } else
4657 fd1dff4b bellard
#endif
4658 7c9d8e07 bellard
    if (!strcmp(device, "socket")) {
4659 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4660 7c9d8e07 bellard
            int fd;
4661 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4662 7c9d8e07 bellard
            ret = -1;
4663 7c9d8e07 bellard
            if (net_socket_fd_init(vlan, fd, 1))
4664 7c9d8e07 bellard
                ret = 0;
4665 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
4666 7c9d8e07 bellard
            ret = net_socket_listen_init(vlan, buf);
4667 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
4668 7c9d8e07 bellard
            ret = net_socket_connect_init(vlan, buf);
4669 3d830459 bellard
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
4670 3d830459 bellard
            ret = net_socket_mcast_init(vlan, buf);
4671 7c9d8e07 bellard
        } else {
4672 7c9d8e07 bellard
            fprintf(stderr, "Unknown socket options: %s\n", p);
4673 7c9d8e07 bellard
            return -1;
4674 7c9d8e07 bellard
        }
4675 833c7174 blueswir1
        vlan->nb_host_devs++;
4676 7c9d8e07 bellard
    } else
4677 7c9d8e07 bellard
    {
4678 7c9d8e07 bellard
        fprintf(stderr, "Unknown network device: %s\n", device);
4679 7c9d8e07 bellard
        return -1;
4680 7c9d8e07 bellard
    }
4681 7c9d8e07 bellard
    if (ret < 0) {
4682 7c9d8e07 bellard
        fprintf(stderr, "Could not initialize device '%s'\n", device);
4683 7c9d8e07 bellard
    }
4684 3b46e624 ths
4685 7c9d8e07 bellard
    return ret;
4686 7c9d8e07 bellard
}
4687 7c9d8e07 bellard
4688 7c9d8e07 bellard
void do_info_network(void)
4689 7c9d8e07 bellard
{
4690 7c9d8e07 bellard
    VLANState *vlan;
4691 7c9d8e07 bellard
    VLANClientState *vc;
4692 7c9d8e07 bellard
4693 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4694 7c9d8e07 bellard
        term_printf("VLAN %d devices:\n", vlan->id);
4695 7c9d8e07 bellard
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
4696 7c9d8e07 bellard
            term_printf("  %s\n", vc->info_str);
4697 7c9d8e07 bellard
    }
4698 7c9d8e07 bellard
}
4699 42550fde ths
4700 330d0414 bellard
/***********************************************************/
4701 a594cfbf bellard
/* USB devices */
4702 a594cfbf bellard
4703 0d92ed30 pbrook
static USBPort *used_usb_ports;
4704 0d92ed30 pbrook
static USBPort *free_usb_ports;
4705 0d92ed30 pbrook
4706 0d92ed30 pbrook
/* ??? Maybe change this to register a hub to keep track of the topology.  */
4707 0d92ed30 pbrook
void qemu_register_usb_port(USBPort *port, void *opaque, int index,
4708 0d92ed30 pbrook
                            usb_attachfn attach)
4709 0d92ed30 pbrook
{
4710 0d92ed30 pbrook
    port->opaque = opaque;
4711 0d92ed30 pbrook
    port->index = index;
4712 0d92ed30 pbrook
    port->attach = attach;
4713 0d92ed30 pbrook
    port->next = free_usb_ports;
4714 0d92ed30 pbrook
    free_usb_ports = port;
4715 0d92ed30 pbrook
}
4716 0d92ed30 pbrook
4717 a594cfbf bellard
static int usb_device_add(const char *devname)
4718 a594cfbf bellard
{
4719 a594cfbf bellard
    const char *p;
4720 a594cfbf bellard
    USBDevice *dev;
4721 0d92ed30 pbrook
    USBPort *port;
4722 a594cfbf bellard
4723 0d92ed30 pbrook
    if (!free_usb_ports)
4724 a594cfbf bellard
        return -1;
4725 a594cfbf bellard
4726 a594cfbf bellard
    if (strstart(devname, "host:", &p)) {
4727 a594cfbf bellard
        dev = usb_host_device_open(p);
4728 a594cfbf bellard
    } else if (!strcmp(devname, "mouse")) {
4729 a594cfbf bellard
        dev = usb_mouse_init();
4730 09b26c5e bellard
    } else if (!strcmp(devname, "tablet")) {
4731 47b2d338 balrog
        dev = usb_tablet_init();
4732 47b2d338 balrog
    } else if (!strcmp(devname, "keyboard")) {
4733 47b2d338 balrog
        dev = usb_keyboard_init();
4734 2e5d83bb pbrook
    } else if (strstart(devname, "disk:", &p)) {
4735 2e5d83bb pbrook
        dev = usb_msd_init(p);
4736 f6d2a316 balrog
    } else if (!strcmp(devname, "wacom-tablet")) {
4737 f6d2a316 balrog
        dev = usb_wacom_init();
4738 a594cfbf bellard
    } else {
4739 a594cfbf bellard
        return -1;
4740 a594cfbf bellard
    }
4741 0d92ed30 pbrook
    if (!dev)
4742 0d92ed30 pbrook
        return -1;
4743 0d92ed30 pbrook
4744 0d92ed30 pbrook
    /* Find a USB port to add the device to.  */
4745 0d92ed30 pbrook
    port = free_usb_ports;
4746 0d92ed30 pbrook
    if (!port->next) {
4747 0d92ed30 pbrook
        USBDevice *hub;
4748 0d92ed30 pbrook
4749 0d92ed30 pbrook
        /* Create a new hub and chain it on.  */
4750 0d92ed30 pbrook
        free_usb_ports = NULL;
4751 0d92ed30 pbrook
        port->next = used_usb_ports;
4752 0d92ed30 pbrook
        used_usb_ports = port;
4753 0d92ed30 pbrook
4754 0d92ed30 pbrook
        hub = usb_hub_init(VM_USB_HUB_SIZE);
4755 0d92ed30 pbrook
        usb_attach(port, hub);
4756 0d92ed30 pbrook
        port = free_usb_ports;
4757 0d92ed30 pbrook
    }
4758 0d92ed30 pbrook
4759 0d92ed30 pbrook
    free_usb_ports = port->next;
4760 0d92ed30 pbrook
    port->next = used_usb_ports;
4761 0d92ed30 pbrook
    used_usb_ports = port;
4762 0d92ed30 pbrook
    usb_attach(port, dev);
4763 a594cfbf bellard
    return 0;
4764 a594cfbf bellard
}
4765 a594cfbf bellard
4766 a594cfbf bellard
static int usb_device_del(const char *devname)
4767 a594cfbf bellard
{
4768 0d92ed30 pbrook
    USBPort *port;
4769 0d92ed30 pbrook
    USBPort **lastp;
4770 059809e4 bellard
    USBDevice *dev;
4771 0d92ed30 pbrook
    int bus_num, addr;
4772 a594cfbf bellard
    const char *p;
4773 a594cfbf bellard
4774 0d92ed30 pbrook
    if (!used_usb_ports)
4775 a594cfbf bellard
        return -1;
4776 a594cfbf bellard
4777 a594cfbf bellard
    p = strchr(devname, '.');
4778 5fafdf24 ths
    if (!p)
4779 a594cfbf bellard
        return -1;
4780 a594cfbf bellard
    bus_num = strtoul(devname, NULL, 0);
4781 a594cfbf bellard
    addr = strtoul(p + 1, NULL, 0);
4782 a594cfbf bellard
    if (bus_num != 0)
4783 a594cfbf bellard
        return -1;
4784 0d92ed30 pbrook
4785 0d92ed30 pbrook
    lastp = &used_usb_ports;
4786 0d92ed30 pbrook
    port = used_usb_ports;
4787 0d92ed30 pbrook
    while (port && port->dev->addr != addr) {
4788 0d92ed30 pbrook
        lastp = &port->next;
4789 0d92ed30 pbrook
        port = port->next;
4790 a594cfbf bellard
    }
4791 0d92ed30 pbrook
4792 0d92ed30 pbrook
    if (!port)
4793 a594cfbf bellard
        return -1;
4794 0d92ed30 pbrook
4795 059809e4 bellard
    dev = port->dev;
4796 0d92ed30 pbrook
    *lastp = port->next;
4797 0d92ed30 pbrook
    usb_attach(port, NULL);
4798 059809e4 bellard
    dev->handle_destroy(dev);
4799 0d92ed30 pbrook
    port->next = free_usb_ports;
4800 0d92ed30 pbrook
    free_usb_ports = port;
4801 a594cfbf bellard
    return 0;
4802 a594cfbf bellard
}
4803 a594cfbf bellard
4804 a594cfbf bellard
void do_usb_add(const char *devname)
4805 a594cfbf bellard
{
4806 a594cfbf bellard
    int ret;
4807 a594cfbf bellard
    ret = usb_device_add(devname);
4808 5fafdf24 ths
    if (ret < 0)
4809 a594cfbf bellard
        term_printf("Could not add USB device '%s'\n", devname);
4810 a594cfbf bellard
}
4811 a594cfbf bellard
4812 a594cfbf bellard
void do_usb_del(const char *devname)
4813 a594cfbf bellard
{
4814 a594cfbf bellard
    int ret;
4815 a594cfbf bellard
    ret = usb_device_del(devname);
4816 5fafdf24 ths
    if (ret < 0)
4817 a594cfbf bellard
        term_printf("Could not remove USB device '%s'\n", devname);
4818 a594cfbf bellard
}
4819 a594cfbf bellard
4820 a594cfbf bellard
void usb_info(void)
4821 a594cfbf bellard
{
4822 a594cfbf bellard
    USBDevice *dev;
4823 0d92ed30 pbrook
    USBPort *port;
4824 a594cfbf bellard
    const char *speed_str;
4825 a594cfbf bellard
4826 0d92ed30 pbrook
    if (!usb_enabled) {
4827 a594cfbf bellard
        term_printf("USB support not enabled\n");
4828 a594cfbf bellard
        return;
4829 a594cfbf bellard
    }
4830 a594cfbf bellard
4831 0d92ed30 pbrook
    for (port = used_usb_ports; port; port = port->next) {
4832 0d92ed30 pbrook
        dev = port->dev;
4833 0d92ed30 pbrook
        if (!dev)
4834 0d92ed30 pbrook
            continue;
4835 0d92ed30 pbrook
        switch(dev->speed) {
4836 5fafdf24 ths
        case USB_SPEED_LOW:
4837 5fafdf24 ths
            speed_str = "1.5";
4838 0d92ed30 pbrook
            break;
4839 5fafdf24 ths
        case USB_SPEED_FULL:
4840 5fafdf24 ths
            speed_str = "12";
4841 0d92ed30 pbrook
            break;
4842 5fafdf24 ths
        case USB_SPEED_HIGH:
4843 5fafdf24 ths
            speed_str = "480";
4844 0d92ed30 pbrook
            break;
4845 0d92ed30 pbrook
        default:
4846 5fafdf24 ths
            speed_str = "?";
4847 0d92ed30 pbrook
            break;
4848 a594cfbf bellard
        }
4849 5fafdf24 ths
        term_printf("  Device %d.%d, Speed %s Mb/s, Product %s\n",
4850 1f6e24e7 bellard
                    0, dev->addr, speed_str, dev->devname);
4851 a594cfbf bellard
    }
4852 a594cfbf bellard
}
4853 a594cfbf bellard
4854 f7cce898 bellard
/***********************************************************/
4855 201a51fc balrog
/* PCMCIA/Cardbus */
4856 201a51fc balrog
4857 201a51fc balrog
static struct pcmcia_socket_entry_s {
4858 201a51fc balrog
    struct pcmcia_socket_s *socket;
4859 201a51fc balrog
    struct pcmcia_socket_entry_s *next;
4860 201a51fc balrog
} *pcmcia_sockets = 0;
4861 201a51fc balrog
4862 201a51fc balrog
void pcmcia_socket_register(struct pcmcia_socket_s *socket)
4863 201a51fc balrog
{
4864 201a51fc balrog
    struct pcmcia_socket_entry_s *entry;
4865 201a51fc balrog
4866 201a51fc balrog
    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
4867 201a51fc balrog
    entry->socket = socket;
4868 201a51fc balrog
    entry->next = pcmcia_sockets;
4869 201a51fc balrog
    pcmcia_sockets = entry;
4870 201a51fc balrog
}
4871 201a51fc balrog
4872 201a51fc balrog
void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
4873 201a51fc balrog
{
4874 201a51fc balrog
    struct pcmcia_socket_entry_s *entry, **ptr;
4875 201a51fc balrog
4876 201a51fc balrog
    ptr = &pcmcia_sockets;
4877 201a51fc balrog
    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
4878 201a51fc balrog
        if (entry->socket == socket) {
4879 201a51fc balrog
            *ptr = entry->next;
4880 201a51fc balrog
            qemu_free(entry);
4881 201a51fc balrog
        }
4882 201a51fc balrog
}
4883 201a51fc balrog
4884 201a51fc balrog
void pcmcia_info(void)
4885 201a51fc balrog
{
4886 201a51fc balrog
    struct pcmcia_socket_entry_s *iter;
4887 201a51fc balrog
    if (!pcmcia_sockets)
4888 201a51fc balrog
        term_printf("No PCMCIA sockets\n");
4889 201a51fc balrog
4890 201a51fc balrog
    for (iter = pcmcia_sockets; iter; iter = iter->next)
4891 201a51fc balrog
        term_printf("%s: %s\n", iter->socket->slot_string,
4892 201a51fc balrog
                    iter->socket->attached ? iter->socket->card_string :
4893 201a51fc balrog
                    "Empty");
4894 201a51fc balrog
}
4895 201a51fc balrog
4896 201a51fc balrog
/***********************************************************/
4897 2ff89790 ths
/* dumb display */
4898 2ff89790 ths
4899 2ff89790 ths
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
4900 2ff89790 ths
{
4901 2ff89790 ths
}
4902 2ff89790 ths
4903 2ff89790 ths
static void dumb_resize(DisplayState *ds, int w, int h)
4904 2ff89790 ths
{
4905 2ff89790 ths
}
4906 2ff89790 ths
4907 2ff89790 ths
static void dumb_refresh(DisplayState *ds)
4908 2ff89790 ths
{
4909 2ff89790 ths
#if defined(CONFIG_SDL)
4910 2ff89790 ths
    vga_hw_update();
4911 2ff89790 ths
#endif
4912 2ff89790 ths
}
4913 2ff89790 ths
4914 2ff89790 ths
static void dumb_display_init(DisplayState *ds)
4915 2ff89790 ths
{
4916 2ff89790 ths
    ds->data = NULL;
4917 2ff89790 ths
    ds->linesize = 0;
4918 2ff89790 ths
    ds->depth = 0;
4919 2ff89790 ths
    ds->dpy_update = dumb_update;
4920 2ff89790 ths
    ds->dpy_resize = dumb_resize;
4921 2ff89790 ths
    ds->dpy_refresh = dumb_refresh;
4922 2ff89790 ths
}
4923 2ff89790 ths
4924 2ff89790 ths
/***********************************************************/
4925 8a7ddc38 bellard
/* I/O handling */
4926 0824d6fc bellard
4927 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
4928 c4b1fcc0 bellard
4929 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
4930 c4b1fcc0 bellard
    int fd;
4931 7c9d8e07 bellard
    IOCanRWHandler *fd_read_poll;
4932 7c9d8e07 bellard
    IOHandler *fd_read;
4933 7c9d8e07 bellard
    IOHandler *fd_write;
4934 cafffd40 ths
    int deleted;
4935 c4b1fcc0 bellard
    void *opaque;
4936 c4b1fcc0 bellard
    /* temporary data */
4937 c4b1fcc0 bellard
    struct pollfd *ufd;
4938 8a7ddc38 bellard
    struct IOHandlerRecord *next;
4939 c4b1fcc0 bellard
} IOHandlerRecord;
4940 c4b1fcc0 bellard
4941 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
4942 c4b1fcc0 bellard
4943 7c9d8e07 bellard
/* XXX: fd_read_poll should be suppressed, but an API change is
4944 7c9d8e07 bellard
   necessary in the character devices to suppress fd_can_read(). */
4945 5fafdf24 ths
int qemu_set_fd_handler2(int fd,
4946 5fafdf24 ths
                         IOCanRWHandler *fd_read_poll,
4947 5fafdf24 ths
                         IOHandler *fd_read,
4948 5fafdf24 ths
                         IOHandler *fd_write,
4949 7c9d8e07 bellard
                         void *opaque)
4950 c4b1fcc0 bellard
{
4951 7c9d8e07 bellard
    IOHandlerRecord **pioh, *ioh;
4952 c4b1fcc0 bellard
4953 7c9d8e07 bellard
    if (!fd_read && !fd_write) {
4954 7c9d8e07 bellard
        pioh = &first_io_handler;
4955 7c9d8e07 bellard
        for(;;) {
4956 7c9d8e07 bellard
            ioh = *pioh;
4957 7c9d8e07 bellard
            if (ioh == NULL)
4958 7c9d8e07 bellard
                break;
4959 7c9d8e07 bellard
            if (ioh->fd == fd) {
4960 cafffd40 ths
                ioh->deleted = 1;
4961 7c9d8e07 bellard
                break;
4962 7c9d8e07 bellard
            }
4963 7c9d8e07 bellard
            pioh = &ioh->next;
4964 7c9d8e07 bellard
        }
4965 7c9d8e07 bellard
    } else {
4966 7c9d8e07 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
4967 7c9d8e07 bellard
            if (ioh->fd == fd)
4968 7c9d8e07 bellard
                goto found;
4969 7c9d8e07 bellard
        }
4970 7c9d8e07 bellard
        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
4971 7c9d8e07 bellard
        if (!ioh)
4972 7c9d8e07 bellard
            return -1;
4973 7c9d8e07 bellard
        ioh->next = first_io_handler;
4974 7c9d8e07 bellard
        first_io_handler = ioh;
4975 7c9d8e07 bellard
    found:
4976 7c9d8e07 bellard
        ioh->fd = fd;
4977 7c9d8e07 bellard
        ioh->fd_read_poll = fd_read_poll;
4978 7c9d8e07 bellard
        ioh->fd_read = fd_read;
4979 7c9d8e07 bellard
        ioh->fd_write = fd_write;
4980 7c9d8e07 bellard
        ioh->opaque = opaque;
4981 cafffd40 ths
        ioh->deleted = 0;
4982 7c9d8e07 bellard
    }
4983 c4b1fcc0 bellard
    return 0;
4984 c4b1fcc0 bellard
}
4985 c4b1fcc0 bellard
4986 5fafdf24 ths
int qemu_set_fd_handler(int fd,
4987 5fafdf24 ths
                        IOHandler *fd_read,
4988 5fafdf24 ths
                        IOHandler *fd_write,
4989 7c9d8e07 bellard
                        void *opaque)
4990 8a7ddc38 bellard
{
4991 7c9d8e07 bellard
    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
4992 8a7ddc38 bellard
}
4993 8a7ddc38 bellard
4994 8a7ddc38 bellard
/***********************************************************/
4995 f331110f bellard
/* Polling handling */
4996 f331110f bellard
4997 f331110f bellard
typedef struct PollingEntry {
4998 f331110f bellard
    PollingFunc *func;
4999 f331110f bellard
    void *opaque;
5000 f331110f bellard
    struct PollingEntry *next;
5001 f331110f bellard
} PollingEntry;
5002 f331110f bellard
5003 f331110f bellard
static PollingEntry *first_polling_entry;
5004 f331110f bellard
5005 f331110f bellard
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
5006 f331110f bellard
{
5007 f331110f bellard
    PollingEntry **ppe, *pe;
5008 f331110f bellard
    pe = qemu_mallocz(sizeof(PollingEntry));
5009 f331110f bellard
    if (!pe)
5010 f331110f bellard
        return -1;
5011 f331110f bellard
    pe->func = func;
5012 f331110f bellard
    pe->opaque = opaque;
5013 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
5014 f331110f bellard
    *ppe = pe;
5015 f331110f bellard
    return 0;
5016 f331110f bellard
}
5017 f331110f bellard
5018 f331110f bellard
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
5019 f331110f bellard
{
5020 f331110f bellard
    PollingEntry **ppe, *pe;
5021 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
5022 f331110f bellard
        pe = *ppe;
5023 f331110f bellard
        if (pe->func == func && pe->opaque == opaque) {
5024 f331110f bellard
            *ppe = pe->next;
5025 f331110f bellard
            qemu_free(pe);
5026 f331110f bellard
            break;
5027 f331110f bellard
        }
5028 f331110f bellard
    }
5029 f331110f bellard
}
5030 f331110f bellard
5031 a18e524a bellard
#ifdef _WIN32
5032 a18e524a bellard
/***********************************************************/
5033 a18e524a bellard
/* Wait objects support */
5034 a18e524a bellard
typedef struct WaitObjects {
5035 a18e524a bellard
    int num;
5036 a18e524a bellard
    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
5037 a18e524a bellard
    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
5038 a18e524a bellard
    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
5039 a18e524a bellard
} WaitObjects;
5040 a18e524a bellard
5041 a18e524a bellard
static WaitObjects wait_objects = {0};
5042 3b46e624 ths
5043 a18e524a bellard
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5044 a18e524a bellard
{
5045 a18e524a bellard
    WaitObjects *w = &wait_objects;
5046 a18e524a bellard
5047 a18e524a bellard
    if (w->num >= MAXIMUM_WAIT_OBJECTS)
5048 a18e524a bellard
        return -1;
5049 a18e524a bellard
    w->events[w->num] = handle;
5050 a18e524a bellard
    w->func[w->num] = func;
5051 a18e524a bellard
    w->opaque[w->num] = opaque;
5052 a18e524a bellard
    w->num++;
5053 a18e524a bellard
    return 0;
5054 a18e524a bellard
}
5055 a18e524a bellard
5056 a18e524a bellard
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5057 a18e524a bellard
{
5058 a18e524a bellard
    int i, found;
5059 a18e524a bellard
    WaitObjects *w = &wait_objects;
5060 a18e524a bellard
5061 a18e524a bellard
    found = 0;
5062 a18e524a bellard
    for (i = 0; i < w->num; i++) {
5063 a18e524a bellard
        if (w->events[i] == handle)
5064 a18e524a bellard
            found = 1;
5065 a18e524a bellard
        if (found) {
5066 a18e524a bellard
            w->events[i] = w->events[i + 1];
5067 a18e524a bellard
            w->func[i] = w->func[i + 1];
5068 a18e524a bellard
            w->opaque[i] = w->opaque[i + 1];
5069 3b46e624 ths
        }
5070 a18e524a bellard
    }
5071 a18e524a bellard
    if (found)
5072 a18e524a bellard
        w->num--;
5073 a18e524a bellard
}
5074 a18e524a bellard
#endif
5075 a18e524a bellard
5076 f331110f bellard
/***********************************************************/
5077 8a7ddc38 bellard
/* savevm/loadvm support */
5078 8a7ddc38 bellard
5079 faea38e7 bellard
#define IO_BUF_SIZE 32768
5080 faea38e7 bellard
5081 faea38e7 bellard
struct QEMUFile {
5082 faea38e7 bellard
    FILE *outfile;
5083 faea38e7 bellard
    BlockDriverState *bs;
5084 faea38e7 bellard
    int is_file;
5085 faea38e7 bellard
    int is_writable;
5086 faea38e7 bellard
    int64_t base_offset;
5087 faea38e7 bellard
    int64_t buf_offset; /* start of buffer when writing, end of buffer
5088 faea38e7 bellard
                           when reading */
5089 faea38e7 bellard
    int buf_index;
5090 faea38e7 bellard
    int buf_size; /* 0 when writing */
5091 faea38e7 bellard
    uint8_t buf[IO_BUF_SIZE];
5092 faea38e7 bellard
};
5093 faea38e7 bellard
5094 faea38e7 bellard
QEMUFile *qemu_fopen(const char *filename, const char *mode)
5095 faea38e7 bellard
{
5096 faea38e7 bellard
    QEMUFile *f;
5097 faea38e7 bellard
5098 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5099 faea38e7 bellard
    if (!f)
5100 faea38e7 bellard
        return NULL;
5101 faea38e7 bellard
    if (!strcmp(mode, "wb")) {
5102 faea38e7 bellard
        f->is_writable = 1;
5103 faea38e7 bellard
    } else if (!strcmp(mode, "rb")) {
5104 faea38e7 bellard
        f->is_writable = 0;
5105 faea38e7 bellard
    } else {
5106 faea38e7 bellard
        goto fail;
5107 faea38e7 bellard
    }
5108 faea38e7 bellard
    f->outfile = fopen(filename, mode);
5109 faea38e7 bellard
    if (!f->outfile)
5110 faea38e7 bellard
        goto fail;
5111 faea38e7 bellard
    f->is_file = 1;
5112 faea38e7 bellard
    return f;
5113 faea38e7 bellard
 fail:
5114 faea38e7 bellard
    if (f->outfile)
5115 faea38e7 bellard
        fclose(f->outfile);
5116 faea38e7 bellard
    qemu_free(f);
5117 faea38e7 bellard
    return NULL;
5118 faea38e7 bellard
}
5119 faea38e7 bellard
5120 faea38e7 bellard
QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
5121 faea38e7 bellard
{
5122 faea38e7 bellard
    QEMUFile *f;
5123 faea38e7 bellard
5124 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5125 faea38e7 bellard
    if (!f)
5126 faea38e7 bellard
        return NULL;
5127 faea38e7 bellard
    f->is_file = 0;
5128 faea38e7 bellard
    f->bs = bs;
5129 faea38e7 bellard
    f->is_writable = is_writable;
5130 faea38e7 bellard
    f->base_offset = offset;
5131 faea38e7 bellard
    return f;
5132 faea38e7 bellard
}
5133 faea38e7 bellard
5134 faea38e7 bellard
void qemu_fflush(QEMUFile *f)
5135 faea38e7 bellard
{
5136 faea38e7 bellard
    if (!f->is_writable)
5137 faea38e7 bellard
        return;
5138 faea38e7 bellard
    if (f->buf_index > 0) {
5139 faea38e7 bellard
        if (f->is_file) {
5140 faea38e7 bellard
            fseek(f->outfile, f->buf_offset, SEEK_SET);
5141 faea38e7 bellard
            fwrite(f->buf, 1, f->buf_index, f->outfile);
5142 faea38e7 bellard
        } else {
5143 5fafdf24 ths
            bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
5144 faea38e7 bellard
                        f->buf, f->buf_index);
5145 faea38e7 bellard
        }
5146 faea38e7 bellard
        f->buf_offset += f->buf_index;
5147 faea38e7 bellard
        f->buf_index = 0;
5148 faea38e7 bellard
    }
5149 faea38e7 bellard
}
5150 faea38e7 bellard
5151 faea38e7 bellard
static void qemu_fill_buffer(QEMUFile *f)
5152 faea38e7 bellard
{
5153 faea38e7 bellard
    int len;
5154 faea38e7 bellard
5155 faea38e7 bellard
    if (f->is_writable)
5156 faea38e7 bellard
        return;
5157 faea38e7 bellard
    if (f->is_file) {
5158 faea38e7 bellard
        fseek(f->outfile, f->buf_offset, SEEK_SET);
5159 faea38e7 bellard
        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
5160 faea38e7 bellard
        if (len < 0)
5161 faea38e7 bellard
            len = 0;
5162 faea38e7 bellard
    } else {
5163 5fafdf24 ths
        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
5164 faea38e7 bellard
                         f->buf, IO_BUF_SIZE);
5165 faea38e7 bellard
        if (len < 0)
5166 faea38e7 bellard
            len = 0;
5167 faea38e7 bellard
    }
5168 faea38e7 bellard
    f->buf_index = 0;
5169 faea38e7 bellard
    f->buf_size = len;
5170 faea38e7 bellard
    f->buf_offset += len;
5171 faea38e7 bellard
}
5172 faea38e7 bellard
5173 faea38e7 bellard
void qemu_fclose(QEMUFile *f)
5174 faea38e7 bellard
{
5175 faea38e7 bellard
    if (f->is_writable)
5176 faea38e7 bellard
        qemu_fflush(f);
5177 faea38e7 bellard
    if (f->is_file) {
5178 faea38e7 bellard
        fclose(f->outfile);
5179 faea38e7 bellard
    }
5180 faea38e7 bellard
    qemu_free(f);
5181 faea38e7 bellard
}
5182 faea38e7 bellard
5183 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
5184 b4608c04 bellard
{
5185 faea38e7 bellard
    int l;
5186 faea38e7 bellard
    while (size > 0) {
5187 faea38e7 bellard
        l = IO_BUF_SIZE - f->buf_index;
5188 faea38e7 bellard
        if (l > size)
5189 faea38e7 bellard
            l = size;
5190 faea38e7 bellard
        memcpy(f->buf + f->buf_index, buf, l);
5191 faea38e7 bellard
        f->buf_index += l;
5192 faea38e7 bellard
        buf += l;
5193 faea38e7 bellard
        size -= l;
5194 faea38e7 bellard
        if (f->buf_index >= IO_BUF_SIZE)
5195 faea38e7 bellard
            qemu_fflush(f);
5196 faea38e7 bellard
    }
5197 b4608c04 bellard
}
5198 b4608c04 bellard
5199 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
5200 b4608c04 bellard
{
5201 faea38e7 bellard
    f->buf[f->buf_index++] = v;
5202 faea38e7 bellard
    if (f->buf_index >= IO_BUF_SIZE)
5203 faea38e7 bellard
        qemu_fflush(f);
5204 faea38e7 bellard
}
5205 faea38e7 bellard
5206 faea38e7 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
5207 faea38e7 bellard
{
5208 faea38e7 bellard
    int size, l;
5209 faea38e7 bellard
5210 faea38e7 bellard
    size = size1;
5211 faea38e7 bellard
    while (size > 0) {
5212 faea38e7 bellard
        l = f->buf_size - f->buf_index;
5213 faea38e7 bellard
        if (l == 0) {
5214 faea38e7 bellard
            qemu_fill_buffer(f);
5215 faea38e7 bellard
            l = f->buf_size - f->buf_index;
5216 faea38e7 bellard
            if (l == 0)
5217 faea38e7 bellard
                break;
5218 faea38e7 bellard
        }
5219 faea38e7 bellard
        if (l > size)
5220 faea38e7 bellard
            l = size;
5221 faea38e7 bellard
        memcpy(buf, f->buf + f->buf_index, l);
5222 faea38e7 bellard
        f->buf_index += l;
5223 faea38e7 bellard
        buf += l;
5224 faea38e7 bellard
        size -= l;
5225 faea38e7 bellard
    }
5226 faea38e7 bellard
    return size1 - size;
5227 faea38e7 bellard
}
5228 faea38e7 bellard
5229 faea38e7 bellard
int qemu_get_byte(QEMUFile *f)
5230 faea38e7 bellard
{
5231 faea38e7 bellard
    if (f->buf_index >= f->buf_size) {
5232 faea38e7 bellard
        qemu_fill_buffer(f);
5233 faea38e7 bellard
        if (f->buf_index >= f->buf_size)
5234 faea38e7 bellard
            return 0;
5235 faea38e7 bellard
    }
5236 faea38e7 bellard
    return f->buf[f->buf_index++];
5237 faea38e7 bellard
}
5238 faea38e7 bellard
5239 faea38e7 bellard
int64_t qemu_ftell(QEMUFile *f)
5240 faea38e7 bellard
{
5241 faea38e7 bellard
    return f->buf_offset - f->buf_size + f->buf_index;
5242 faea38e7 bellard
}
5243 faea38e7 bellard
5244 faea38e7 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
5245 faea38e7 bellard
{
5246 faea38e7 bellard
    if (whence == SEEK_SET) {
5247 faea38e7 bellard
        /* nothing to do */
5248 faea38e7 bellard
    } else if (whence == SEEK_CUR) {
5249 faea38e7 bellard
        pos += qemu_ftell(f);
5250 faea38e7 bellard
    } else {
5251 faea38e7 bellard
        /* SEEK_END not supported */
5252 faea38e7 bellard
        return -1;
5253 faea38e7 bellard
    }
5254 faea38e7 bellard
    if (f->is_writable) {
5255 faea38e7 bellard
        qemu_fflush(f);
5256 faea38e7 bellard
        f->buf_offset = pos;
5257 faea38e7 bellard
    } else {
5258 faea38e7 bellard
        f->buf_offset = pos;
5259 faea38e7 bellard
        f->buf_index = 0;
5260 faea38e7 bellard
        f->buf_size = 0;
5261 faea38e7 bellard
    }
5262 faea38e7 bellard
    return pos;
5263 8a7ddc38 bellard
}
5264 8a7ddc38 bellard
5265 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
5266 8a7ddc38 bellard
{
5267 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5268 8a7ddc38 bellard
    qemu_put_byte(f, v);
5269 8a7ddc38 bellard
}
5270 8a7ddc38 bellard
5271 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
5272 8a7ddc38 bellard
{
5273 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
5274 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
5275 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5276 8a7ddc38 bellard
    qemu_put_byte(f, v);
5277 8a7ddc38 bellard
}
5278 8a7ddc38 bellard
5279 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
5280 8a7ddc38 bellard
{
5281 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
5282 8a7ddc38 bellard
    qemu_put_be32(f, v);
5283 8a7ddc38 bellard
}
5284 8a7ddc38 bellard
5285 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
5286 8a7ddc38 bellard
{
5287 8a7ddc38 bellard
    unsigned int v;
5288 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
5289 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5290 8a7ddc38 bellard
    return v;
5291 8a7ddc38 bellard
}
5292 8a7ddc38 bellard
5293 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
5294 8a7ddc38 bellard
{
5295 8a7ddc38 bellard
    unsigned int v;
5296 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
5297 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
5298 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
5299 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5300 8a7ddc38 bellard
    return v;
5301 8a7ddc38 bellard
}
5302 8a7ddc38 bellard
5303 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
5304 8a7ddc38 bellard
{
5305 8a7ddc38 bellard
    uint64_t v;
5306 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
5307 8a7ddc38 bellard
    v |= qemu_get_be32(f);
5308 8a7ddc38 bellard
    return v;
5309 8a7ddc38 bellard
}
5310 8a7ddc38 bellard
5311 8a7ddc38 bellard
typedef struct SaveStateEntry {
5312 8a7ddc38 bellard
    char idstr[256];
5313 8a7ddc38 bellard
    int instance_id;
5314 8a7ddc38 bellard
    int version_id;
5315 8a7ddc38 bellard
    SaveStateHandler *save_state;
5316 8a7ddc38 bellard
    LoadStateHandler *load_state;
5317 8a7ddc38 bellard
    void *opaque;
5318 8a7ddc38 bellard
    struct SaveStateEntry *next;
5319 8a7ddc38 bellard
} SaveStateEntry;
5320 b4608c04 bellard
5321 8a7ddc38 bellard
static SaveStateEntry *first_se;
5322 8a7ddc38 bellard
5323 5fafdf24 ths
int register_savevm(const char *idstr,
5324 5fafdf24 ths
                    int instance_id,
5325 8a7ddc38 bellard
                    int version_id,
5326 8a7ddc38 bellard
                    SaveStateHandler *save_state,
5327 8a7ddc38 bellard
                    LoadStateHandler *load_state,
5328 8a7ddc38 bellard
                    void *opaque)
5329 8a7ddc38 bellard
{
5330 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
5331 8a7ddc38 bellard
5332 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
5333 8a7ddc38 bellard
    if (!se)
5334 8a7ddc38 bellard
        return -1;
5335 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
5336 8a7ddc38 bellard
    se->instance_id = instance_id;
5337 8a7ddc38 bellard
    se->version_id = version_id;
5338 8a7ddc38 bellard
    se->save_state = save_state;
5339 8a7ddc38 bellard
    se->load_state = load_state;
5340 8a7ddc38 bellard
    se->opaque = opaque;
5341 8a7ddc38 bellard
    se->next = NULL;
5342 8a7ddc38 bellard
5343 8a7ddc38 bellard
    /* add at the end of list */
5344 8a7ddc38 bellard
    pse = &first_se;
5345 8a7ddc38 bellard
    while (*pse != NULL)
5346 8a7ddc38 bellard
        pse = &(*pse)->next;
5347 8a7ddc38 bellard
    *pse = se;
5348 8a7ddc38 bellard
    return 0;
5349 8a7ddc38 bellard
}
5350 8a7ddc38 bellard
5351 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
5352 faea38e7 bellard
#define QEMU_VM_FILE_VERSION 0x00000002
5353 8a7ddc38 bellard
5354 faea38e7 bellard
int qemu_savevm_state(QEMUFile *f)
5355 8a7ddc38 bellard
{
5356 8a7ddc38 bellard
    SaveStateEntry *se;
5357 faea38e7 bellard
    int len, ret;
5358 faea38e7 bellard
    int64_t cur_pos, len_pos, total_len_pos;
5359 313aa567 bellard
5360 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
5361 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
5362 faea38e7 bellard
    total_len_pos = qemu_ftell(f);
5363 faea38e7 bellard
    qemu_put_be64(f, 0); /* total size */
5364 8a7ddc38 bellard
5365 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5366 8a7ddc38 bellard
        /* ID string */
5367 8a7ddc38 bellard
        len = strlen(se->idstr);
5368 8a7ddc38 bellard
        qemu_put_byte(f, len);
5369 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
5370 8a7ddc38 bellard
5371 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
5372 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
5373 8a7ddc38 bellard
5374 8a7ddc38 bellard
        /* record size: filled later */
5375 faea38e7 bellard
        len_pos = qemu_ftell(f);
5376 8a7ddc38 bellard
        qemu_put_be32(f, 0);
5377 3b46e624 ths
5378 8a7ddc38 bellard
        se->save_state(f, se->opaque);
5379 8a7ddc38 bellard
5380 8a7ddc38 bellard
        /* fill record size */
5381 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5382 faea38e7 bellard
        len = cur_pos - len_pos - 4;
5383 faea38e7 bellard
        qemu_fseek(f, len_pos, SEEK_SET);
5384 8a7ddc38 bellard
        qemu_put_be32(f, len);
5385 faea38e7 bellard
        qemu_fseek(f, cur_pos, SEEK_SET);
5386 8a7ddc38 bellard
    }
5387 faea38e7 bellard
    cur_pos = qemu_ftell(f);
5388 faea38e7 bellard
    qemu_fseek(f, total_len_pos, SEEK_SET);
5389 faea38e7 bellard
    qemu_put_be64(f, cur_pos - total_len_pos - 8);
5390 faea38e7 bellard
    qemu_fseek(f, cur_pos, SEEK_SET);
5391 8a7ddc38 bellard
5392 8a7ddc38 bellard
    ret = 0;
5393 8a7ddc38 bellard
    return ret;
5394 8a7ddc38 bellard
}
5395 8a7ddc38 bellard
5396 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
5397 8a7ddc38 bellard
{
5398 8a7ddc38 bellard
    SaveStateEntry *se;
5399 8a7ddc38 bellard
5400 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5401 5fafdf24 ths
        if (!strcmp(se->idstr, idstr) &&
5402 8a7ddc38 bellard
            instance_id == se->instance_id)
5403 8a7ddc38 bellard
            return se;
5404 8a7ddc38 bellard
    }
5405 8a7ddc38 bellard
    return NULL;
5406 8a7ddc38 bellard
}
5407 8a7ddc38 bellard
5408 faea38e7 bellard
int qemu_loadvm_state(QEMUFile *f)
5409 8a7ddc38 bellard
{
5410 8a7ddc38 bellard
    SaveStateEntry *se;
5411 faea38e7 bellard
    int len, ret, instance_id, record_len, version_id;
5412 faea38e7 bellard
    int64_t total_len, end_pos, cur_pos;
5413 8a7ddc38 bellard
    unsigned int v;
5414 8a7ddc38 bellard
    char idstr[256];
5415 3b46e624 ths
5416 8a7ddc38 bellard
    v = qemu_get_be32(f);
5417 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
5418 8a7ddc38 bellard
        goto fail;
5419 8a7ddc38 bellard
    v = qemu_get_be32(f);
5420 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
5421 8a7ddc38 bellard
    fail:
5422 8a7ddc38 bellard
        ret = -1;
5423 8a7ddc38 bellard
        goto the_end;
5424 8a7ddc38 bellard
    }
5425 faea38e7 bellard
    total_len = qemu_get_be64(f);
5426 faea38e7 bellard
    end_pos = total_len + qemu_ftell(f);
5427 b4608c04 bellard
    for(;;) {
5428 faea38e7 bellard
        if (qemu_ftell(f) >= end_pos)
5429 cd4c3e88 bellard
            break;
5430 faea38e7 bellard
        len = qemu_get_byte(f);
5431 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
5432 8a7ddc38 bellard
        idstr[len] = '\0';
5433 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
5434 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
5435 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
5436 8a7ddc38 bellard
#if 0
5437 5fafdf24 ths
        printf("idstr=%s instance=0x%x version=%d len=%d\n",
5438 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
5439 8a7ddc38 bellard
#endif
5440 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5441 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
5442 8a7ddc38 bellard
        if (!se) {
5443 5fafdf24 ths
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
5444 8a7ddc38 bellard
                    instance_id, idstr);
5445 8a7ddc38 bellard
        } else {
5446 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
5447 8a7ddc38 bellard
            if (ret < 0) {
5448 5fafdf24 ths
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
5449 8a7ddc38 bellard
                        instance_id, idstr);
5450 8a7ddc38 bellard
            }
5451 34865134 bellard
        }
5452 8a7ddc38 bellard
        /* always seek to exact end of record */
5453 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
5454 8a7ddc38 bellard
    }
5455 8a7ddc38 bellard
    ret = 0;
5456 8a7ddc38 bellard
 the_end:
5457 faea38e7 bellard
    return ret;
5458 faea38e7 bellard
}
5459 faea38e7 bellard
5460 faea38e7 bellard
/* device can contain snapshots */
5461 faea38e7 bellard
static int bdrv_can_snapshot(BlockDriverState *bs)
5462 faea38e7 bellard
{
5463 faea38e7 bellard
    return (bs &&
5464 faea38e7 bellard
            !bdrv_is_removable(bs) &&
5465 faea38e7 bellard
            !bdrv_is_read_only(bs));
5466 faea38e7 bellard
}
5467 faea38e7 bellard
5468 faea38e7 bellard
/* device must be snapshots in order to have a reliable snapshot */
5469 faea38e7 bellard
static int bdrv_has_snapshot(BlockDriverState *bs)
5470 faea38e7 bellard
{
5471 faea38e7 bellard
    return (bs &&
5472 faea38e7 bellard
            !bdrv_is_removable(bs) &&
5473 faea38e7 bellard
            !bdrv_is_read_only(bs));
5474 faea38e7 bellard
}
5475 faea38e7 bellard
5476 faea38e7 bellard
static BlockDriverState *get_bs_snapshots(void)
5477 faea38e7 bellard
{
5478 faea38e7 bellard
    BlockDriverState *bs;
5479 faea38e7 bellard
    int i;
5480 faea38e7 bellard
5481 faea38e7 bellard
    if (bs_snapshots)
5482 faea38e7 bellard
        return bs_snapshots;
5483 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5484 faea38e7 bellard
        bs = bs_table[i];
5485 faea38e7 bellard
        if (bdrv_can_snapshot(bs))
5486 faea38e7 bellard
            goto ok;
5487 faea38e7 bellard
    }
5488 faea38e7 bellard
    return NULL;
5489 faea38e7 bellard
 ok:
5490 faea38e7 bellard
    bs_snapshots = bs;
5491 faea38e7 bellard
    return bs;
5492 faea38e7 bellard
}
5493 faea38e7 bellard
5494 faea38e7 bellard
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
5495 faea38e7 bellard
                              const char *name)
5496 faea38e7 bellard
{
5497 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5498 faea38e7 bellard
    int nb_sns, i, ret;
5499 3b46e624 ths
5500 faea38e7 bellard
    ret = -ENOENT;
5501 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5502 faea38e7 bellard
    if (nb_sns < 0)
5503 faea38e7 bellard
        return ret;
5504 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5505 faea38e7 bellard
        sn = &sn_tab[i];
5506 faea38e7 bellard
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
5507 faea38e7 bellard
            *sn_info = *sn;
5508 faea38e7 bellard
            ret = 0;
5509 faea38e7 bellard
            break;
5510 faea38e7 bellard
        }
5511 faea38e7 bellard
    }
5512 faea38e7 bellard
    qemu_free(sn_tab);
5513 faea38e7 bellard
    return ret;
5514 faea38e7 bellard
}
5515 faea38e7 bellard
5516 faea38e7 bellard
void do_savevm(const char *name)
5517 faea38e7 bellard
{
5518 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5519 faea38e7 bellard
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
5520 faea38e7 bellard
    int must_delete, ret, i;
5521 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5522 faea38e7 bellard
    QEMUFile *f;
5523 faea38e7 bellard
    int saved_vm_running;
5524 4c279bdf bellard
#ifdef _WIN32
5525 4c279bdf bellard
    struct _timeb tb;
5526 4c279bdf bellard
#else
5527 faea38e7 bellard
    struct timeval tv;
5528 4c279bdf bellard
#endif
5529 faea38e7 bellard
5530 faea38e7 bellard
    bs = get_bs_snapshots();
5531 faea38e7 bellard
    if (!bs) {
5532 faea38e7 bellard
        term_printf("No block device can accept snapshots\n");
5533 faea38e7 bellard
        return;
5534 faea38e7 bellard
    }
5535 faea38e7 bellard
5536 6192bc37 pbrook
    /* ??? Should this occur after vm_stop?  */
5537 6192bc37 pbrook
    qemu_aio_flush();
5538 6192bc37 pbrook
5539 faea38e7 bellard
    saved_vm_running = vm_running;
5540 faea38e7 bellard
    vm_stop(0);
5541 3b46e624 ths
5542 faea38e7 bellard
    must_delete = 0;
5543 faea38e7 bellard
    if (name) {
5544 faea38e7 bellard
        ret = bdrv_snapshot_find(bs, old_sn, name);
5545 faea38e7 bellard
        if (ret >= 0) {
5546 faea38e7 bellard
            must_delete = 1;
5547 faea38e7 bellard
        }
5548 faea38e7 bellard
    }
5549 faea38e7 bellard
    memset(sn, 0, sizeof(*sn));
5550 faea38e7 bellard
    if (must_delete) {
5551 faea38e7 bellard
        pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
5552 faea38e7 bellard
        pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
5553 faea38e7 bellard
    } else {
5554 faea38e7 bellard
        if (name)
5555 faea38e7 bellard
            pstrcpy(sn->name, sizeof(sn->name), name);
5556 faea38e7 bellard
    }
5557 faea38e7 bellard
5558 faea38e7 bellard
    /* fill auxiliary fields */
5559 4c279bdf bellard
#ifdef _WIN32
5560 4c279bdf bellard
    _ftime(&tb);
5561 4c279bdf bellard
    sn->date_sec = tb.time;
5562 4c279bdf bellard
    sn->date_nsec = tb.millitm * 1000000;
5563 4c279bdf bellard
#else
5564 faea38e7 bellard
    gettimeofday(&tv, NULL);
5565 faea38e7 bellard
    sn->date_sec = tv.tv_sec;
5566 faea38e7 bellard
    sn->date_nsec = tv.tv_usec * 1000;
5567 4c279bdf bellard
#endif
5568 faea38e7 bellard
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
5569 3b46e624 ths
5570 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5571 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5572 faea38e7 bellard
                    bdrv_get_device_name(bs));
5573 faea38e7 bellard
        goto the_end;
5574 faea38e7 bellard
    }
5575 3b46e624 ths
5576 faea38e7 bellard
    /* save the VM state */
5577 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
5578 faea38e7 bellard
    if (!f) {
5579 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5580 faea38e7 bellard
        goto the_end;
5581 faea38e7 bellard
    }
5582 faea38e7 bellard
    ret = qemu_savevm_state(f);
5583 faea38e7 bellard
    sn->vm_state_size = qemu_ftell(f);
5584 faea38e7 bellard
    qemu_fclose(f);
5585 faea38e7 bellard
    if (ret < 0) {
5586 faea38e7 bellard
        term_printf("Error %d while writing VM\n", ret);
5587 faea38e7 bellard
        goto the_end;
5588 faea38e7 bellard
    }
5589 3b46e624 ths
5590 faea38e7 bellard
    /* create the snapshots */
5591 faea38e7 bellard
5592 faea38e7 bellard
    for(i = 0; i < MAX_DISKS; i++) {
5593 faea38e7 bellard
        bs1 = bs_table[i];
5594 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5595 faea38e7 bellard
            if (must_delete) {
5596 faea38e7 bellard
                ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
5597 faea38e7 bellard
                if (ret < 0) {
5598 faea38e7 bellard
                    term_printf("Error while deleting snapshot on '%s'\n",
5599 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5600 faea38e7 bellard
                }
5601 faea38e7 bellard
            }
5602 faea38e7 bellard
            ret = bdrv_snapshot_create(bs1, sn);
5603 faea38e7 bellard
            if (ret < 0) {
5604 faea38e7 bellard
                term_printf("Error while creating snapshot on '%s'\n",
5605 faea38e7 bellard
                            bdrv_get_device_name(bs1));
5606 faea38e7 bellard
            }
5607 faea38e7 bellard
        }
5608 faea38e7 bellard
    }
5609 faea38e7 bellard
5610 faea38e7 bellard
 the_end:
5611 8a7ddc38 bellard
    if (saved_vm_running)
5612 8a7ddc38 bellard
        vm_start();
5613 faea38e7 bellard
}
5614 faea38e7 bellard
5615 faea38e7 bellard
void do_loadvm(const char *name)
5616 faea38e7 bellard
{
5617 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5618 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5619 faea38e7 bellard
    QEMUFile *f;
5620 faea38e7 bellard
    int i, ret;
5621 faea38e7 bellard
    int saved_vm_running;
5622 faea38e7 bellard
5623 faea38e7 bellard
    bs = get_bs_snapshots();
5624 faea38e7 bellard
    if (!bs) {
5625 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5626 faea38e7 bellard
        return;
5627 faea38e7 bellard
    }
5628 3b46e624 ths
5629 6192bc37 pbrook
    /* Flush all IO requests so they don't interfere with the new state.  */
5630 6192bc37 pbrook
    qemu_aio_flush();
5631 6192bc37 pbrook
5632 faea38e7 bellard
    saved_vm_running = vm_running;
5633 faea38e7 bellard
    vm_stop(0);
5634 faea38e7 bellard
5635 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5636 faea38e7 bellard
        bs1 = bs_table[i];
5637 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5638 faea38e7 bellard
            ret = bdrv_snapshot_goto(bs1, name);
5639 faea38e7 bellard
            if (ret < 0) {
5640 faea38e7 bellard
                if (bs != bs1)
5641 faea38e7 bellard
                    term_printf("Warning: ");
5642 faea38e7 bellard
                switch(ret) {
5643 faea38e7 bellard
                case -ENOTSUP:
5644 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5645 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5646 faea38e7 bellard
                    break;
5647 faea38e7 bellard
                case -ENOENT:
5648 faea38e7 bellard
                    term_printf("Could not find snapshot '%s' on device '%s'\n",
5649 faea38e7 bellard
                                name, bdrv_get_device_name(bs1));
5650 faea38e7 bellard
                    break;
5651 faea38e7 bellard
                default:
5652 faea38e7 bellard
                    term_printf("Error %d while activating snapshot on '%s'\n",
5653 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5654 faea38e7 bellard
                    break;
5655 faea38e7 bellard
                }
5656 faea38e7 bellard
                /* fatal on snapshot block device */
5657 faea38e7 bellard
                if (bs == bs1)
5658 faea38e7 bellard
                    goto the_end;
5659 faea38e7 bellard
            }
5660 faea38e7 bellard
        }
5661 faea38e7 bellard
    }
5662 faea38e7 bellard
5663 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5664 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5665 faea38e7 bellard
                    bdrv_get_device_name(bs));
5666 faea38e7 bellard
        return;
5667 faea38e7 bellard
    }
5668 3b46e624 ths
5669 faea38e7 bellard
    /* restore the VM state */
5670 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
5671 faea38e7 bellard
    if (!f) {
5672 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5673 faea38e7 bellard
        goto the_end;
5674 faea38e7 bellard
    }
5675 faea38e7 bellard
    ret = qemu_loadvm_state(f);
5676 faea38e7 bellard
    qemu_fclose(f);
5677 faea38e7 bellard
    if (ret < 0) {
5678 faea38e7 bellard
        term_printf("Error %d while loading VM state\n", ret);
5679 faea38e7 bellard
    }
5680 faea38e7 bellard
 the_end:
5681 faea38e7 bellard
    if (saved_vm_running)
5682 faea38e7 bellard
        vm_start();
5683 faea38e7 bellard
}
5684 faea38e7 bellard
5685 faea38e7 bellard
void do_delvm(const char *name)
5686 faea38e7 bellard
{
5687 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5688 faea38e7 bellard
    int i, ret;
5689 faea38e7 bellard
5690 faea38e7 bellard
    bs = get_bs_snapshots();
5691 faea38e7 bellard
    if (!bs) {
5692 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5693 faea38e7 bellard
        return;
5694 faea38e7 bellard
    }
5695 3b46e624 ths
5696 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5697 faea38e7 bellard
        bs1 = bs_table[i];
5698 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5699 faea38e7 bellard
            ret = bdrv_snapshot_delete(bs1, name);
5700 faea38e7 bellard
            if (ret < 0) {
5701 faea38e7 bellard
                if (ret == -ENOTSUP)
5702 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5703 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5704 faea38e7 bellard
                else
5705 faea38e7 bellard
                    term_printf("Error %d while deleting snapshot on '%s'\n",
5706 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5707 faea38e7 bellard
            }
5708 faea38e7 bellard
        }
5709 faea38e7 bellard
    }
5710 faea38e7 bellard
}
5711 faea38e7 bellard
5712 faea38e7 bellard
void do_info_snapshots(void)
5713 faea38e7 bellard
{
5714 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5715 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5716 faea38e7 bellard
    int nb_sns, i;
5717 faea38e7 bellard
    char buf[256];
5718 faea38e7 bellard
5719 faea38e7 bellard
    bs = get_bs_snapshots();
5720 faea38e7 bellard
    if (!bs) {
5721 faea38e7 bellard
        term_printf("No available block device supports snapshots\n");
5722 faea38e7 bellard
        return;
5723 faea38e7 bellard
    }
5724 faea38e7 bellard
    term_printf("Snapshot devices:");
5725 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5726 faea38e7 bellard
        bs1 = bs_table[i];
5727 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5728 faea38e7 bellard
            if (bs == bs1)
5729 faea38e7 bellard
                term_printf(" %s", bdrv_get_device_name(bs1));
5730 faea38e7 bellard
        }
5731 faea38e7 bellard
    }
5732 faea38e7 bellard
    term_printf("\n");
5733 faea38e7 bellard
5734 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5735 faea38e7 bellard
    if (nb_sns < 0) {
5736 faea38e7 bellard
        term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
5737 faea38e7 bellard
        return;
5738 faea38e7 bellard
    }
5739 faea38e7 bellard
    term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
5740 faea38e7 bellard
    term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
5741 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5742 faea38e7 bellard
        sn = &sn_tab[i];
5743 faea38e7 bellard
        term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
5744 faea38e7 bellard
    }
5745 faea38e7 bellard
    qemu_free(sn_tab);
5746 8a7ddc38 bellard
}
5747 8a7ddc38 bellard
5748 8a7ddc38 bellard
/***********************************************************/
5749 8a7ddc38 bellard
/* cpu save/restore */
5750 8a7ddc38 bellard
5751 8a7ddc38 bellard
#if defined(TARGET_I386)
5752 8a7ddc38 bellard
5753 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
5754 8a7ddc38 bellard
{
5755 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
5756 20f32282 bellard
    qemu_put_betl(f, dt->base);
5757 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
5758 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
5759 8a7ddc38 bellard
}
5760 8a7ddc38 bellard
5761 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
5762 8a7ddc38 bellard
{
5763 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
5764 20f32282 bellard
    dt->base = qemu_get_betl(f);
5765 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
5766 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
5767 8a7ddc38 bellard
}
5768 8a7ddc38 bellard
5769 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
5770 8a7ddc38 bellard
{
5771 8a7ddc38 bellard
    CPUState *env = opaque;
5772 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
5773 8a7ddc38 bellard
    uint32_t hflags;
5774 8a7ddc38 bellard
    int i;
5775 3b46e624 ths
5776 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5777 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
5778 20f32282 bellard
    qemu_put_betls(f, &env->eip);
5779 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
5780 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
5781 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
5782 3b46e624 ths
5783 8a7ddc38 bellard
    /* FPU */
5784 8a7ddc38 bellard
    fpuc = env->fpuc;
5785 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
5786 8a7ddc38 bellard
    fptag = 0;
5787 664e0f19 bellard
    for(i = 0; i < 8; i++) {
5788 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
5789 8a7ddc38 bellard
    }
5790 3b46e624 ths
5791 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
5792 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
5793 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
5794 8a7ddc38 bellard
5795 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5796 664e0f19 bellard
    fpregs_format = 0;
5797 664e0f19 bellard
#else
5798 664e0f19 bellard
    fpregs_format = 1;
5799 664e0f19 bellard
#endif
5800 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
5801 3b46e624 ths
5802 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5803 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5804 8636b5d8 bellard
        {
5805 8636b5d8 bellard
            uint64_t mant;
5806 8636b5d8 bellard
            uint16_t exp;
5807 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
5808 8636b5d8 bellard
               contains the MMX register */
5809 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
5810 8636b5d8 bellard
            qemu_put_be64(f, mant);
5811 8636b5d8 bellard
            qemu_put_be16(f, exp);
5812 8636b5d8 bellard
        }
5813 664e0f19 bellard
#else
5814 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
5815 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
5816 664e0f19 bellard
           problems if the image is restored on a CPU where long
5817 664e0f19 bellard
           doubles are used instead. */
5818 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
5819 664e0f19 bellard
#endif
5820 8a7ddc38 bellard
    }
5821 8a7ddc38 bellard
5822 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5823 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
5824 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
5825 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
5826 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
5827 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
5828 3b46e624 ths
5829 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
5830 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
5831 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
5832 3b46e624 ths
5833 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
5834 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
5835 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
5836 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
5837 3b46e624 ths
5838 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5839 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
5840 8a7ddc38 bellard
5841 8a7ddc38 bellard
    /* MMU */
5842 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
5843 02536f8b bellard
5844 664e0f19 bellard
    /* XMM */
5845 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
5846 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5847 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5848 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5849 02536f8b bellard
    }
5850 02536f8b bellard
5851 664e0f19 bellard
#ifdef TARGET_X86_64
5852 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
5853 02536f8b bellard
    qemu_put_be64s(f, &env->star);
5854 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
5855 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
5856 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
5857 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
5858 02536f8b bellard
#endif
5859 3b21e03e bellard
    qemu_put_be32s(f, &env->smbase);
5860 8a7ddc38 bellard
}
5861 8a7ddc38 bellard
5862 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
5863 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
5864 664e0f19 bellard
union x86_longdouble {
5865 664e0f19 bellard
    uint64_t mant;
5866 664e0f19 bellard
    uint16_t exp;
5867 664e0f19 bellard
};
5868 664e0f19 bellard
5869 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
5870 664e0f19 bellard
#define EXPBIAS1 1023
5871 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
5872 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
5873 664e0f19 bellard
5874 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
5875 664e0f19 bellard
{
5876 664e0f19 bellard
    int e;
5877 664e0f19 bellard
    /* mantissa */
5878 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
5879 664e0f19 bellard
    /* exponent + sign */
5880 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
5881 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
5882 664e0f19 bellard
    p->exp = e;
5883 664e0f19 bellard
}
5884 8636b5d8 bellard
#endif
5885 664e0f19 bellard
5886 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5887 8a7ddc38 bellard
{
5888 8a7ddc38 bellard
    CPUState *env = opaque;
5889 664e0f19 bellard
    int i, guess_mmx;
5890 8a7ddc38 bellard
    uint32_t hflags;
5891 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
5892 8a7ddc38 bellard
5893 3b21e03e bellard
    if (version_id != 3 && version_id != 4)
5894 8a7ddc38 bellard
        return -EINVAL;
5895 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5896 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
5897 20f32282 bellard
    qemu_get_betls(f, &env->eip);
5898 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
5899 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
5900 8a7ddc38 bellard
5901 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
5902 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
5903 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
5904 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
5905 3b46e624 ths
5906 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
5907 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
5908 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
5909 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
5910 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5911 8a7ddc38 bellard
        uint64_t mant;
5912 8a7ddc38 bellard
        uint16_t exp;
5913 3b46e624 ths
5914 664e0f19 bellard
        switch(fpregs_format) {
5915 664e0f19 bellard
        case 0:
5916 664e0f19 bellard
            mant = qemu_get_be64(f);
5917 664e0f19 bellard
            exp = qemu_get_be16(f);
5918 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5919 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
5920 664e0f19 bellard
#else
5921 664e0f19 bellard
            /* difficult case */
5922 664e0f19 bellard
            if (guess_mmx)
5923 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
5924 664e0f19 bellard
            else
5925 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
5926 664e0f19 bellard
#endif
5927 664e0f19 bellard
            break;
5928 664e0f19 bellard
        case 1:
5929 664e0f19 bellard
            mant = qemu_get_be64(f);
5930 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5931 8636b5d8 bellard
            {
5932 8636b5d8 bellard
                union x86_longdouble *p;
5933 8636b5d8 bellard
                /* difficult case */
5934 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
5935 8636b5d8 bellard
                if (guess_mmx) {
5936 8636b5d8 bellard
                    p->mant = mant;
5937 8636b5d8 bellard
                    p->exp = 0xffff;
5938 8636b5d8 bellard
                } else {
5939 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
5940 8636b5d8 bellard
                }
5941 664e0f19 bellard
            }
5942 664e0f19 bellard
#else
5943 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
5944 3b46e624 ths
#endif
5945 664e0f19 bellard
            break;
5946 664e0f19 bellard
        default:
5947 664e0f19 bellard
            return -EINVAL;
5948 664e0f19 bellard
        }
5949 8a7ddc38 bellard
    }
5950 8a7ddc38 bellard
5951 8a7ddc38 bellard
    env->fpuc = fpuc;
5952 7a0e1f41 bellard
    /* XXX: restore FPU round state */
5953 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
5954 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
5955 664e0f19 bellard
    fptag ^= 0xff;
5956 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5957 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
5958 8a7ddc38 bellard
    }
5959 3b46e624 ths
5960 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5961 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
5962 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
5963 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
5964 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
5965 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
5966 3b46e624 ths
5967 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
5968 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
5969 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
5970 3b46e624 ths
5971 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
5972 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
5973 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
5974 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
5975 3b46e624 ths
5976 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5977 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
5978 8a7ddc38 bellard
5979 8a7ddc38 bellard
    /* MMU */
5980 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
5981 8a7ddc38 bellard
5982 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
5983 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5984 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5985 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5986 02536f8b bellard
    }
5987 02536f8b bellard
5988 664e0f19 bellard
#ifdef TARGET_X86_64
5989 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
5990 02536f8b bellard
    qemu_get_be64s(f, &env->star);
5991 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
5992 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
5993 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
5994 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
5995 02536f8b bellard
#endif
5996 5fafdf24 ths
    if (version_id >= 4)
5997 3b21e03e bellard
        qemu_get_be32s(f, &env->smbase);
5998 02536f8b bellard
5999 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
6000 8a7ddc38 bellard
    env->hflags = hflags;
6001 8a7ddc38 bellard
    tlb_flush(env, 1);
6002 8a7ddc38 bellard
    return 0;
6003 8a7ddc38 bellard
}
6004 8a7ddc38 bellard
6005 a541f297 bellard
#elif defined(TARGET_PPC)
6006 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
6007 a541f297 bellard
{
6008 a541f297 bellard
}
6009 a541f297 bellard
6010 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6011 a541f297 bellard
{
6012 a541f297 bellard
    return 0;
6013 a541f297 bellard
}
6014 6af0bf9c bellard
6015 6af0bf9c bellard
#elif defined(TARGET_MIPS)
6016 6af0bf9c bellard
void cpu_save(QEMUFile *f, void *opaque)
6017 6af0bf9c bellard
{
6018 6af0bf9c bellard
}
6019 6af0bf9c bellard
6020 6af0bf9c bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6021 6af0bf9c bellard
{
6022 6af0bf9c bellard
    return 0;
6023 6af0bf9c bellard
}
6024 6af0bf9c bellard
6025 e95c8d51 bellard
#elif defined(TARGET_SPARC)
6026 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
6027 e95c8d51 bellard
{
6028 e80cfcfc bellard
    CPUState *env = opaque;
6029 e80cfcfc bellard
    int i;
6030 e80cfcfc bellard
    uint32_t tmp;
6031 e80cfcfc bellard
6032 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6033 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
6034 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6035 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
6036 e80cfcfc bellard
6037 e80cfcfc bellard
    /* FPU */
6038 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6039 4fa5d772 bellard
        union {
6040 1bdb68ea bellard
            float32 f;
6041 1bdb68ea bellard
            uint32_t i;
6042 4fa5d772 bellard
        } u;
6043 4fa5d772 bellard
        u.f = env->fpr[i];
6044 1bdb68ea bellard
        qemu_put_be32(f, u.i);
6045 4fa5d772 bellard
    }
6046 4fa5d772 bellard
6047 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
6048 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
6049 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
6050 e80cfcfc bellard
    tmp = GET_PSR(env);
6051 4fa5d772 bellard
    qemu_put_be32(f, tmp);
6052 3475187d bellard
    qemu_put_betls(f, &env->fsr);
6053 3475187d bellard
    qemu_put_betls(f, &env->tbr);
6054 3475187d bellard
#ifndef TARGET_SPARC64
6055 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
6056 e80cfcfc bellard
    /* MMU */
6057 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6058 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
6059 3475187d bellard
#endif
6060 e95c8d51 bellard
}
6061 e95c8d51 bellard
6062 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6063 e95c8d51 bellard
{
6064 e80cfcfc bellard
    CPUState *env = opaque;
6065 e80cfcfc bellard
    int i;
6066 e80cfcfc bellard
    uint32_t tmp;
6067 e80cfcfc bellard
6068 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6069 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
6070 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6071 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
6072 e80cfcfc bellard
6073 e80cfcfc bellard
    /* FPU */
6074 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6075 4fa5d772 bellard
        union {
6076 1bdb68ea bellard
            float32 f;
6077 1bdb68ea bellard
            uint32_t i;
6078 4fa5d772 bellard
        } u;
6079 1bdb68ea bellard
        u.i = qemu_get_be32(f);
6080 4fa5d772 bellard
        env->fpr[i] = u.f;
6081 4fa5d772 bellard
    }
6082 4fa5d772 bellard
6083 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
6084 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
6085 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
6086 4fa5d772 bellard
    tmp = qemu_get_be32(f);
6087 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
6088 4fa5d772 bellard
                     correctly updated */
6089 e80cfcfc bellard
    PUT_PSR(env, tmp);
6090 3475187d bellard
    qemu_get_betls(f, &env->fsr);
6091 3475187d bellard
    qemu_get_betls(f, &env->tbr);
6092 3475187d bellard
#ifndef TARGET_SPARC64
6093 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
6094 e80cfcfc bellard
    /* MMU */
6095 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6096 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
6097 3475187d bellard
#endif
6098 e80cfcfc bellard
    tlb_flush(env, 1);
6099 e95c8d51 bellard
    return 0;
6100 e95c8d51 bellard
}
6101 b5ff1b31 bellard
6102 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6103 b5ff1b31 bellard
6104 b5ff1b31 bellard
void cpu_save(QEMUFile *f, void *opaque)
6105 b5ff1b31 bellard
{
6106 aa941b94 balrog
    int i;
6107 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6108 aa941b94 balrog
6109 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6110 aa941b94 balrog
        qemu_put_be32(f, env->regs[i]);
6111 aa941b94 balrog
    }
6112 aa941b94 balrog
    qemu_put_be32(f, cpsr_read(env));
6113 aa941b94 balrog
    qemu_put_be32(f, env->spsr);
6114 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6115 aa941b94 balrog
        qemu_put_be32(f, env->banked_spsr[i]);
6116 aa941b94 balrog
        qemu_put_be32(f, env->banked_r13[i]);
6117 aa941b94 balrog
        qemu_put_be32(f, env->banked_r14[i]);
6118 aa941b94 balrog
    }
6119 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6120 aa941b94 balrog
        qemu_put_be32(f, env->usr_regs[i]);
6121 aa941b94 balrog
        qemu_put_be32(f, env->fiq_regs[i]);
6122 aa941b94 balrog
    }
6123 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cpuid);
6124 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cachetype);
6125 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_sys);
6126 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_coproc);
6127 610c3c8a balrog
    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
6128 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_base);
6129 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_data);
6130 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_insn);
6131 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c3);
6132 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_insn);
6133 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_data);
6134 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6135 aa941b94 balrog
        qemu_put_be32(f, env->cp15.c6_region[i]);
6136 aa941b94 balrog
    }
6137 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_insn);
6138 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_data);
6139 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_insn);
6140 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_data);
6141 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_fcse);
6142 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_context);
6143 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c15_cpar);
6144 aa941b94 balrog
6145 aa941b94 balrog
    qemu_put_be32(f, env->features);
6146 aa941b94 balrog
6147 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6148 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6149 aa941b94 balrog
            CPU_DoubleU u;
6150 aa941b94 balrog
            u.d = env->vfp.regs[i];
6151 aa941b94 balrog
            qemu_put_be32(f, u.l.upper);
6152 aa941b94 balrog
            qemu_put_be32(f, u.l.lower);
6153 aa941b94 balrog
        }
6154 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6155 aa941b94 balrog
            qemu_put_be32(f, env->vfp.xregs[i]);
6156 aa941b94 balrog
        }
6157 aa941b94 balrog
6158 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6159 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_len);
6160 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_stride);
6161 aa941b94 balrog
    }
6162 aa941b94 balrog
6163 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6164 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6165 aa941b94 balrog
            qemu_put_be64(f, env->iwmmxt.regs[i]);
6166 aa941b94 balrog
        }
6167 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6168 aa941b94 balrog
            qemu_put_be32(f, env->iwmmxt.cregs[i]);
6169 aa941b94 balrog
        }
6170 aa941b94 balrog
    }
6171 b5ff1b31 bellard
}
6172 b5ff1b31 bellard
6173 b5ff1b31 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6174 b5ff1b31 bellard
{
6175 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6176 aa941b94 balrog
    int i;
6177 aa941b94 balrog
6178 aa941b94 balrog
    if (version_id != 0)
6179 aa941b94 balrog
        return -EINVAL;
6180 aa941b94 balrog
6181 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6182 aa941b94 balrog
        env->regs[i] = qemu_get_be32(f);
6183 aa941b94 balrog
    }
6184 aa941b94 balrog
    cpsr_write(env, qemu_get_be32(f), 0xffffffff);
6185 aa941b94 balrog
    env->spsr = qemu_get_be32(f);
6186 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6187 aa941b94 balrog
        env->banked_spsr[i] = qemu_get_be32(f);
6188 aa941b94 balrog
        env->banked_r13[i] = qemu_get_be32(f);
6189 aa941b94 balrog
        env->banked_r14[i] = qemu_get_be32(f);
6190 aa941b94 balrog
    }
6191 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6192 aa941b94 balrog
        env->usr_regs[i] = qemu_get_be32(f);
6193 aa941b94 balrog
        env->fiq_regs[i] = qemu_get_be32(f);
6194 aa941b94 balrog
    }
6195 aa941b94 balrog
    env->cp15.c0_cpuid = qemu_get_be32(f);
6196 aa941b94 balrog
    env->cp15.c0_cachetype = qemu_get_be32(f);
6197 aa941b94 balrog
    env->cp15.c1_sys = qemu_get_be32(f);
6198 aa941b94 balrog
    env->cp15.c1_coproc = qemu_get_be32(f);
6199 610c3c8a balrog
    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
6200 aa941b94 balrog
    env->cp15.c2_base = qemu_get_be32(f);
6201 aa941b94 balrog
    env->cp15.c2_data = qemu_get_be32(f);
6202 aa941b94 balrog
    env->cp15.c2_insn = qemu_get_be32(f);
6203 aa941b94 balrog
    env->cp15.c3 = qemu_get_be32(f);
6204 aa941b94 balrog
    env->cp15.c5_insn = qemu_get_be32(f);
6205 aa941b94 balrog
    env->cp15.c5_data = qemu_get_be32(f);
6206 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6207 aa941b94 balrog
        env->cp15.c6_region[i] = qemu_get_be32(f);
6208 aa941b94 balrog
    }
6209 aa941b94 balrog
    env->cp15.c6_insn = qemu_get_be32(f);
6210 aa941b94 balrog
    env->cp15.c6_data = qemu_get_be32(f);
6211 aa941b94 balrog
    env->cp15.c9_insn = qemu_get_be32(f);
6212 aa941b94 balrog
    env->cp15.c9_data = qemu_get_be32(f);
6213 aa941b94 balrog
    env->cp15.c13_fcse = qemu_get_be32(f);
6214 aa941b94 balrog
    env->cp15.c13_context = qemu_get_be32(f);
6215 aa941b94 balrog
    env->cp15.c15_cpar = qemu_get_be32(f);
6216 aa941b94 balrog
6217 aa941b94 balrog
    env->features = qemu_get_be32(f);
6218 aa941b94 balrog
6219 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6220 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6221 aa941b94 balrog
            CPU_DoubleU u;
6222 aa941b94 balrog
            u.l.upper = qemu_get_be32(f);
6223 aa941b94 balrog
            u.l.lower = qemu_get_be32(f);
6224 aa941b94 balrog
            env->vfp.regs[i] = u.d;
6225 aa941b94 balrog
        }
6226 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6227 aa941b94 balrog
            env->vfp.xregs[i] = qemu_get_be32(f);
6228 aa941b94 balrog
        }
6229 aa941b94 balrog
6230 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6231 aa941b94 balrog
        env->vfp.vec_len = qemu_get_be32(f);
6232 aa941b94 balrog
        env->vfp.vec_stride = qemu_get_be32(f);
6233 aa941b94 balrog
    }
6234 aa941b94 balrog
6235 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6236 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6237 aa941b94 balrog
            env->iwmmxt.regs[i] = qemu_get_be64(f);
6238 aa941b94 balrog
        }
6239 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6240 aa941b94 balrog
            env->iwmmxt.cregs[i] = qemu_get_be32(f);
6241 aa941b94 balrog
        }
6242 aa941b94 balrog
    }
6243 aa941b94 balrog
6244 b5ff1b31 bellard
    return 0;
6245 b5ff1b31 bellard
}
6246 b5ff1b31 bellard
6247 8a7ddc38 bellard
#else
6248 8a7ddc38 bellard
6249 8a7ddc38 bellard
#warning No CPU save/restore functions
6250 8a7ddc38 bellard
6251 8a7ddc38 bellard
#endif
6252 8a7ddc38 bellard
6253 8a7ddc38 bellard
/***********************************************************/
6254 8a7ddc38 bellard
/* ram save/restore */
6255 8a7ddc38 bellard
6256 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6257 8a7ddc38 bellard
{
6258 8a7ddc38 bellard
    int v;
6259 8a7ddc38 bellard
6260 8a7ddc38 bellard
    v = qemu_get_byte(f);
6261 8a7ddc38 bellard
    switch(v) {
6262 8a7ddc38 bellard
    case 0:
6263 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
6264 8a7ddc38 bellard
            return -EIO;
6265 8a7ddc38 bellard
        break;
6266 8a7ddc38 bellard
    case 1:
6267 8a7ddc38 bellard
        v = qemu_get_byte(f);
6268 8a7ddc38 bellard
        memset(buf, v, len);
6269 8a7ddc38 bellard
        break;
6270 8a7ddc38 bellard
    default:
6271 8a7ddc38 bellard
        return -EINVAL;
6272 8a7ddc38 bellard
    }
6273 8a7ddc38 bellard
    return 0;
6274 8a7ddc38 bellard
}
6275 8a7ddc38 bellard
6276 c88676f8 bellard
static int ram_load_v1(QEMUFile *f, void *opaque)
6277 c88676f8 bellard
{
6278 c88676f8 bellard
    int i, ret;
6279 c88676f8 bellard
6280 c88676f8 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6281 c88676f8 bellard
        return -EINVAL;
6282 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6283 c88676f8 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6284 c88676f8 bellard
        if (ret)
6285 c88676f8 bellard
            return ret;
6286 c88676f8 bellard
    }
6287 c88676f8 bellard
    return 0;
6288 c88676f8 bellard
}
6289 c88676f8 bellard
6290 c88676f8 bellard
#define BDRV_HASH_BLOCK_SIZE 1024
6291 c88676f8 bellard
#define IOBUF_SIZE 4096
6292 c88676f8 bellard
#define RAM_CBLOCK_MAGIC 0xfabe
6293 c88676f8 bellard
6294 c88676f8 bellard
typedef struct RamCompressState {
6295 c88676f8 bellard
    z_stream zstream;
6296 c88676f8 bellard
    QEMUFile *f;
6297 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6298 c88676f8 bellard
} RamCompressState;
6299 c88676f8 bellard
6300 c88676f8 bellard
static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6301 c88676f8 bellard
{
6302 c88676f8 bellard
    int ret;
6303 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6304 c88676f8 bellard
    s->f = f;
6305 c88676f8 bellard
    ret = deflateInit2(&s->zstream, 1,
6306 5fafdf24 ths
                       Z_DEFLATED, 15,
6307 c88676f8 bellard
                       9, Z_DEFAULT_STRATEGY);
6308 c88676f8 bellard
    if (ret != Z_OK)
6309 c88676f8 bellard
        return -1;
6310 c88676f8 bellard
    s->zstream.avail_out = IOBUF_SIZE;
6311 c88676f8 bellard
    s->zstream.next_out = s->buf;
6312 c88676f8 bellard
    return 0;
6313 c88676f8 bellard
}
6314 c88676f8 bellard
6315 c88676f8 bellard
static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6316 c88676f8 bellard
{
6317 c88676f8 bellard
    qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6318 c88676f8 bellard
    qemu_put_be16(s->f, len);
6319 c88676f8 bellard
    qemu_put_buffer(s->f, buf, len);
6320 c88676f8 bellard
}
6321 c88676f8 bellard
6322 c88676f8 bellard
static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6323 c88676f8 bellard
{
6324 c88676f8 bellard
    int ret;
6325 c88676f8 bellard
6326 c88676f8 bellard
    s->zstream.avail_in = len;
6327 c88676f8 bellard
    s->zstream.next_in = (uint8_t *)buf;
6328 c88676f8 bellard
    while (s->zstream.avail_in > 0) {
6329 c88676f8 bellard
        ret = deflate(&s->zstream, Z_NO_FLUSH);
6330 c88676f8 bellard
        if (ret != Z_OK)
6331 c88676f8 bellard
            return -1;
6332 c88676f8 bellard
        if (s->zstream.avail_out == 0) {
6333 c88676f8 bellard
            ram_put_cblock(s, s->buf, IOBUF_SIZE);
6334 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6335 c88676f8 bellard
            s->zstream.next_out = s->buf;
6336 c88676f8 bellard
        }
6337 c88676f8 bellard
    }
6338 c88676f8 bellard
    return 0;
6339 c88676f8 bellard
}
6340 c88676f8 bellard
6341 c88676f8 bellard
static void ram_compress_close(RamCompressState *s)
6342 c88676f8 bellard
{
6343 c88676f8 bellard
    int len, ret;
6344 c88676f8 bellard
6345 c88676f8 bellard
    /* compress last bytes */
6346 c88676f8 bellard
    for(;;) {
6347 c88676f8 bellard
        ret = deflate(&s->zstream, Z_FINISH);
6348 c88676f8 bellard
        if (ret == Z_OK || ret == Z_STREAM_END) {
6349 c88676f8 bellard
            len = IOBUF_SIZE - s->zstream.avail_out;
6350 c88676f8 bellard
            if (len > 0) {
6351 c88676f8 bellard
                ram_put_cblock(s, s->buf, len);
6352 c88676f8 bellard
            }
6353 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6354 c88676f8 bellard
            s->zstream.next_out = s->buf;
6355 c88676f8 bellard
            if (ret == Z_STREAM_END)
6356 c88676f8 bellard
                break;
6357 c88676f8 bellard
        } else {
6358 c88676f8 bellard
            goto fail;
6359 c88676f8 bellard
        }
6360 c88676f8 bellard
    }
6361 c88676f8 bellard
fail:
6362 c88676f8 bellard
    deflateEnd(&s->zstream);
6363 c88676f8 bellard
}
6364 c88676f8 bellard
6365 c88676f8 bellard
typedef struct RamDecompressState {
6366 c88676f8 bellard
    z_stream zstream;
6367 c88676f8 bellard
    QEMUFile *f;
6368 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6369 c88676f8 bellard
} RamDecompressState;
6370 c88676f8 bellard
6371 c88676f8 bellard
static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6372 c88676f8 bellard
{
6373 c88676f8 bellard
    int ret;
6374 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6375 c88676f8 bellard
    s->f = f;
6376 c88676f8 bellard
    ret = inflateInit(&s->zstream);
6377 c88676f8 bellard
    if (ret != Z_OK)
6378 c88676f8 bellard
        return -1;
6379 c88676f8 bellard
    return 0;
6380 c88676f8 bellard
}
6381 c88676f8 bellard
6382 c88676f8 bellard
static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6383 c88676f8 bellard
{
6384 c88676f8 bellard
    int ret, clen;
6385 c88676f8 bellard
6386 c88676f8 bellard
    s->zstream.avail_out = len;
6387 c88676f8 bellard
    s->zstream.next_out = buf;
6388 c88676f8 bellard
    while (s->zstream.avail_out > 0) {
6389 c88676f8 bellard
        if (s->zstream.avail_in == 0) {
6390 c88676f8 bellard
            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6391 c88676f8 bellard
                return -1;
6392 c88676f8 bellard
            clen = qemu_get_be16(s->f);
6393 c88676f8 bellard
            if (clen > IOBUF_SIZE)
6394 c88676f8 bellard
                return -1;
6395 c88676f8 bellard
            qemu_get_buffer(s->f, s->buf, clen);
6396 c88676f8 bellard
            s->zstream.avail_in = clen;
6397 c88676f8 bellard
            s->zstream.next_in = s->buf;
6398 c88676f8 bellard
        }
6399 c88676f8 bellard
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6400 c88676f8 bellard
        if (ret != Z_OK && ret != Z_STREAM_END) {
6401 c88676f8 bellard
            return -1;
6402 c88676f8 bellard
        }
6403 c88676f8 bellard
    }
6404 c88676f8 bellard
    return 0;
6405 c88676f8 bellard
}
6406 c88676f8 bellard
6407 c88676f8 bellard
static void ram_decompress_close(RamDecompressState *s)
6408 c88676f8 bellard
{
6409 c88676f8 bellard
    inflateEnd(&s->zstream);
6410 c88676f8 bellard
}
6411 c88676f8 bellard
6412 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
6413 8a7ddc38 bellard
{
6414 8a7ddc38 bellard
    int i;
6415 c88676f8 bellard
    RamCompressState s1, *s = &s1;
6416 c88676f8 bellard
    uint8_t buf[10];
6417 3b46e624 ths
6418 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
6419 c88676f8 bellard
    if (ram_compress_open(s, f) < 0)
6420 c88676f8 bellard
        return;
6421 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6422 c88676f8 bellard
#if 0
6423 c88676f8 bellard
        if (tight_savevm_enabled) {
6424 c88676f8 bellard
            int64_t sector_num;
6425 c88676f8 bellard
            int j;
6426 c88676f8 bellard

6427 c88676f8 bellard
            /* find if the memory block is available on a virtual
6428 c88676f8 bellard
               block device */
6429 c88676f8 bellard
            sector_num = -1;
6430 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
6431 c88676f8 bellard
                if (bs_table[j]) {
6432 5fafdf24 ths
                    sector_num = bdrv_hash_find(bs_table[j],
6433 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6434 c88676f8 bellard
                    if (sector_num >= 0)
6435 c88676f8 bellard
                        break;
6436 c88676f8 bellard
                }
6437 c88676f8 bellard
            }
6438 c88676f8 bellard
            if (j == MAX_DISKS)
6439 c88676f8 bellard
                goto normal_compress;
6440 c88676f8 bellard
            buf[0] = 1;
6441 c88676f8 bellard
            buf[1] = j;
6442 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
6443 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
6444 5fafdf24 ths
        } else
6445 c88676f8 bellard
#endif
6446 c88676f8 bellard
        {
6447 c88676f8 bellard
            //        normal_compress:
6448 c88676f8 bellard
            buf[0] = 0;
6449 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
6450 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6451 c88676f8 bellard
        }
6452 8a7ddc38 bellard
    }
6453 c88676f8 bellard
    ram_compress_close(s);
6454 8a7ddc38 bellard
}
6455 8a7ddc38 bellard
6456 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
6457 8a7ddc38 bellard
{
6458 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
6459 c88676f8 bellard
    uint8_t buf[10];
6460 c88676f8 bellard
    int i;
6461 8a7ddc38 bellard
6462 c88676f8 bellard
    if (version_id == 1)
6463 c88676f8 bellard
        return ram_load_v1(f, opaque);
6464 c88676f8 bellard
    if (version_id != 2)
6465 8a7ddc38 bellard
        return -EINVAL;
6466 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6467 8a7ddc38 bellard
        return -EINVAL;
6468 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
6469 c88676f8 bellard
        return -EINVAL;
6470 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6471 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
6472 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
6473 c88676f8 bellard
            goto error;
6474 c88676f8 bellard
        }
6475 c88676f8 bellard
        if (buf[0] == 0) {
6476 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
6477 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
6478 c88676f8 bellard
                goto error;
6479 c88676f8 bellard
            }
6480 5fafdf24 ths
        } else
6481 c88676f8 bellard
#if 0
6482 c88676f8 bellard
        if (buf[0] == 1) {
6483 c88676f8 bellard
            int bs_index;
6484 c88676f8 bellard
            int64_t sector_num;
6485 c88676f8 bellard

6486 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
6487 c88676f8 bellard
            bs_index = buf[1];
6488 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
6489 c88676f8 bellard
            if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
6490 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
6491 c88676f8 bellard
                goto error;
6492 c88676f8 bellard
            }
6493 5fafdf24 ths
            if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i,
6494 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
6495 5fafdf24 ths
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
6496 c88676f8 bellard
                        bs_index, sector_num);
6497 c88676f8 bellard
                goto error;
6498 c88676f8 bellard
            }
6499 5fafdf24 ths
        } else
6500 c88676f8 bellard
#endif
6501 c88676f8 bellard
        {
6502 c88676f8 bellard
        error:
6503 c88676f8 bellard
            printf("Error block header\n");
6504 c88676f8 bellard
            return -EINVAL;
6505 c88676f8 bellard
        }
6506 8a7ddc38 bellard
    }
6507 c88676f8 bellard
    ram_decompress_close(s);
6508 8a7ddc38 bellard
    return 0;
6509 8a7ddc38 bellard
}
6510 8a7ddc38 bellard
6511 8a7ddc38 bellard
/***********************************************************/
6512 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
6513 83f64091 bellard
6514 83f64091 bellard
struct QEMUBH {
6515 83f64091 bellard
    QEMUBHFunc *cb;
6516 83f64091 bellard
    void *opaque;
6517 83f64091 bellard
    int scheduled;
6518 83f64091 bellard
    QEMUBH *next;
6519 83f64091 bellard
};
6520 83f64091 bellard
6521 83f64091 bellard
static QEMUBH *first_bh = NULL;
6522 83f64091 bellard
6523 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
6524 83f64091 bellard
{
6525 83f64091 bellard
    QEMUBH *bh;
6526 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
6527 83f64091 bellard
    if (!bh)
6528 83f64091 bellard
        return NULL;
6529 83f64091 bellard
    bh->cb = cb;
6530 83f64091 bellard
    bh->opaque = opaque;
6531 83f64091 bellard
    return bh;
6532 83f64091 bellard
}
6533 83f64091 bellard
6534 6eb5733a bellard
int qemu_bh_poll(void)
6535 83f64091 bellard
{
6536 83f64091 bellard
    QEMUBH *bh, **pbh;
6537 6eb5733a bellard
    int ret;
6538 83f64091 bellard
6539 6eb5733a bellard
    ret = 0;
6540 83f64091 bellard
    for(;;) {
6541 83f64091 bellard
        pbh = &first_bh;
6542 83f64091 bellard
        bh = *pbh;
6543 83f64091 bellard
        if (!bh)
6544 83f64091 bellard
            break;
6545 6eb5733a bellard
        ret = 1;
6546 83f64091 bellard
        *pbh = bh->next;
6547 83f64091 bellard
        bh->scheduled = 0;
6548 83f64091 bellard
        bh->cb(bh->opaque);
6549 83f64091 bellard
    }
6550 6eb5733a bellard
    return ret;
6551 83f64091 bellard
}
6552 83f64091 bellard
6553 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
6554 83f64091 bellard
{
6555 83f64091 bellard
    CPUState *env = cpu_single_env;
6556 83f64091 bellard
    if (bh->scheduled)
6557 83f64091 bellard
        return;
6558 83f64091 bellard
    bh->scheduled = 1;
6559 83f64091 bellard
    bh->next = first_bh;
6560 83f64091 bellard
    first_bh = bh;
6561 83f64091 bellard
6562 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
6563 83f64091 bellard
    if (env) {
6564 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
6565 83f64091 bellard
    }
6566 83f64091 bellard
}
6567 83f64091 bellard
6568 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
6569 83f64091 bellard
{
6570 83f64091 bellard
    QEMUBH **pbh;
6571 83f64091 bellard
    if (bh->scheduled) {
6572 83f64091 bellard
        pbh = &first_bh;
6573 83f64091 bellard
        while (*pbh != bh)
6574 83f64091 bellard
            pbh = &(*pbh)->next;
6575 83f64091 bellard
        *pbh = bh->next;
6576 83f64091 bellard
        bh->scheduled = 0;
6577 83f64091 bellard
    }
6578 83f64091 bellard
}
6579 83f64091 bellard
6580 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
6581 83f64091 bellard
{
6582 83f64091 bellard
    qemu_bh_cancel(bh);
6583 83f64091 bellard
    qemu_free(bh);
6584 83f64091 bellard
}
6585 83f64091 bellard
6586 83f64091 bellard
/***********************************************************/
6587 cc1daa40 bellard
/* machine registration */
6588 cc1daa40 bellard
6589 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
6590 cc1daa40 bellard
6591 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
6592 cc1daa40 bellard
{
6593 cc1daa40 bellard
    QEMUMachine **pm;
6594 cc1daa40 bellard
    pm = &first_machine;
6595 cc1daa40 bellard
    while (*pm != NULL)
6596 cc1daa40 bellard
        pm = &(*pm)->next;
6597 cc1daa40 bellard
    m->next = NULL;
6598 cc1daa40 bellard
    *pm = m;
6599 cc1daa40 bellard
    return 0;
6600 cc1daa40 bellard
}
6601 cc1daa40 bellard
6602 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
6603 cc1daa40 bellard
{
6604 cc1daa40 bellard
    QEMUMachine *m;
6605 cc1daa40 bellard
6606 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
6607 cc1daa40 bellard
        if (!strcmp(m->name, name))
6608 cc1daa40 bellard
            return m;
6609 cc1daa40 bellard
    }
6610 cc1daa40 bellard
    return NULL;
6611 cc1daa40 bellard
}
6612 cc1daa40 bellard
6613 cc1daa40 bellard
/***********************************************************/
6614 8a7ddc38 bellard
/* main execution loop */
6615 8a7ddc38 bellard
6616 8a7ddc38 bellard
void gui_update(void *opaque)
6617 8a7ddc38 bellard
{
6618 740733bb ths
    DisplayState *ds = opaque;
6619 740733bb ths
    ds->dpy_refresh(ds);
6620 740733bb ths
    qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
6621 8a7ddc38 bellard
}
6622 8a7ddc38 bellard
6623 0bd48850 bellard
struct vm_change_state_entry {
6624 0bd48850 bellard
    VMChangeStateHandler *cb;
6625 0bd48850 bellard
    void *opaque;
6626 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
6627 0bd48850 bellard
};
6628 0bd48850 bellard
6629 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
6630 0bd48850 bellard
6631 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
6632 0bd48850 bellard
                                                     void *opaque)
6633 0bd48850 bellard
{
6634 0bd48850 bellard
    VMChangeStateEntry *e;
6635 0bd48850 bellard
6636 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
6637 0bd48850 bellard
    if (!e)
6638 0bd48850 bellard
        return NULL;
6639 0bd48850 bellard
6640 0bd48850 bellard
    e->cb = cb;
6641 0bd48850 bellard
    e->opaque = opaque;
6642 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
6643 0bd48850 bellard
    return e;
6644 0bd48850 bellard
}
6645 0bd48850 bellard
6646 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
6647 0bd48850 bellard
{
6648 0bd48850 bellard
    LIST_REMOVE (e, entries);
6649 0bd48850 bellard
    qemu_free (e);
6650 0bd48850 bellard
}
6651 0bd48850 bellard
6652 0bd48850 bellard
static void vm_state_notify(int running)
6653 0bd48850 bellard
{
6654 0bd48850 bellard
    VMChangeStateEntry *e;
6655 0bd48850 bellard
6656 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
6657 0bd48850 bellard
        e->cb(e->opaque, running);
6658 0bd48850 bellard
    }
6659 0bd48850 bellard
}
6660 0bd48850 bellard
6661 8a7ddc38 bellard
/* XXX: support several handlers */
6662 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
6663 0bd48850 bellard
static void *vm_stop_opaque;
6664 8a7ddc38 bellard
6665 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
6666 8a7ddc38 bellard
{
6667 8a7ddc38 bellard
    vm_stop_cb = cb;
6668 8a7ddc38 bellard
    vm_stop_opaque = opaque;
6669 8a7ddc38 bellard
    return 0;
6670 8a7ddc38 bellard
}
6671 8a7ddc38 bellard
6672 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
6673 8a7ddc38 bellard
{
6674 8a7ddc38 bellard
    vm_stop_cb = NULL;
6675 8a7ddc38 bellard
}
6676 8a7ddc38 bellard
6677 8a7ddc38 bellard
void vm_start(void)
6678 8a7ddc38 bellard
{
6679 8a7ddc38 bellard
    if (!vm_running) {
6680 8a7ddc38 bellard
        cpu_enable_ticks();
6681 8a7ddc38 bellard
        vm_running = 1;
6682 0bd48850 bellard
        vm_state_notify(1);
6683 efe75411 ths
        qemu_rearm_alarm_timer(alarm_timer);
6684 8a7ddc38 bellard
    }
6685 8a7ddc38 bellard
}
6686 8a7ddc38 bellard
6687 5fafdf24 ths
void vm_stop(int reason)
6688 8a7ddc38 bellard
{
6689 8a7ddc38 bellard
    if (vm_running) {
6690 8a7ddc38 bellard
        cpu_disable_ticks();
6691 8a7ddc38 bellard
        vm_running = 0;
6692 8a7ddc38 bellard
        if (reason != 0) {
6693 8a7ddc38 bellard
            if (vm_stop_cb) {
6694 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
6695 8a7ddc38 bellard
            }
6696 34865134 bellard
        }
6697 0bd48850 bellard
        vm_state_notify(0);
6698 8a7ddc38 bellard
    }
6699 8a7ddc38 bellard
}
6700 8a7ddc38 bellard
6701 bb0c6722 bellard
/* reset/shutdown handler */
6702 bb0c6722 bellard
6703 bb0c6722 bellard
typedef struct QEMUResetEntry {
6704 bb0c6722 bellard
    QEMUResetHandler *func;
6705 bb0c6722 bellard
    void *opaque;
6706 bb0c6722 bellard
    struct QEMUResetEntry *next;
6707 bb0c6722 bellard
} QEMUResetEntry;
6708 bb0c6722 bellard
6709 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
6710 bb0c6722 bellard
static int reset_requested;
6711 bb0c6722 bellard
static int shutdown_requested;
6712 3475187d bellard
static int powerdown_requested;
6713 bb0c6722 bellard
6714 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
6715 bb0c6722 bellard
{
6716 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
6717 bb0c6722 bellard
6718 bb0c6722 bellard
    pre = &first_reset_entry;
6719 bb0c6722 bellard
    while (*pre != NULL)
6720 bb0c6722 bellard
        pre = &(*pre)->next;
6721 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
6722 bb0c6722 bellard
    re->func = func;
6723 bb0c6722 bellard
    re->opaque = opaque;
6724 bb0c6722 bellard
    re->next = NULL;
6725 bb0c6722 bellard
    *pre = re;
6726 bb0c6722 bellard
}
6727 bb0c6722 bellard
6728 52f61fde ths
static void qemu_system_reset(void)
6729 bb0c6722 bellard
{
6730 bb0c6722 bellard
    QEMUResetEntry *re;
6731 bb0c6722 bellard
6732 bb0c6722 bellard
    /* reset all devices */
6733 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
6734 bb0c6722 bellard
        re->func(re->opaque);
6735 bb0c6722 bellard
    }
6736 bb0c6722 bellard
}
6737 bb0c6722 bellard
6738 bb0c6722 bellard
void qemu_system_reset_request(void)
6739 bb0c6722 bellard
{
6740 d1beab82 bellard
    if (no_reboot) {
6741 d1beab82 bellard
        shutdown_requested = 1;
6742 d1beab82 bellard
    } else {
6743 d1beab82 bellard
        reset_requested = 1;
6744 d1beab82 bellard
    }
6745 6a00d601 bellard
    if (cpu_single_env)
6746 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6747 bb0c6722 bellard
}
6748 bb0c6722 bellard
6749 bb0c6722 bellard
void qemu_system_shutdown_request(void)
6750 bb0c6722 bellard
{
6751 bb0c6722 bellard
    shutdown_requested = 1;
6752 6a00d601 bellard
    if (cpu_single_env)
6753 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6754 bb0c6722 bellard
}
6755 bb0c6722 bellard
6756 3475187d bellard
void qemu_system_powerdown_request(void)
6757 3475187d bellard
{
6758 3475187d bellard
    powerdown_requested = 1;
6759 6a00d601 bellard
    if (cpu_single_env)
6760 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6761 bb0c6722 bellard
}
6762 bb0c6722 bellard
6763 5905b2e5 bellard
void main_loop_wait(int timeout)
6764 8a7ddc38 bellard
{
6765 cafffd40 ths
    IOHandlerRecord *ioh;
6766 e035649e bellard
    fd_set rfds, wfds, xfds;
6767 877cf882 ths
    int ret, nfds;
6768 877cf882 ths
#ifdef _WIN32
6769 877cf882 ths
    int ret2, i;
6770 877cf882 ths
#endif
6771 fd1dff4b bellard
    struct timeval tv;
6772 f331110f bellard
    PollingEntry *pe;
6773 f331110f bellard
6774 c4b1fcc0 bellard
6775 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
6776 f331110f bellard
    ret = 0;
6777 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
6778 f331110f bellard
        ret |= pe->func(pe->opaque);
6779 f331110f bellard
    }
6780 38e205a2 bellard
#ifdef _WIN32
6781 e6b1e558 ths
    if (ret == 0) {
6782 a18e524a bellard
        int err;
6783 a18e524a bellard
        WaitObjects *w = &wait_objects;
6784 3b46e624 ths
6785 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
6786 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
6787 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
6788 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
6789 3b46e624 ths
6790 5fafdf24 ths
            /* Check for additional signaled events */
6791 e6b1e558 ths
            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
6792 3b46e624 ths
6793 e6b1e558 ths
                /* Check if event is signaled */
6794 e6b1e558 ths
                ret2 = WaitForSingleObject(w->events[i], 0);
6795 e6b1e558 ths
                if(ret2 == WAIT_OBJECT_0) {
6796 e6b1e558 ths
                    if (w->func[i])
6797 e6b1e558 ths
                        w->func[i](w->opaque[i]);
6798 e6b1e558 ths
                } else if (ret2 == WAIT_TIMEOUT) {
6799 e6b1e558 ths
                } else {
6800 e6b1e558 ths
                    err = GetLastError();
6801 e6b1e558 ths
                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
6802 3b46e624 ths
                }
6803 3b46e624 ths
            }
6804 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
6805 a18e524a bellard
        } else {
6806 a18e524a bellard
            err = GetLastError();
6807 e6b1e558 ths
            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
6808 a18e524a bellard
        }
6809 f331110f bellard
    }
6810 fd1dff4b bellard
#endif
6811 fd1dff4b bellard
    /* poll any events */
6812 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
6813 fd1dff4b bellard
    nfds = -1;
6814 fd1dff4b bellard
    FD_ZERO(&rfds);
6815 fd1dff4b bellard
    FD_ZERO(&wfds);
6816 e035649e bellard
    FD_ZERO(&xfds);
6817 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6818 cafffd40 ths
        if (ioh->deleted)
6819 cafffd40 ths
            continue;
6820 fd1dff4b bellard
        if (ioh->fd_read &&
6821 fd1dff4b bellard
            (!ioh->fd_read_poll ||
6822 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
6823 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
6824 fd1dff4b bellard
            if (ioh->fd > nfds)
6825 fd1dff4b bellard
                nfds = ioh->fd;
6826 fd1dff4b bellard
        }
6827 fd1dff4b bellard
        if (ioh->fd_write) {
6828 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
6829 fd1dff4b bellard
            if (ioh->fd > nfds)
6830 fd1dff4b bellard
                nfds = ioh->fd;
6831 fd1dff4b bellard
        }
6832 fd1dff4b bellard
    }
6833 3b46e624 ths
6834 fd1dff4b bellard
    tv.tv_sec = 0;
6835 fd1dff4b bellard
#ifdef _WIN32
6836 fd1dff4b bellard
    tv.tv_usec = 0;
6837 38e205a2 bellard
#else
6838 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
6839 fd1dff4b bellard
#endif
6840 e035649e bellard
#if defined(CONFIG_SLIRP)
6841 e035649e bellard
    if (slirp_inited) {
6842 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
6843 e035649e bellard
    }
6844 e035649e bellard
#endif
6845 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
6846 fd1dff4b bellard
    if (ret > 0) {
6847 cafffd40 ths
        IOHandlerRecord **pioh;
6848 cafffd40 ths
6849 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6850 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
6851 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
6852 7c9d8e07 bellard
            }
6853 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
6854 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
6855 c4b1fcc0 bellard
            }
6856 b4608c04 bellard
        }
6857 cafffd40 ths
6858 cafffd40 ths
        /* remove deleted IO handlers */
6859 cafffd40 ths
        pioh = &first_io_handler;
6860 cafffd40 ths
        while (*pioh) {
6861 cafffd40 ths
            ioh = *pioh;
6862 cafffd40 ths
            if (ioh->deleted) {
6863 cafffd40 ths
                *pioh = ioh->next;
6864 cafffd40 ths
                qemu_free(ioh);
6865 5fafdf24 ths
            } else
6866 cafffd40 ths
                pioh = &ioh->next;
6867 cafffd40 ths
        }
6868 fd1dff4b bellard
    }
6869 c20709aa bellard
#if defined(CONFIG_SLIRP)
6870 fd1dff4b bellard
    if (slirp_inited) {
6871 e035649e bellard
        if (ret < 0) {
6872 e035649e bellard
            FD_ZERO(&rfds);
6873 e035649e bellard
            FD_ZERO(&wfds);
6874 e035649e bellard
            FD_ZERO(&xfds);
6875 c20709aa bellard
        }
6876 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
6877 fd1dff4b bellard
    }
6878 c20709aa bellard
#endif
6879 83f64091 bellard
    qemu_aio_poll();
6880 c20709aa bellard
6881 fd1dff4b bellard
    if (vm_running) {
6882 5fafdf24 ths
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
6883 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
6884 fd1dff4b bellard
        /* run dma transfers, if any */
6885 fd1dff4b bellard
        DMA_run();
6886 fd1dff4b bellard
    }
6887 423f0742 pbrook
6888 fd1dff4b bellard
    /* real time timers */
6889 5fafdf24 ths
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
6890 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
6891 423f0742 pbrook
6892 423f0742 pbrook
    /* Check bottom-halves last in case any of the earlier events triggered
6893 423f0742 pbrook
       them.  */
6894 423f0742 pbrook
    qemu_bh_poll();
6895 3b46e624 ths
6896 5905b2e5 bellard
}
6897 5905b2e5 bellard
6898 6a00d601 bellard
static CPUState *cur_cpu;
6899 6a00d601 bellard
6900 5905b2e5 bellard
int main_loop(void)
6901 5905b2e5 bellard
{
6902 5905b2e5 bellard
    int ret, timeout;
6903 89bfc105 bellard
#ifdef CONFIG_PROFILER
6904 89bfc105 bellard
    int64_t ti;
6905 89bfc105 bellard
#endif
6906 6a00d601 bellard
    CPUState *env;
6907 5905b2e5 bellard
6908 6a00d601 bellard
    cur_cpu = first_cpu;
6909 5905b2e5 bellard
    for(;;) {
6910 5905b2e5 bellard
        if (vm_running) {
6911 15a76449 bellard
6912 15a76449 bellard
            env = cur_cpu;
6913 15a76449 bellard
            for(;;) {
6914 15a76449 bellard
                /* get next cpu */
6915 15a76449 bellard
                env = env->next_cpu;
6916 15a76449 bellard
                if (!env)
6917 15a76449 bellard
                    env = first_cpu;
6918 89bfc105 bellard
#ifdef CONFIG_PROFILER
6919 89bfc105 bellard
                ti = profile_getclock();
6920 89bfc105 bellard
#endif
6921 6a00d601 bellard
                ret = cpu_exec(env);
6922 89bfc105 bellard
#ifdef CONFIG_PROFILER
6923 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
6924 89bfc105 bellard
#endif
6925 bd967e05 pbrook
                if (ret == EXCP_HLT) {
6926 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
6927 bd967e05 pbrook
                    cur_cpu = env;
6928 bd967e05 pbrook
                    continue;
6929 bd967e05 pbrook
                }
6930 15a76449 bellard
                if (ret != EXCP_HALTED)
6931 15a76449 bellard
                    break;
6932 15a76449 bellard
                /* all CPUs are halted ? */
6933 bd967e05 pbrook
                if (env == cur_cpu)
6934 15a76449 bellard
                    break;
6935 15a76449 bellard
            }
6936 15a76449 bellard
            cur_cpu = env;
6937 15a76449 bellard
6938 5905b2e5 bellard
            if (shutdown_requested) {
6939 3475187d bellard
                ret = EXCP_INTERRUPT;
6940 5905b2e5 bellard
                break;
6941 5905b2e5 bellard
            }
6942 5905b2e5 bellard
            if (reset_requested) {
6943 5905b2e5 bellard
                reset_requested = 0;
6944 5905b2e5 bellard
                qemu_system_reset();
6945 3475187d bellard
                ret = EXCP_INTERRUPT;
6946 3475187d bellard
            }
6947 3475187d bellard
            if (powerdown_requested) {
6948 3475187d bellard
                powerdown_requested = 0;
6949 3475187d bellard
                qemu_system_powerdown();
6950 3475187d bellard
                ret = EXCP_INTERRUPT;
6951 5905b2e5 bellard
            }
6952 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
6953 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
6954 5905b2e5 bellard
            }
6955 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
6956 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
6957 bd967e05 pbrook
            if (ret == EXCP_HALTED)
6958 5905b2e5 bellard
                timeout = 10;
6959 5905b2e5 bellard
            else
6960 5905b2e5 bellard
                timeout = 0;
6961 5905b2e5 bellard
        } else {
6962 5905b2e5 bellard
            timeout = 10;
6963 5905b2e5 bellard
        }
6964 89bfc105 bellard
#ifdef CONFIG_PROFILER
6965 89bfc105 bellard
        ti = profile_getclock();
6966 89bfc105 bellard
#endif
6967 5905b2e5 bellard
        main_loop_wait(timeout);
6968 89bfc105 bellard
#ifdef CONFIG_PROFILER
6969 89bfc105 bellard
        dev_time += profile_getclock() - ti;
6970 89bfc105 bellard
#endif
6971 b4608c04 bellard
    }
6972 34865134 bellard
    cpu_disable_ticks();
6973 34865134 bellard
    return ret;
6974 b4608c04 bellard
}
6975 b4608c04 bellard
6976 15f82208 ths
static void help(int exitcode)
6977 0824d6fc bellard
{
6978 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
6979 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
6980 0824d6fc bellard
           "\n"
6981 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
6982 fc01f7e7 bellard
           "\n"
6983 a20dd508 bellard
           "Standard options:\n"
6984 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
6985 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
6986 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
6987 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
6988 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
6989 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
6990 3e3d5815 balrog
           "-mtdblock file  use 'file' as on-board Flash memory image\n"
6991 a1bb27b1 pbrook
           "-sd file        use 'file' as SecureDigital card image\n"
6992 86f55663 j_mayer
           "-pflash file    use 'file' as a parallel flash image\n"
6993 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
6994 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
6995 667accab ths
#ifdef CONFIG_SDL
6996 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
6997 3780e197 ths
           "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
6998 667accab ths
           "-no-quit        disable SDL window close capability\n"
6999 667accab ths
#endif
7000 52ca8d6a bellard
#ifdef TARGET_I386
7001 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
7002 52ca8d6a bellard
#endif
7003 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
7004 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
7005 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
7006 a171fe39 balrog
           "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"
7007 4ca0074c bellard
#ifndef _WIN32
7008 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
7009 4ca0074c bellard
#endif
7010 1d14ffa9 bellard
#ifdef HAS_AUDIO
7011 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
7012 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
7013 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
7014 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
7015 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
7016 1d14ffa9 bellard
#endif
7017 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
7018 d63d307f bellard
           "-full-screen    start in full screen\n"
7019 a09db21f bellard
#ifdef TARGET_I386
7020 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
7021 a09db21f bellard
#endif
7022 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
7023 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
7024 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7025 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
7026 bb0c6722 bellard
#endif
7027 c35734b2 ths
           "-name string    set the name of the guest\n"
7028 c4b1fcc0 bellard
           "\n"
7029 c4b1fcc0 bellard
           "Network options:\n"
7030 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
7031 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
7032 c20709aa bellard
#ifdef CONFIG_SLIRP
7033 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
7034 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
7035 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
7036 7c9d8e07 bellard
#endif
7037 7fb843f8 bellard
#ifdef _WIN32
7038 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
7039 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
7040 7fb843f8 bellard
#else
7041 b46a8906 ths
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7042 b46a8906 ths
           "                connect the host TAP network interface to VLAN 'n' and use the\n"
7043 b46a8906 ths
           "                network scripts 'file' (default=%s)\n"
7044 b46a8906 ths
           "                and 'dfile' (default=%s);\n"
7045 b46a8906 ths
           "                use '[down]script=no' to disable script execution;\n"
7046 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
7047 7fb843f8 bellard
#endif
7048 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
7049 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
7050 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7051 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
7052 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
7053 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
7054 7c9d8e07 bellard
           "\n"
7055 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
7056 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
7057 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
7058 7c9d8e07 bellard
#ifndef _WIN32
7059 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
7060 c94c8d64 bellard
#endif
7061 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
7062 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
7063 c20709aa bellard
#endif
7064 a20dd508 bellard
           "\n"
7065 c4b1fcc0 bellard
           "Linux boot specific:\n"
7066 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
7067 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
7068 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
7069 fc01f7e7 bellard
           "\n"
7070 330d0414 bellard
           "Debug/Expert options:\n"
7071 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
7072 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
7073 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
7074 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
7075 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
7076 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
7077 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
7078 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
7079 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
7080 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
7081 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
7082 d993e026 bellard
#ifdef USE_KQEMU
7083 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
7084 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
7085 d993e026 bellard
#endif
7086 77fef8c1 bellard
#ifdef USE_CODE_COPY
7087 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
7088 77fef8c1 bellard
#endif
7089 bb0c6722 bellard
#ifdef TARGET_I386
7090 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
7091 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
7092 6515b203 bellard
           "-no-acpi        disable ACPI\n"
7093 bb0c6722 bellard
#endif
7094 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
7095 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
7096 24236869 bellard
           "-vnc display    start a VNC server on display\n"
7097 71e3ceb8 ths
#ifndef _WIN32
7098 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
7099 71e3ceb8 ths
#endif
7100 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
7101 66508601 blueswir1
#ifdef TARGET_SPARC
7102 66508601 blueswir1
           "-prom-env variable=value  set OpenBIOS nvram variables\n"
7103 66508601 blueswir1
#endif
7104 f3dcfada ths
           "-clock          force the use of the given methods for timer alarm.\n"
7105 f3dcfada ths
           "                To see what timers are available use -clock help\n"
7106 0824d6fc bellard
           "\n"
7107 82c643ff bellard
           "During emulation, the following keys are useful:\n"
7108 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
7109 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
7110 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
7111 82c643ff bellard
           "\n"
7112 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
7113 82c643ff bellard
           ,
7114 0db63474 bellard
           "qemu",
7115 a00bad7e bellard
           DEFAULT_RAM_SIZE,
7116 7c9d8e07 bellard
#ifndef _WIN32
7117 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
7118 b46a8906 ths
           DEFAULT_NETWORK_DOWN_SCRIPT,
7119 7c9d8e07 bellard
#endif
7120 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
7121 6e44ba7f bellard
           "/tmp/qemu.log");
7122 15f82208 ths
    exit(exitcode);
7123 0824d6fc bellard
}
7124 0824d6fc bellard
7125 cd6f1169 bellard
#define HAS_ARG 0x0001
7126 cd6f1169 bellard
7127 cd6f1169 bellard
enum {
7128 cd6f1169 bellard
    QEMU_OPTION_h,
7129 cd6f1169 bellard
7130 cc1daa40 bellard
    QEMU_OPTION_M,
7131 94fc95cd j_mayer
    QEMU_OPTION_cpu,
7132 cd6f1169 bellard
    QEMU_OPTION_fda,
7133 cd6f1169 bellard
    QEMU_OPTION_fdb,
7134 cd6f1169 bellard
    QEMU_OPTION_hda,
7135 cd6f1169 bellard
    QEMU_OPTION_hdb,
7136 cd6f1169 bellard
    QEMU_OPTION_hdc,
7137 cd6f1169 bellard
    QEMU_OPTION_hdd,
7138 cd6f1169 bellard
    QEMU_OPTION_cdrom,
7139 3e3d5815 balrog
    QEMU_OPTION_mtdblock,
7140 a1bb27b1 pbrook
    QEMU_OPTION_sd,
7141 86f55663 j_mayer
    QEMU_OPTION_pflash,
7142 cd6f1169 bellard
    QEMU_OPTION_boot,
7143 cd6f1169 bellard
    QEMU_OPTION_snapshot,
7144 52ca8d6a bellard
#ifdef TARGET_I386
7145 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
7146 52ca8d6a bellard
#endif
7147 cd6f1169 bellard
    QEMU_OPTION_m,
7148 cd6f1169 bellard
    QEMU_OPTION_nographic,
7149 a171fe39 balrog
    QEMU_OPTION_portrait,
7150 1d14ffa9 bellard
#ifdef HAS_AUDIO
7151 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
7152 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
7153 1d14ffa9 bellard
#endif
7154 cd6f1169 bellard
7155 7c9d8e07 bellard
    QEMU_OPTION_net,
7156 c7f74643 bellard
    QEMU_OPTION_tftp,
7157 47d5d01a ths
    QEMU_OPTION_bootp,
7158 9d728e8c bellard
    QEMU_OPTION_smb,
7159 9bf05444 bellard
    QEMU_OPTION_redir,
7160 cd6f1169 bellard
7161 cd6f1169 bellard
    QEMU_OPTION_kernel,
7162 cd6f1169 bellard
    QEMU_OPTION_append,
7163 cd6f1169 bellard
    QEMU_OPTION_initrd,
7164 cd6f1169 bellard
7165 cd6f1169 bellard
    QEMU_OPTION_S,
7166 cd6f1169 bellard
    QEMU_OPTION_s,
7167 cd6f1169 bellard
    QEMU_OPTION_p,
7168 cd6f1169 bellard
    QEMU_OPTION_d,
7169 cd6f1169 bellard
    QEMU_OPTION_hdachs,
7170 cd6f1169 bellard
    QEMU_OPTION_L,
7171 1192dad8 j_mayer
    QEMU_OPTION_bios,
7172 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
7173 3d11d0eb bellard
    QEMU_OPTION_k,
7174 ee22c2f7 bellard
    QEMU_OPTION_localtime,
7175 1f04275e bellard
    QEMU_OPTION_cirrusvga,
7176 d34cab9f ths
    QEMU_OPTION_vmsvga,
7177 e9b137c2 bellard
    QEMU_OPTION_g,
7178 1bfe856e bellard
    QEMU_OPTION_std_vga,
7179 20d8a3ed ths
    QEMU_OPTION_echr,
7180 82c643ff bellard
    QEMU_OPTION_monitor,
7181 82c643ff bellard
    QEMU_OPTION_serial,
7182 6508fe59 bellard
    QEMU_OPTION_parallel,
7183 d63d307f bellard
    QEMU_OPTION_loadvm,
7184 d63d307f bellard
    QEMU_OPTION_full_screen,
7185 43523e93 ths
    QEMU_OPTION_no_frame,
7186 3780e197 ths
    QEMU_OPTION_alt_grab,
7187 667accab ths
    QEMU_OPTION_no_quit,
7188 f7cce898 bellard
    QEMU_OPTION_pidfile,
7189 d993e026 bellard
    QEMU_OPTION_no_kqemu,
7190 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
7191 a09db21f bellard
    QEMU_OPTION_win2k_hack,
7192 bb36d470 bellard
    QEMU_OPTION_usb,
7193 a594cfbf bellard
    QEMU_OPTION_usbdevice,
7194 6a00d601 bellard
    QEMU_OPTION_smp,
7195 24236869 bellard
    QEMU_OPTION_vnc,
7196 6515b203 bellard
    QEMU_OPTION_no_acpi,
7197 d1beab82 bellard
    QEMU_OPTION_no_reboot,
7198 9467cd46 balrog
    QEMU_OPTION_show_cursor,
7199 71e3ceb8 ths
    QEMU_OPTION_daemonize,
7200 9ae02555 ths
    QEMU_OPTION_option_rom,
7201 c35734b2 ths
    QEMU_OPTION_semihosting,
7202 c35734b2 ths
    QEMU_OPTION_name,
7203 66508601 blueswir1
    QEMU_OPTION_prom_env,
7204 2b8f2d41 balrog
    QEMU_OPTION_old_param,
7205 f3dcfada ths
    QEMU_OPTION_clock,
7206 cd6f1169 bellard
};
7207 cd6f1169 bellard
7208 cd6f1169 bellard
typedef struct QEMUOption {
7209 cd6f1169 bellard
    const char *name;
7210 cd6f1169 bellard
    int flags;
7211 cd6f1169 bellard
    int index;
7212 cd6f1169 bellard
} QEMUOption;
7213 cd6f1169 bellard
7214 cd6f1169 bellard
const QEMUOption qemu_options[] = {
7215 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
7216 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
7217 cd6f1169 bellard
7218 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
7219 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
7220 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
7221 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7222 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
7223 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7224 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7225 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
7226 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
7227 3e3d5815 balrog
    { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
7228 a1bb27b1 pbrook
    { "sd", HAS_ARG, QEMU_OPTION_sd },
7229 86f55663 j_mayer
    { "pflash", HAS_ARG, QEMU_OPTION_pflash },
7230 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
7231 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
7232 52ca8d6a bellard
#ifdef TARGET_I386
7233 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7234 52ca8d6a bellard
#endif
7235 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
7236 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
7237 a171fe39 balrog
    { "portrait", 0, QEMU_OPTION_portrait },
7238 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
7239 1d14ffa9 bellard
#ifdef HAS_AUDIO
7240 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
7241 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7242 1d14ffa9 bellard
#endif
7243 cd6f1169 bellard
7244 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
7245 158156d1 bellard
#ifdef CONFIG_SLIRP
7246 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
7247 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
7248 c94c8d64 bellard
#ifndef _WIN32
7249 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
7250 c94c8d64 bellard
#endif
7251 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
7252 158156d1 bellard
#endif
7253 cd6f1169 bellard
7254 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7255 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
7256 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7257 cd6f1169 bellard
7258 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
7259 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
7260 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
7261 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
7262 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7263 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
7264 1192dad8 j_mayer
    { "bios", HAS_ARG, QEMU_OPTION_bios },
7265 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
7266 d993e026 bellard
#ifdef USE_KQEMU
7267 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
7268 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
7269 d993e026 bellard
#endif
7270 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7271 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
7272 77d4bc34 bellard
#endif
7273 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
7274 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
7275 8b6e0729 balrog
    { "echr", HAS_ARG, QEMU_OPTION_echr },
7276 8b6e0729 balrog
    { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7277 8b6e0729 balrog
    { "serial", HAS_ARG, QEMU_OPTION_serial },
7278 8b6e0729 balrog
    { "parallel", HAS_ARG, QEMU_OPTION_parallel },
7279 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7280 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
7281 667accab ths
#ifdef CONFIG_SDL
7282 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
7283 3780e197 ths
    { "alt-grab", 0, QEMU_OPTION_alt_grab },
7284 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
7285 667accab ths
#endif
7286 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
7287 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
7288 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
7289 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
7290 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
7291 96d30e48 ths
7292 1f04275e bellard
    /* temporary options */
7293 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
7294 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
7295 d34cab9f ths
    { "vmwarevga", 0, QEMU_OPTION_vmsvga },
7296 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
7297 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
7298 9467cd46 balrog
    { "show-cursor", 0, QEMU_OPTION_show_cursor },
7299 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
7300 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
7301 a87295e8 pbrook
#if defined(TARGET_ARM) || defined(TARGET_M68K)
7302 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
7303 8e71621f pbrook
#endif
7304 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
7305 66508601 blueswir1
#if defined(TARGET_SPARC)
7306 66508601 blueswir1
    { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
7307 66508601 blueswir1
#endif
7308 2b8f2d41 balrog
#if defined(TARGET_ARM)
7309 2b8f2d41 balrog
    { "old-param", 0, QEMU_OPTION_old_param },
7310 2b8f2d41 balrog
#endif
7311 f3dcfada ths
    { "clock", HAS_ARG, QEMU_OPTION_clock },
7312 cd6f1169 bellard
    { NULL },
7313 fc01f7e7 bellard
};
7314 fc01f7e7 bellard
7315 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
7316 77fef8c1 bellard
7317 77fef8c1 bellard
/* this stack is only used during signal handling */
7318 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
7319 77fef8c1 bellard
7320 77fef8c1 bellard
static uint8_t *signal_stack;
7321 77fef8c1 bellard
7322 77fef8c1 bellard
#endif
7323 77fef8c1 bellard
7324 5905b2e5 bellard
/* password input */
7325 5905b2e5 bellard
7326 2bac6019 balrog
int qemu_key_check(BlockDriverState *bs, const char *name)
7327 2bac6019 balrog
{
7328 2bac6019 balrog
    char password[256];
7329 2bac6019 balrog
    int i;
7330 2bac6019 balrog
7331 2bac6019 balrog
    if (!bdrv_is_encrypted(bs))
7332 2bac6019 balrog
        return 0;
7333 2bac6019 balrog
7334 2bac6019 balrog
    term_printf("%s is encrypted.\n", name);
7335 2bac6019 balrog
    for(i = 0; i < 3; i++) {
7336 2bac6019 balrog
        monitor_readline("Password: ", 1, password, sizeof(password));
7337 2bac6019 balrog
        if (bdrv_set_key(bs, password) == 0)
7338 2bac6019 balrog
            return 0;
7339 2bac6019 balrog
        term_printf("invalid password\n");
7340 2bac6019 balrog
    }
7341 2bac6019 balrog
    return -EPERM;
7342 2bac6019 balrog
}
7343 2bac6019 balrog
7344 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
7345 5905b2e5 bellard
{
7346 5905b2e5 bellard
    BlockDriverState *bs;
7347 5905b2e5 bellard
7348 5905b2e5 bellard
    if (index < 4) {
7349 5905b2e5 bellard
        bs = bs_table[index];
7350 5905b2e5 bellard
    } else if (index < 6) {
7351 5905b2e5 bellard
        bs = fd_table[index - 4];
7352 5905b2e5 bellard
    } else {
7353 5905b2e5 bellard
        bs = NULL;
7354 5905b2e5 bellard
    }
7355 5905b2e5 bellard
    return bs;
7356 5905b2e5 bellard
}
7357 5905b2e5 bellard
7358 5905b2e5 bellard
static void read_passwords(void)
7359 5905b2e5 bellard
{
7360 5905b2e5 bellard
    BlockDriverState *bs;
7361 2bac6019 balrog
    int i;
7362 5905b2e5 bellard
7363 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
7364 5905b2e5 bellard
        bs = get_bdrv(i);
7365 2bac6019 balrog
        if (bs)
7366 2bac6019 balrog
            qemu_key_check(bs, bdrv_get_device_name(bs));
7367 5905b2e5 bellard
    }
7368 5905b2e5 bellard
}
7369 5905b2e5 bellard
7370 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
7371 cc1daa40 bellard
void register_machines(void)
7372 cc1daa40 bellard
{
7373 cc1daa40 bellard
#if defined(TARGET_I386)
7374 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
7375 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
7376 cc1daa40 bellard
#elif defined(TARGET_PPC)
7377 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
7378 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
7379 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
7380 1a6c0886 j_mayer
    qemu_register_machine(&ref405ep_machine);
7381 1a6c0886 j_mayer
    qemu_register_machine(&taihu_machine);
7382 6af0bf9c bellard
#elif defined(TARGET_MIPS)
7383 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
7384 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
7385 ad6fe1d2 ths
    qemu_register_machine(&mips_pica61_machine);
7386 6bf5b4e8 ths
    qemu_register_machine(&mips_mipssim_machine);
7387 cc1daa40 bellard
#elif defined(TARGET_SPARC)
7388 3475187d bellard
#ifdef TARGET_SPARC64
7389 3475187d bellard
    qemu_register_machine(&sun4u_machine);
7390 3475187d bellard
#else
7391 36cd9210 blueswir1
    qemu_register_machine(&ss5_machine);
7392 e0353fe2 blueswir1
    qemu_register_machine(&ss10_machine);
7393 cc1daa40 bellard
#endif
7394 b5ff1b31 bellard
#elif defined(TARGET_ARM)
7395 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
7396 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
7397 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
7398 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
7399 b00052e4 balrog
    qemu_register_machine(&akitapda_machine);
7400 b00052e4 balrog
    qemu_register_machine(&spitzpda_machine);
7401 b00052e4 balrog
    qemu_register_machine(&borzoipda_machine);
7402 b00052e4 balrog
    qemu_register_machine(&terrierpda_machine);
7403 c3d2689d balrog
    qemu_register_machine(&palmte_machine);
7404 27c7ca7e bellard
#elif defined(TARGET_SH4)
7405 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
7406 0d78f544 ths
    qemu_register_machine(&r2d_machine);
7407 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
7408 eddf68a6 j_mayer
    /* XXX: TODO */
7409 0633879f pbrook
#elif defined(TARGET_M68K)
7410 20dcee94 pbrook
    qemu_register_machine(&mcf5208evb_machine);
7411 0633879f pbrook
    qemu_register_machine(&an5206_machine);
7412 f1ccf904 ths
#elif defined(TARGET_CRIS)
7413 f1ccf904 ths
    qemu_register_machine(&bareetraxfs_machine);
7414 b5ff1b31 bellard
#else
7415 b5ff1b31 bellard
#error unsupported CPU
7416 3475187d bellard
#endif
7417 cc1daa40 bellard
}
7418 cc1daa40 bellard
7419 1d14ffa9 bellard
#ifdef HAS_AUDIO
7420 6a36d84e bellard
struct soundhw soundhw[] = {
7421 b00052e4 balrog
#ifdef HAS_AUDIO_CHOICE
7422 fd06c375 bellard
#ifdef TARGET_I386
7423 fd06c375 bellard
    {
7424 fd06c375 bellard
        "pcspk",
7425 fd06c375 bellard
        "PC speaker",
7426 fd06c375 bellard
        0,
7427 fd06c375 bellard
        1,
7428 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
7429 fd06c375 bellard
    },
7430 fd06c375 bellard
#endif
7431 6a36d84e bellard
    {
7432 6a36d84e bellard
        "sb16",
7433 6a36d84e bellard
        "Creative Sound Blaster 16",
7434 6a36d84e bellard
        0,
7435 6a36d84e bellard
        1,
7436 6a36d84e bellard
        { .init_isa = SB16_init }
7437 6a36d84e bellard
    },
7438 6a36d84e bellard
7439 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
7440 6a36d84e bellard
    {
7441 6a36d84e bellard
        "adlib",
7442 1d14ffa9 bellard
#ifdef HAS_YMF262
7443 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
7444 1d14ffa9 bellard
#else
7445 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
7446 1d14ffa9 bellard
#endif
7447 6a36d84e bellard
        0,
7448 6a36d84e bellard
        1,
7449 6a36d84e bellard
        { .init_isa = Adlib_init }
7450 6a36d84e bellard
    },
7451 1d14ffa9 bellard
#endif
7452 6a36d84e bellard
7453 1d14ffa9 bellard
#ifdef CONFIG_GUS
7454 6a36d84e bellard
    {
7455 6a36d84e bellard
        "gus",
7456 6a36d84e bellard
        "Gravis Ultrasound GF1",
7457 6a36d84e bellard
        0,
7458 6a36d84e bellard
        1,
7459 6a36d84e bellard
        { .init_isa = GUS_init }
7460 6a36d84e bellard
    },
7461 1d14ffa9 bellard
#endif
7462 6a36d84e bellard
7463 6a36d84e bellard
    {
7464 6a36d84e bellard
        "es1370",
7465 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
7466 6a36d84e bellard
        0,
7467 6a36d84e bellard
        0,
7468 6a36d84e bellard
        { .init_pci = es1370_init }
7469 6a36d84e bellard
    },
7470 b00052e4 balrog
#endif
7471 6a36d84e bellard
7472 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
7473 6a36d84e bellard
};
7474 6a36d84e bellard
7475 6a36d84e bellard
static void select_soundhw (const char *optarg)
7476 6a36d84e bellard
{
7477 6a36d84e bellard
    struct soundhw *c;
7478 6a36d84e bellard
7479 6a36d84e bellard
    if (*optarg == '?') {
7480 6a36d84e bellard
    show_valid_cards:
7481 6a36d84e bellard
7482 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
7483 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
7484 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
7485 6a36d84e bellard
        }
7486 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
7487 1d14ffa9 bellard
        exit (*optarg != '?');
7488 1d14ffa9 bellard
    }
7489 1d14ffa9 bellard
    else {
7490 6a36d84e bellard
        size_t l;
7491 1d14ffa9 bellard
        const char *p;
7492 1d14ffa9 bellard
        char *e;
7493 1d14ffa9 bellard
        int bad_card = 0;
7494 1d14ffa9 bellard
7495 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
7496 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7497 6a36d84e bellard
                c->enabled = 1;
7498 6a36d84e bellard
            }
7499 6a36d84e bellard
            return;
7500 6a36d84e bellard
        }
7501 1d14ffa9 bellard
7502 6a36d84e bellard
        p = optarg;
7503 1d14ffa9 bellard
        while (*p) {
7504 1d14ffa9 bellard
            e = strchr (p, ',');
7505 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
7506 6a36d84e bellard
7507 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7508 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
7509 6a36d84e bellard
                    c->enabled = 1;
7510 1d14ffa9 bellard
                    break;
7511 1d14ffa9 bellard
                }
7512 1d14ffa9 bellard
            }
7513 6a36d84e bellard
7514 6a36d84e bellard
            if (!c->name) {
7515 1d14ffa9 bellard
                if (l > 80) {
7516 1d14ffa9 bellard
                    fprintf (stderr,
7517 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
7518 1d14ffa9 bellard
                }
7519 1d14ffa9 bellard
                else {
7520 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
7521 1d14ffa9 bellard
                             (int) l, p);
7522 1d14ffa9 bellard
                }
7523 1d14ffa9 bellard
                bad_card = 1;
7524 1d14ffa9 bellard
            }
7525 1d14ffa9 bellard
            p += l + (e != NULL);
7526 1d14ffa9 bellard
        }
7527 1d14ffa9 bellard
7528 1d14ffa9 bellard
        if (bad_card)
7529 1d14ffa9 bellard
            goto show_valid_cards;
7530 1d14ffa9 bellard
    }
7531 1d14ffa9 bellard
}
7532 1d14ffa9 bellard
#endif
7533 1d14ffa9 bellard
7534 3587d7e6 bellard
#ifdef _WIN32
7535 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
7536 3587d7e6 bellard
{
7537 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
7538 3587d7e6 bellard
    return TRUE;
7539 3587d7e6 bellard
}
7540 3587d7e6 bellard
#endif
7541 3587d7e6 bellard
7542 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
7543 c20709aa bellard
7544 0824d6fc bellard
int main(int argc, char **argv)
7545 0824d6fc bellard
{
7546 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7547 cfc3475a pbrook
    int use_gdbstub;
7548 cfc3475a pbrook
    const char *gdbstub_port;
7549 67b915a5 bellard
#endif
7550 86f55663 j_mayer
    int i, cdrom_index, pflash_index;
7551 1ccde1cb bellard
    int snapshot, linux_boot;
7552 7f7f9873 bellard
    const char *initrd_filename;
7553 96d30e48 ths
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
7554 86f55663 j_mayer
    const char *pflash_filename[MAX_PFLASH];
7555 a1bb27b1 pbrook
    const char *sd_filename;
7556 3e3d5815 balrog
    const char *mtd_filename;
7557 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
7558 313aa567 bellard
    DisplayState *ds = &display_state;
7559 46d4767d bellard
    int cyls, heads, secs, translation;
7560 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
7561 7c9d8e07 bellard
    int nb_net_clients;
7562 cd6f1169 bellard
    int optind;
7563 cd6f1169 bellard
    const char *r, *optarg;
7564 82c643ff bellard
    CharDriverState *monitor_hd;
7565 82c643ff bellard
    char monitor_device[128];
7566 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
7567 8d11df9e bellard
    int serial_device_index;
7568 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
7569 6508fe59 bellard
    int parallel_device_index;
7570 d63d307f bellard
    const char *loadvm = NULL;
7571 cc1daa40 bellard
    QEMUMachine *machine;
7572 94fc95cd j_mayer
    const char *cpu_model;
7573 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
7574 a594cfbf bellard
    int usb_devices_index;
7575 71e3ceb8 ths
    int fds[2];
7576 93815bc2 ths
    const char *pid_file = NULL;
7577 833c7174 blueswir1
    VLANState *vlan;
7578 0bd48850 bellard
7579 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
7580 be995c27 bellard
#ifndef _WIN32
7581 be995c27 bellard
    {
7582 be995c27 bellard
        struct sigaction act;
7583 be995c27 bellard
        sigfillset(&act.sa_mask);
7584 be995c27 bellard
        act.sa_flags = 0;
7585 be995c27 bellard
        act.sa_handler = SIG_IGN;
7586 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
7587 be995c27 bellard
    }
7588 3587d7e6 bellard
#else
7589 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
7590 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
7591 a8e5ac33 bellard
       QEMU to run on a single CPU */
7592 a8e5ac33 bellard
    {
7593 a8e5ac33 bellard
        HANDLE h;
7594 a8e5ac33 bellard
        DWORD mask, smask;
7595 a8e5ac33 bellard
        int i;
7596 a8e5ac33 bellard
        h = GetCurrentProcess();
7597 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
7598 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
7599 a8e5ac33 bellard
                if (mask & (1 << i))
7600 a8e5ac33 bellard
                    break;
7601 a8e5ac33 bellard
            }
7602 a8e5ac33 bellard
            if (i != 32) {
7603 a8e5ac33 bellard
                mask = 1 << i;
7604 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
7605 a8e5ac33 bellard
            }
7606 a8e5ac33 bellard
        }
7607 a8e5ac33 bellard
    }
7608 67b915a5 bellard
#endif
7609 be995c27 bellard
7610 cc1daa40 bellard
    register_machines();
7611 cc1daa40 bellard
    machine = first_machine;
7612 94fc95cd j_mayer
    cpu_model = NULL;
7613 fc01f7e7 bellard
    initrd_filename = NULL;
7614 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
7615 c45886db bellard
        fd_filename[i] = NULL;
7616 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++)
7617 96d30e48 ths
        hd_filename[i] = NULL;
7618 86f55663 j_mayer
    for(i = 0; i < MAX_PFLASH; i++)
7619 86f55663 j_mayer
        pflash_filename[i] = NULL;
7620 86f55663 j_mayer
    pflash_index = 0;
7621 a1bb27b1 pbrook
    sd_filename = NULL;
7622 3e3d5815 balrog
    mtd_filename = NULL;
7623 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
7624 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
7625 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7626 b4608c04 bellard
    use_gdbstub = 0;
7627 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
7628 67b915a5 bellard
#endif
7629 33e3963e bellard
    snapshot = 0;
7630 a20dd508 bellard
    nographic = 0;
7631 a20dd508 bellard
    kernel_filename = NULL;
7632 a20dd508 bellard
    kernel_cmdline = "";
7633 cc1daa40 bellard
#ifdef TARGET_PPC
7634 cc1daa40 bellard
    cdrom_index = 1;
7635 cc1daa40 bellard
#else
7636 cc1daa40 bellard
    cdrom_index = 2;
7637 cc1daa40 bellard
#endif
7638 c4b1fcc0 bellard
    cyls = heads = secs = 0;
7639 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
7640 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
7641 c4b1fcc0 bellard
7642 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
7643 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
7644 8d11df9e bellard
        serial_devices[i][0] = '\0';
7645 8d11df9e bellard
    serial_device_index = 0;
7646 3b46e624 ths
7647 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
7648 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
7649 6508fe59 bellard
        parallel_devices[i][0] = '\0';
7650 6508fe59 bellard
    parallel_device_index = 0;
7651 3b46e624 ths
7652 a594cfbf bellard
    usb_devices_index = 0;
7653 3b46e624 ths
7654 7c9d8e07 bellard
    nb_net_clients = 0;
7655 7c9d8e07 bellard
7656 7c9d8e07 bellard
    nb_nics = 0;
7657 702c651c bellard
    /* default mac address of the first network interface */
7658 3b46e624 ths
7659 cd6f1169 bellard
    optind = 1;
7660 0824d6fc bellard
    for(;;) {
7661 cd6f1169 bellard
        if (optind >= argc)
7662 0824d6fc bellard
            break;
7663 cd6f1169 bellard
        r = argv[optind];
7664 cd6f1169 bellard
        if (r[0] != '-') {
7665 96d30e48 ths
            hd_filename[0] = argv[optind++];
7666 cd6f1169 bellard
        } else {
7667 cd6f1169 bellard
            const QEMUOption *popt;
7668 cd6f1169 bellard
7669 cd6f1169 bellard
            optind++;
7670 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
7671 dff5efc8 pbrook
            if (r[1] == '-')
7672 dff5efc8 pbrook
                r++;
7673 cd6f1169 bellard
            popt = qemu_options;
7674 cd6f1169 bellard
            for(;;) {
7675 cd6f1169 bellard
                if (!popt->name) {
7676 5fafdf24 ths
                    fprintf(stderr, "%s: invalid option -- '%s'\n",
7677 cd6f1169 bellard
                            argv[0], r);
7678 cd6f1169 bellard
                    exit(1);
7679 cd6f1169 bellard
                }
7680 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
7681 cd6f1169 bellard
                    break;
7682 cd6f1169 bellard
                popt++;
7683 cd6f1169 bellard
            }
7684 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
7685 cd6f1169 bellard
                if (optind >= argc) {
7686 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
7687 cd6f1169 bellard
                            argv[0], r);
7688 cd6f1169 bellard
                    exit(1);
7689 cd6f1169 bellard
                }
7690 cd6f1169 bellard
                optarg = argv[optind++];
7691 cd6f1169 bellard
            } else {
7692 cd6f1169 bellard
                optarg = NULL;
7693 cd6f1169 bellard
            }
7694 cd6f1169 bellard
7695 cd6f1169 bellard
            switch(popt->index) {
7696 cc1daa40 bellard
            case QEMU_OPTION_M:
7697 cc1daa40 bellard
                machine = find_machine(optarg);
7698 cc1daa40 bellard
                if (!machine) {
7699 cc1daa40 bellard
                    QEMUMachine *m;
7700 cc1daa40 bellard
                    printf("Supported machines are:\n");
7701 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
7702 cc1daa40 bellard
                        printf("%-10s %s%s\n",
7703 5fafdf24 ths
                               m->name, m->desc,
7704 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
7705 cc1daa40 bellard
                    }
7706 15f82208 ths
                    exit(*optarg != '?');
7707 cc1daa40 bellard
                }
7708 cc1daa40 bellard
                break;
7709 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
7710 94fc95cd j_mayer
                /* hw initialization will check this */
7711 15f82208 ths
                if (*optarg == '?') {
7712 c732abe2 j_mayer
/* XXX: implement xxx_cpu_list for targets that still miss it */
7713 c732abe2 j_mayer
#if defined(cpu_list)
7714 c732abe2 j_mayer
                    cpu_list(stdout, &fprintf);
7715 94fc95cd j_mayer
#endif
7716 15f82208 ths
                    exit(0);
7717 94fc95cd j_mayer
                } else {
7718 94fc95cd j_mayer
                    cpu_model = optarg;
7719 94fc95cd j_mayer
                }
7720 94fc95cd j_mayer
                break;
7721 cd6f1169 bellard
            case QEMU_OPTION_initrd:
7722 fc01f7e7 bellard
                initrd_filename = optarg;
7723 fc01f7e7 bellard
                break;
7724 cd6f1169 bellard
            case QEMU_OPTION_hda:
7725 cd6f1169 bellard
            case QEMU_OPTION_hdb:
7726 cc1daa40 bellard
            case QEMU_OPTION_hdc:
7727 cc1daa40 bellard
            case QEMU_OPTION_hdd:
7728 cc1daa40 bellard
                {
7729 cc1daa40 bellard
                    int hd_index;
7730 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
7731 96d30e48 ths
                    hd_filename[hd_index] = optarg;
7732 96d30e48 ths
                    if (hd_index == cdrom_index)
7733 96d30e48 ths
                        cdrom_index = -1;
7734 cc1daa40 bellard
                }
7735 fc01f7e7 bellard
                break;
7736 3e3d5815 balrog
            case QEMU_OPTION_mtdblock:
7737 3e3d5815 balrog
                mtd_filename = optarg;
7738 3e3d5815 balrog
                break;
7739 a1bb27b1 pbrook
            case QEMU_OPTION_sd:
7740 a1bb27b1 pbrook
                sd_filename = optarg;
7741 a1bb27b1 pbrook
                break;
7742 86f55663 j_mayer
            case QEMU_OPTION_pflash:
7743 86f55663 j_mayer
                if (pflash_index >= MAX_PFLASH) {
7744 86f55663 j_mayer
                    fprintf(stderr, "qemu: too many parallel flash images\n");
7745 86f55663 j_mayer
                    exit(1);
7746 86f55663 j_mayer
                }
7747 86f55663 j_mayer
                pflash_filename[pflash_index++] = optarg;
7748 86f55663 j_mayer
                break;
7749 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
7750 33e3963e bellard
                snapshot = 1;
7751 33e3963e bellard
                break;
7752 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
7753 330d0414 bellard
                {
7754 330d0414 bellard
                    const char *p;
7755 330d0414 bellard
                    p = optarg;
7756 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
7757 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
7758 46d4767d bellard
                        goto chs_fail;
7759 330d0414 bellard
                    if (*p != ',')
7760 330d0414 bellard
                        goto chs_fail;
7761 330d0414 bellard
                    p++;
7762 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
7763 46d4767d bellard
                    if (heads < 1 || heads > 16)
7764 46d4767d bellard
                        goto chs_fail;
7765 330d0414 bellard
                    if (*p != ',')
7766 330d0414 bellard
                        goto chs_fail;
7767 330d0414 bellard
                    p++;
7768 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
7769 46d4767d bellard
                    if (secs < 1 || secs > 63)
7770 46d4767d bellard
                        goto chs_fail;
7771 46d4767d bellard
                    if (*p == ',') {
7772 46d4767d bellard
                        p++;
7773 46d4767d bellard
                        if (!strcmp(p, "none"))
7774 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
7775 46d4767d bellard
                        else if (!strcmp(p, "lba"))
7776 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
7777 46d4767d bellard
                        else if (!strcmp(p, "auto"))
7778 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
7779 46d4767d bellard
                        else
7780 46d4767d bellard
                            goto chs_fail;
7781 46d4767d bellard
                    } else if (*p != '\0') {
7782 c4b1fcc0 bellard
                    chs_fail:
7783 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
7784 46d4767d bellard
                        exit(1);
7785 c4b1fcc0 bellard
                    }
7786 330d0414 bellard
                }
7787 330d0414 bellard
                break;
7788 cd6f1169 bellard
            case QEMU_OPTION_nographic:
7789 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
7790 a39437aa ths
                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
7791 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
7792 a20dd508 bellard
                nographic = 1;
7793 a20dd508 bellard
                break;
7794 a171fe39 balrog
            case QEMU_OPTION_portrait:
7795 a171fe39 balrog
                graphic_rotate = 1;
7796 a171fe39 balrog
                break;
7797 cd6f1169 bellard
            case QEMU_OPTION_kernel:
7798 a20dd508 bellard
                kernel_filename = optarg;
7799 a20dd508 bellard
                break;
7800 cd6f1169 bellard
            case QEMU_OPTION_append:
7801 a20dd508 bellard
                kernel_cmdline = optarg;
7802 313aa567 bellard
                break;
7803 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
7804 96d30e48 ths
                if (cdrom_index >= 0) {
7805 96d30e48 ths
                    hd_filename[cdrom_index] = optarg;
7806 fa1fb14c ths
                }
7807 36b486bb bellard
                break;
7808 cd6f1169 bellard
            case QEMU_OPTION_boot:
7809 36b486bb bellard
                boot_device = optarg[0];
7810 5fafdf24 ths
                if (boot_device != 'a' &&
7811 eec85c2a ths
#if defined(TARGET_SPARC) || defined(TARGET_I386)
7812 6f7e9aec bellard
                    // Network boot
7813 6f7e9aec bellard
                    boot_device != 'n' &&
7814 6f7e9aec bellard
#endif
7815 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
7816 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
7817 36b486bb bellard
                    exit(1);
7818 36b486bb bellard
                }
7819 36b486bb bellard
                break;
7820 cd6f1169 bellard
            case QEMU_OPTION_fda:
7821 c45886db bellard
                fd_filename[0] = optarg;
7822 c45886db bellard
                break;
7823 cd6f1169 bellard
            case QEMU_OPTION_fdb:
7824 c45886db bellard
                fd_filename[1] = optarg;
7825 c45886db bellard
                break;
7826 52ca8d6a bellard
#ifdef TARGET_I386
7827 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
7828 52ca8d6a bellard
                fd_bootchk = 0;
7829 52ca8d6a bellard
                break;
7830 52ca8d6a bellard
#endif
7831 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
7832 77fef8c1 bellard
                code_copy_enabled = 0;
7833 77fef8c1 bellard
                break;
7834 7c9d8e07 bellard
            case QEMU_OPTION_net:
7835 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
7836 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
7837 c4b1fcc0 bellard
                    exit(1);
7838 c4b1fcc0 bellard
                }
7839 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
7840 7c9d8e07 bellard
                        sizeof(net_clients[0]),
7841 7c9d8e07 bellard
                        optarg);
7842 7c9d8e07 bellard
                nb_net_clients++;
7843 702c651c bellard
                break;
7844 c7f74643 bellard
#ifdef CONFIG_SLIRP
7845 c7f74643 bellard
            case QEMU_OPTION_tftp:
7846 c7f74643 bellard
                tftp_prefix = optarg;
7847 9bf05444 bellard
                break;
7848 47d5d01a ths
            case QEMU_OPTION_bootp:
7849 47d5d01a ths
                bootp_filename = optarg;
7850 47d5d01a ths
                break;
7851 c94c8d64 bellard
#ifndef _WIN32
7852 9d728e8c bellard
            case QEMU_OPTION_smb:
7853 9d728e8c bellard
                net_slirp_smb(optarg);
7854 9d728e8c bellard
                break;
7855 c94c8d64 bellard
#endif
7856 9bf05444 bellard
            case QEMU_OPTION_redir:
7857 3b46e624 ths
                net_slirp_redir(optarg);
7858 9bf05444 bellard
                break;
7859 c7f74643 bellard
#endif
7860 1d14ffa9 bellard
#ifdef HAS_AUDIO
7861 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
7862 1d14ffa9 bellard
                AUD_help ();
7863 1d14ffa9 bellard
                exit (0);
7864 1d14ffa9 bellard
                break;
7865 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
7866 1d14ffa9 bellard
                select_soundhw (optarg);
7867 1d14ffa9 bellard
                break;
7868 1d14ffa9 bellard
#endif
7869 cd6f1169 bellard
            case QEMU_OPTION_h:
7870 15f82208 ths
                help(0);
7871 cd6f1169 bellard
                break;
7872 cd6f1169 bellard
            case QEMU_OPTION_m:
7873 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
7874 cd6f1169 bellard
                if (ram_size <= 0)
7875 15f82208 ths
                    help(1);
7876 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
7877 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
7878 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
7879 cd6f1169 bellard
                    exit(1);
7880 cd6f1169 bellard
                }
7881 cd6f1169 bellard
                break;
7882 cd6f1169 bellard
            case QEMU_OPTION_d:
7883 cd6f1169 bellard
                {
7884 cd6f1169 bellard
                    int mask;
7885 cd6f1169 bellard
                    CPULogItem *item;
7886 3b46e624 ths
7887 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
7888 cd6f1169 bellard
                    if (!mask) {
7889 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
7890 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
7891 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
7892 f193c797 bellard
                    }
7893 f193c797 bellard
                    exit(1);
7894 cd6f1169 bellard
                    }
7895 cd6f1169 bellard
                    cpu_set_log(mask);
7896 f193c797 bellard
                }
7897 cd6f1169 bellard
                break;
7898 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7899 cd6f1169 bellard
            case QEMU_OPTION_s:
7900 cd6f1169 bellard
                use_gdbstub = 1;
7901 cd6f1169 bellard
                break;
7902 cd6f1169 bellard
            case QEMU_OPTION_p:
7903 cfc3475a pbrook
                gdbstub_port = optarg;
7904 cd6f1169 bellard
                break;
7905 67b915a5 bellard
#endif
7906 cd6f1169 bellard
            case QEMU_OPTION_L:
7907 cd6f1169 bellard
                bios_dir = optarg;
7908 cd6f1169 bellard
                break;
7909 1192dad8 j_mayer
            case QEMU_OPTION_bios:
7910 1192dad8 j_mayer
                bios_name = optarg;
7911 1192dad8 j_mayer
                break;
7912 cd6f1169 bellard
            case QEMU_OPTION_S:
7913 3c07f8e8 pbrook
                autostart = 0;
7914 cd6f1169 bellard
                break;
7915 3d11d0eb bellard
            case QEMU_OPTION_k:
7916 3d11d0eb bellard
                keyboard_layout = optarg;
7917 3d11d0eb bellard
                break;
7918 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
7919 ee22c2f7 bellard
                rtc_utc = 0;
7920 ee22c2f7 bellard
                break;
7921 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
7922 1f04275e bellard
                cirrus_vga_enabled = 1;
7923 d34cab9f ths
                vmsvga_enabled = 0;
7924 d34cab9f ths
                break;
7925 d34cab9f ths
            case QEMU_OPTION_vmsvga:
7926 d34cab9f ths
                cirrus_vga_enabled = 0;
7927 d34cab9f ths
                vmsvga_enabled = 1;
7928 1f04275e bellard
                break;
7929 1bfe856e bellard
            case QEMU_OPTION_std_vga:
7930 1bfe856e bellard
                cirrus_vga_enabled = 0;
7931 d34cab9f ths
                vmsvga_enabled = 0;
7932 1bfe856e bellard
                break;
7933 e9b137c2 bellard
            case QEMU_OPTION_g:
7934 e9b137c2 bellard
                {
7935 e9b137c2 bellard
                    const char *p;
7936 e9b137c2 bellard
                    int w, h, depth;
7937 e9b137c2 bellard
                    p = optarg;
7938 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
7939 e9b137c2 bellard
                    if (w <= 0) {
7940 e9b137c2 bellard
                    graphic_error:
7941 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
7942 e9b137c2 bellard
                        exit(1);
7943 e9b137c2 bellard
                    }
7944 e9b137c2 bellard
                    if (*p != 'x')
7945 e9b137c2 bellard
                        goto graphic_error;
7946 e9b137c2 bellard
                    p++;
7947 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
7948 e9b137c2 bellard
                    if (h <= 0)
7949 e9b137c2 bellard
                        goto graphic_error;
7950 e9b137c2 bellard
                    if (*p == 'x') {
7951 e9b137c2 bellard
                        p++;
7952 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
7953 5fafdf24 ths
                        if (depth != 8 && depth != 15 && depth != 16 &&
7954 e9b137c2 bellard
                            depth != 24 && depth != 32)
7955 e9b137c2 bellard
                            goto graphic_error;
7956 e9b137c2 bellard
                    } else if (*p == '\0') {
7957 e9b137c2 bellard
                        depth = graphic_depth;
7958 e9b137c2 bellard
                    } else {
7959 e9b137c2 bellard
                        goto graphic_error;
7960 e9b137c2 bellard
                    }
7961 3b46e624 ths
7962 e9b137c2 bellard
                    graphic_width = w;
7963 e9b137c2 bellard
                    graphic_height = h;
7964 e9b137c2 bellard
                    graphic_depth = depth;
7965 e9b137c2 bellard
                }
7966 e9b137c2 bellard
                break;
7967 20d8a3ed ths
            case QEMU_OPTION_echr:
7968 20d8a3ed ths
                {
7969 20d8a3ed ths
                    char *r;
7970 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
7971 20d8a3ed ths
                    if (r == optarg)
7972 20d8a3ed ths
                        printf("Bad argument to echr\n");
7973 20d8a3ed ths
                    break;
7974 20d8a3ed ths
                }
7975 82c643ff bellard
            case QEMU_OPTION_monitor:
7976 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
7977 82c643ff bellard
                break;
7978 82c643ff bellard
            case QEMU_OPTION_serial:
7979 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
7980 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
7981 8d11df9e bellard
                    exit(1);
7982 8d11df9e bellard
                }
7983 5fafdf24 ths
                pstrcpy(serial_devices[serial_device_index],
7984 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
7985 8d11df9e bellard
                serial_device_index++;
7986 82c643ff bellard
                break;
7987 6508fe59 bellard
            case QEMU_OPTION_parallel:
7988 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
7989 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
7990 6508fe59 bellard
                    exit(1);
7991 6508fe59 bellard
                }
7992 5fafdf24 ths
                pstrcpy(parallel_devices[parallel_device_index],
7993 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
7994 6508fe59 bellard
                parallel_device_index++;
7995 6508fe59 bellard
                break;
7996 d63d307f bellard
            case QEMU_OPTION_loadvm:
7997 d63d307f bellard
                loadvm = optarg;
7998 d63d307f bellard
                break;
7999 d63d307f bellard
            case QEMU_OPTION_full_screen:
8000 d63d307f bellard
                full_screen = 1;
8001 d63d307f bellard
                break;
8002 667accab ths
#ifdef CONFIG_SDL
8003 43523e93 ths
            case QEMU_OPTION_no_frame:
8004 43523e93 ths
                no_frame = 1;
8005 43523e93 ths
                break;
8006 3780e197 ths
            case QEMU_OPTION_alt_grab:
8007 3780e197 ths
                alt_grab = 1;
8008 3780e197 ths
                break;
8009 667accab ths
            case QEMU_OPTION_no_quit:
8010 667accab ths
                no_quit = 1;
8011 667accab ths
                break;
8012 667accab ths
#endif
8013 f7cce898 bellard
            case QEMU_OPTION_pidfile:
8014 93815bc2 ths
                pid_file = optarg;
8015 f7cce898 bellard
                break;
8016 a09db21f bellard
#ifdef TARGET_I386
8017 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
8018 a09db21f bellard
                win2k_install_hack = 1;
8019 a09db21f bellard
                break;
8020 a09db21f bellard
#endif
8021 d993e026 bellard
#ifdef USE_KQEMU
8022 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
8023 d993e026 bellard
                kqemu_allowed = 0;
8024 d993e026 bellard
                break;
8025 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
8026 89bfc105 bellard
                kqemu_allowed = 2;
8027 89bfc105 bellard
                break;
8028 d993e026 bellard
#endif
8029 bb36d470 bellard
            case QEMU_OPTION_usb:
8030 bb36d470 bellard
                usb_enabled = 1;
8031 bb36d470 bellard
                break;
8032 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
8033 a594cfbf bellard
                usb_enabled = 1;
8034 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
8035 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
8036 a594cfbf bellard
                    exit(1);
8037 a594cfbf bellard
                }
8038 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
8039 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
8040 a594cfbf bellard
                        optarg);
8041 a594cfbf bellard
                usb_devices_index++;
8042 a594cfbf bellard
                break;
8043 6a00d601 bellard
            case QEMU_OPTION_smp:
8044 6a00d601 bellard
                smp_cpus = atoi(optarg);
8045 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
8046 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
8047 6a00d601 bellard
                    exit(1);
8048 6a00d601 bellard
                }
8049 6a00d601 bellard
                break;
8050 24236869 bellard
            case QEMU_OPTION_vnc:
8051 73fc9742 ths
                vnc_display = optarg;
8052 24236869 bellard
                break;
8053 6515b203 bellard
            case QEMU_OPTION_no_acpi:
8054 6515b203 bellard
                acpi_enabled = 0;
8055 6515b203 bellard
                break;
8056 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
8057 d1beab82 bellard
                no_reboot = 1;
8058 d1beab82 bellard
                break;
8059 9467cd46 balrog
            case QEMU_OPTION_show_cursor:
8060 9467cd46 balrog
                cursor_hide = 0;
8061 9467cd46 balrog
                break;
8062 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
8063 71e3ceb8 ths
                daemonize = 1;
8064 71e3ceb8 ths
                break;
8065 9ae02555 ths
            case QEMU_OPTION_option_rom:
8066 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
8067 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
8068 9ae02555 ths
                    exit(1);
8069 9ae02555 ths
                }
8070 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
8071 9ae02555 ths
                nb_option_roms++;
8072 9ae02555 ths
                break;
8073 8e71621f pbrook
            case QEMU_OPTION_semihosting:
8074 8e71621f pbrook
                semihosting_enabled = 1;
8075 8e71621f pbrook
                break;
8076 c35734b2 ths
            case QEMU_OPTION_name:
8077 c35734b2 ths
                qemu_name = optarg;
8078 c35734b2 ths
                break;
8079 66508601 blueswir1
#ifdef TARGET_SPARC
8080 66508601 blueswir1
            case QEMU_OPTION_prom_env:
8081 66508601 blueswir1
                if (nb_prom_envs >= MAX_PROM_ENVS) {
8082 66508601 blueswir1
                    fprintf(stderr, "Too many prom variables\n");
8083 66508601 blueswir1
                    exit(1);
8084 66508601 blueswir1
                }
8085 66508601 blueswir1
                prom_envs[nb_prom_envs] = optarg;
8086 66508601 blueswir1
                nb_prom_envs++;
8087 66508601 blueswir1
                break;
8088 66508601 blueswir1
#endif
8089 2b8f2d41 balrog
#ifdef TARGET_ARM
8090 2b8f2d41 balrog
            case QEMU_OPTION_old_param:
8091 2b8f2d41 balrog
                old_param = 1;
8092 2b8f2d41 balrog
#endif
8093 f3dcfada ths
            case QEMU_OPTION_clock:
8094 f3dcfada ths
                configure_alarms(optarg);
8095 f3dcfada ths
                break;
8096 cd6f1169 bellard
            }
8097 0824d6fc bellard
        }
8098 0824d6fc bellard
    }
8099 330d0414 bellard
8100 71e3ceb8 ths
#ifndef _WIN32
8101 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
8102 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
8103 71e3ceb8 ths
        daemonize = 0;
8104 71e3ceb8 ths
    }
8105 71e3ceb8 ths
8106 71e3ceb8 ths
    if (daemonize) {
8107 71e3ceb8 ths
        pid_t pid;
8108 71e3ceb8 ths
8109 71e3ceb8 ths
        if (pipe(fds) == -1)
8110 71e3ceb8 ths
            exit(1);
8111 71e3ceb8 ths
8112 71e3ceb8 ths
        pid = fork();
8113 71e3ceb8 ths
        if (pid > 0) {
8114 71e3ceb8 ths
            uint8_t status;
8115 71e3ceb8 ths
            ssize_t len;
8116 71e3ceb8 ths
8117 71e3ceb8 ths
            close(fds[1]);
8118 71e3ceb8 ths
8119 71e3ceb8 ths
        again:
8120 93815bc2 ths
            len = read(fds[0], &status, 1);
8121 93815bc2 ths
            if (len == -1 && (errno == EINTR))
8122 93815bc2 ths
                goto again;
8123 93815bc2 ths
8124 93815bc2 ths
            if (len != 1)
8125 93815bc2 ths
                exit(1);
8126 93815bc2 ths
            else if (status == 1) {
8127 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
8128 93815bc2 ths
                exit(1);
8129 93815bc2 ths
            } else
8130 93815bc2 ths
                exit(0);
8131 71e3ceb8 ths
        } else if (pid < 0)
8132 93815bc2 ths
            exit(1);
8133 71e3ceb8 ths
8134 71e3ceb8 ths
        setsid();
8135 71e3ceb8 ths
8136 71e3ceb8 ths
        pid = fork();
8137 71e3ceb8 ths
        if (pid > 0)
8138 71e3ceb8 ths
            exit(0);
8139 71e3ceb8 ths
        else if (pid < 0)
8140 71e3ceb8 ths
            exit(1);
8141 71e3ceb8 ths
8142 71e3ceb8 ths
        umask(027);
8143 71e3ceb8 ths
        chdir("/");
8144 71e3ceb8 ths
8145 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
8146 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
8147 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
8148 71e3ceb8 ths
    }
8149 71e3ceb8 ths
#endif
8150 71e3ceb8 ths
8151 aa26bb2d ths
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
8152 93815bc2 ths
        if (daemonize) {
8153 93815bc2 ths
            uint8_t status = 1;
8154 93815bc2 ths
            write(fds[1], &status, 1);
8155 93815bc2 ths
        } else
8156 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
8157 93815bc2 ths
        exit(1);
8158 93815bc2 ths
    }
8159 93815bc2 ths
8160 ff3fbb30 bellard
#ifdef USE_KQEMU
8161 ff3fbb30 bellard
    if (smp_cpus > 1)
8162 ff3fbb30 bellard
        kqemu_allowed = 0;
8163 ff3fbb30 bellard
#endif
8164 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
8165 42550fde ths
8166 42550fde ths
    if (!linux_boot &&
8167 d84fe7ae ths
        boot_device != 'n' &&
8168 5fafdf24 ths
        hd_filename[0] == '\0' &&
8169 96d30e48 ths
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
8170 c45886db bellard
        fd_filename[0] == '\0')
8171 15f82208 ths
        help(1);
8172 0824d6fc bellard
8173 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
8174 96d30e48 ths
    if (hd_filename[0] == '\0' && boot_device == 'c') {
8175 96d30e48 ths
        if (fd_filename[0] != '\0')
8176 96d30e48 ths
            boot_device = 'a';
8177 96d30e48 ths
        else
8178 96d30e48 ths
            boot_device = 'd';
8179 96d30e48 ths
    }
8180 96d30e48 ths
8181 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
8182 3b46e624 ths
8183 634fce96 pbrook
    init_timers();
8184 634fce96 pbrook
    init_timer_alarm();
8185 83f64091 bellard
    qemu_aio_init();
8186 634fce96 pbrook
8187 fd1dff4b bellard
#ifdef _WIN32
8188 fd1dff4b bellard
    socket_init();
8189 fd1dff4b bellard
#endif
8190 fd1dff4b bellard
8191 7c9d8e07 bellard
    /* init network clients */
8192 7c9d8e07 bellard
    if (nb_net_clients == 0) {
8193 7c9d8e07 bellard
        /* if no clients, we use a default config */
8194 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
8195 7c9d8e07 bellard
                "nic");
8196 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
8197 7c9d8e07 bellard
                "user");
8198 7c9d8e07 bellard
        nb_net_clients = 2;
8199 c20709aa bellard
    }
8200 c20709aa bellard
8201 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
8202 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
8203 7c9d8e07 bellard
            exit(1);
8204 702c651c bellard
    }
8205 833c7174 blueswir1
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8206 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8207 833c7174 blueswir1
            continue;
8208 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0) {
8209 833c7174 blueswir1
            fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
8210 833c7174 blueswir1
            exit(1);
8211 833c7174 blueswir1
        }
8212 833c7174 blueswir1
        if (vlan->nb_host_devs == 0)
8213 833c7174 blueswir1
            fprintf(stderr,
8214 833c7174 blueswir1
                    "Warning: vlan %d is not connected to host network\n",
8215 833c7174 blueswir1
                    vlan->id);
8216 833c7174 blueswir1
    }
8217 f1510b2c bellard
8218 eec85c2a ths
#ifdef TARGET_I386
8219 eec85c2a ths
    if (boot_device == 'n') {
8220 eec85c2a ths
        for (i = 0; i < nb_nics; i++) {
8221 eec85c2a ths
            const char *model = nd_table[i].model;
8222 eec85c2a ths
            char buf[1024];
8223 eec85c2a ths
            if (model == NULL)
8224 eec85c2a ths
                model = "ne2k_pci";
8225 eec85c2a ths
            snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8226 eec85c2a ths
            if (get_image_size(buf) > 0) {
8227 eec85c2a ths
                option_rom[nb_option_roms] = strdup(buf);
8228 eec85c2a ths
                nb_option_roms++;
8229 eec85c2a ths
                break;
8230 eec85c2a ths
            }
8231 eec85c2a ths
        }
8232 eec85c2a ths
        if (i == nb_nics) {
8233 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
8234 eec85c2a ths
            exit(1);
8235 eec85c2a ths
        }
8236 eec85c2a ths
    }
8237 eec85c2a ths
#endif
8238 eec85c2a ths
8239 0824d6fc bellard
    /* init the memory */
8240 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
8241 9ae02555 ths
8242 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
8243 7f7f9873 bellard
    if (!phys_ram_base) {
8244 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
8245 0824d6fc bellard
        exit(1);
8246 0824d6fc bellard
    }
8247 0824d6fc bellard
8248 96d30e48 ths
    /* we always create the cdrom drive, even if no disk is there */
8249 5905b2e5 bellard
    bdrv_init();
8250 96d30e48 ths
    if (cdrom_index >= 0) {
8251 96d30e48 ths
        bs_table[cdrom_index] = bdrv_new("cdrom");
8252 96d30e48 ths
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
8253 c4b1fcc0 bellard
    }
8254 c4b1fcc0 bellard
8255 96d30e48 ths
    /* open the virtual block devices */
8256 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++) {
8257 96d30e48 ths
        if (hd_filename[i]) {
8258 96d30e48 ths
            if (!bs_table[i]) {
8259 96d30e48 ths
                char buf[64];
8260 96d30e48 ths
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
8261 96d30e48 ths
                bs_table[i] = bdrv_new(buf);
8262 96d30e48 ths
            }
8263 96d30e48 ths
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8264 96d30e48 ths
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
8265 96d30e48 ths
                        hd_filename[i]);
8266 96d30e48 ths
                exit(1);
8267 96d30e48 ths
            }
8268 96d30e48 ths
            if (i == 0 && cyls != 0) {
8269 96d30e48 ths
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
8270 96d30e48 ths
                bdrv_set_translation_hint(bs_table[i], translation);
8271 96d30e48 ths
            }
8272 96d30e48 ths
        }
8273 c4b1fcc0 bellard
    }
8274 c4b1fcc0 bellard
8275 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
8276 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
8277 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
8278 c4b1fcc0 bellard
8279 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
8280 c4b1fcc0 bellard
        if (fd_filename[i]) {
8281 c4b1fcc0 bellard
            if (!fd_table[i]) {
8282 c4b1fcc0 bellard
                char buf[64];
8283 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
8284 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
8285 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
8286 c4b1fcc0 bellard
            }
8287 a1bb27b1 pbrook
            if (fd_filename[i][0] != '\0') {
8288 83f64091 bellard
                if (bdrv_open(fd_table[i], fd_filename[i],
8289 83f64091 bellard
                              snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8290 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
8291 c4b1fcc0 bellard
                            fd_filename[i]);
8292 c4b1fcc0 bellard
                    exit(1);
8293 c4b1fcc0 bellard
                }
8294 c4b1fcc0 bellard
            }
8295 33e3963e bellard
        }
8296 33e3963e bellard
    }
8297 33e3963e bellard
8298 2bac6019 balrog
    /* Open the virtual parallel flash block devices */
8299 86f55663 j_mayer
    for(i = 0; i < MAX_PFLASH; i++) {
8300 86f55663 j_mayer
        if (pflash_filename[i]) {
8301 86f55663 j_mayer
            if (!pflash_table[i]) {
8302 86f55663 j_mayer
                char buf[64];
8303 86f55663 j_mayer
                snprintf(buf, sizeof(buf), "fl%c", i + 'a');
8304 86f55663 j_mayer
                pflash_table[i] = bdrv_new(buf);
8305 86f55663 j_mayer
            }
8306 86f55663 j_mayer
            if (bdrv_open(pflash_table[i], pflash_filename[i],
8307 86f55663 j_mayer
                          snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8308 86f55663 j_mayer
                fprintf(stderr, "qemu: could not open flash image '%s'\n",
8309 86f55663 j_mayer
                        pflash_filename[i]);
8310 86f55663 j_mayer
                exit(1);
8311 86f55663 j_mayer
            }
8312 86f55663 j_mayer
        }
8313 86f55663 j_mayer
    }
8314 86f55663 j_mayer
8315 a1bb27b1 pbrook
    sd_bdrv = bdrv_new ("sd");
8316 a1bb27b1 pbrook
    /* FIXME: This isn't really a floppy, but it's a reasonable
8317 a1bb27b1 pbrook
       approximation.  */
8318 a1bb27b1 pbrook
    bdrv_set_type_hint(sd_bdrv, BDRV_TYPE_FLOPPY);
8319 a1bb27b1 pbrook
    if (sd_filename) {
8320 a1bb27b1 pbrook
        if (bdrv_open(sd_bdrv, sd_filename,
8321 a1bb27b1 pbrook
                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8322 a1bb27b1 pbrook
            fprintf(stderr, "qemu: could not open SD card image %s\n",
8323 a1bb27b1 pbrook
                    sd_filename);
8324 2bac6019 balrog
        } else
8325 a171fe39 balrog
            qemu_key_check(sd_bdrv, sd_filename);
8326 a1bb27b1 pbrook
    }
8327 a1bb27b1 pbrook
8328 3e3d5815 balrog
    if (mtd_filename) {
8329 3e3d5815 balrog
        mtd_bdrv = bdrv_new ("mtd");
8330 3e3d5815 balrog
        if (bdrv_open(mtd_bdrv, mtd_filename,
8331 3e3d5815 balrog
                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0 ||
8332 3e3d5815 balrog
            qemu_key_check(mtd_bdrv, mtd_filename)) {
8333 3e3d5815 balrog
            fprintf(stderr, "qemu: could not open Flash image %s\n",
8334 3e3d5815 balrog
                    mtd_filename);
8335 3e3d5815 balrog
            bdrv_delete(mtd_bdrv);
8336 3e3d5815 balrog
            mtd_bdrv = 0;
8337 3e3d5815 balrog
        }
8338 3e3d5815 balrog
    }
8339 3e3d5815 balrog
8340 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
8341 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
8342 8a7ddc38 bellard
8343 330d0414 bellard
    init_ioports();
8344 0824d6fc bellard
8345 313aa567 bellard
    /* terminal init */
8346 740733bb ths
    memset(&display_state, 0, sizeof(display_state));
8347 a20dd508 bellard
    if (nographic) {
8348 2ff89790 ths
        /* nearly nothing to do */
8349 2ff89790 ths
        dumb_display_init(ds);
8350 73fc9742 ths
    } else if (vnc_display != NULL) {
8351 71cab5ca ths
        vnc_display_init(ds);
8352 71cab5ca ths
        if (vnc_display_open(ds, vnc_display) < 0)
8353 71cab5ca ths
            exit(1);
8354 313aa567 bellard
    } else {
8355 5b0753e0 bellard
#if defined(CONFIG_SDL)
8356 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
8357 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
8358 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
8359 313aa567 bellard
#endif
8360 313aa567 bellard
    }
8361 0824d6fc bellard
8362 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
8363 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
8364 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
8365 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
8366 20d8a3ed ths
                monitor_device[0] = '\0';
8367 20d8a3ed ths
                break;
8368 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
8369 20d8a3ed ths
                monitor_device[0] = '\0';
8370 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
8371 20d8a3ed ths
                break;
8372 20d8a3ed ths
            }
8373 20d8a3ed ths
        }
8374 20d8a3ed ths
    }
8375 20d8a3ed ths
    if (monitor_device[0] != '\0') {
8376 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
8377 20d8a3ed ths
        if (!monitor_hd) {
8378 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
8379 20d8a3ed ths
            exit(1);
8380 20d8a3ed ths
        }
8381 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
8382 82c643ff bellard
    }
8383 82c643ff bellard
8384 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
8385 c03b0f0f bellard
        const char *devname = serial_devices[i];
8386 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8387 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
8388 8d11df9e bellard
            if (!serial_hds[i]) {
8389 5fafdf24 ths
                fprintf(stderr, "qemu: could not open serial device '%s'\n",
8390 c03b0f0f bellard
                        devname);
8391 8d11df9e bellard
                exit(1);
8392 8d11df9e bellard
            }
8393 af3a9031 ths
            if (strstart(devname, "vc", 0))
8394 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
8395 8d11df9e bellard
        }
8396 82c643ff bellard
    }
8397 82c643ff bellard
8398 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
8399 c03b0f0f bellard
        const char *devname = parallel_devices[i];
8400 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8401 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
8402 6508fe59 bellard
            if (!parallel_hds[i]) {
8403 5fafdf24 ths
                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
8404 c03b0f0f bellard
                        devname);
8405 6508fe59 bellard
                exit(1);
8406 6508fe59 bellard
            }
8407 af3a9031 ths
            if (strstart(devname, "vc", 0))
8408 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
8409 6508fe59 bellard
        }
8410 6508fe59 bellard
    }
8411 6508fe59 bellard
8412 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
8413 cc1daa40 bellard
                  ds, fd_filename, snapshot,
8414 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
8415 73332e5c bellard
8416 0d92ed30 pbrook
    /* init USB devices */
8417 0d92ed30 pbrook
    if (usb_enabled) {
8418 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
8419 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
8420 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
8421 0d92ed30 pbrook
                        usb_devices[i]);
8422 0d92ed30 pbrook
            }
8423 0d92ed30 pbrook
        }
8424 0d92ed30 pbrook
    }
8425 0d92ed30 pbrook
8426 740733bb ths
    if (display_state.dpy_refresh) {
8427 740733bb ths
        display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
8428 740733bb ths
        qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
8429 740733bb ths
    }
8430 7f7f9873 bellard
8431 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8432 b4608c04 bellard
    if (use_gdbstub) {
8433 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
8434 c636bb66 bellard
           accordingly. */
8435 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
8436 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
8437 c636bb66 bellard
                    gdbstub_port);
8438 8a7ddc38 bellard
            exit(1);
8439 8a7ddc38 bellard
        }
8440 45669e00 balrog
    }
8441 67b915a5 bellard
#endif
8442 45669e00 balrog
8443 d63d307f bellard
    if (loadvm)
8444 faea38e7 bellard
        do_loadvm(loadvm);
8445 d63d307f bellard
8446 67b915a5 bellard
    {
8447 5905b2e5 bellard
        /* XXX: simplify init */
8448 5905b2e5 bellard
        read_passwords();
8449 3c07f8e8 pbrook
        if (autostart) {
8450 5905b2e5 bellard
            vm_start();
8451 5905b2e5 bellard
        }
8452 0824d6fc bellard
    }
8453 ffd843bc ths
8454 71e3ceb8 ths
    if (daemonize) {
8455 71e3ceb8 ths
        uint8_t status = 0;
8456 71e3ceb8 ths
        ssize_t len;
8457 71e3ceb8 ths
        int fd;
8458 71e3ceb8 ths
8459 71e3ceb8 ths
    again1:
8460 71e3ceb8 ths
        len = write(fds[1], &status, 1);
8461 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
8462 71e3ceb8 ths
            goto again1;
8463 71e3ceb8 ths
8464 71e3ceb8 ths
        if (len != 1)
8465 71e3ceb8 ths
            exit(1);
8466 71e3ceb8 ths
8467 aeb30be6 balrog
        TFR(fd = open("/dev/null", O_RDWR));
8468 71e3ceb8 ths
        if (fd == -1)
8469 71e3ceb8 ths
            exit(1);
8470 71e3ceb8 ths
8471 71e3ceb8 ths
        dup2(fd, 0);
8472 71e3ceb8 ths
        dup2(fd, 1);
8473 71e3ceb8 ths
        dup2(fd, 2);
8474 71e3ceb8 ths
8475 71e3ceb8 ths
        close(fd);
8476 71e3ceb8 ths
    }
8477 71e3ceb8 ths
8478 8a7ddc38 bellard
    main_loop();
8479 40c3bac3 bellard
    quit_timers();
8480 b46a8906 ths
8481 7d294b61 ths
#if !defined(_WIN32)
8482 b46a8906 ths
    /* close network clients */
8483 b46a8906 ths
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8484 b46a8906 ths
        VLANClientState *vc;
8485 b46a8906 ths
8486 7d294b61 ths
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
8487 b46a8906 ths
            if (vc->fd_read == tap_receive) {
8488 b46a8906 ths
                char ifname[64];
8489 b46a8906 ths
                TAPState *s = vc->opaque;
8490 b46a8906 ths
8491 b46a8906 ths
                if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
8492 b46a8906 ths
                    s->down_script[0])
8493 b46a8906 ths
                    launch_script(s->down_script, ifname, s->fd);
8494 b46a8906 ths
            }
8495 b46a8906 ths
    }
8496 7d294b61 ths
    }
8497 7d294b61 ths
#endif
8498 0824d6fc bellard
    return 0;
8499 0824d6fc bellard
}