Statistics
| Branch: | Revision:

root / vl.c @ 3c6b2088

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

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

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