Statistics
| Branch: | Revision:

root / vl.c @ ea785922

History | View | Annotate | Download (183.6 kB)

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

5504 c88676f8 bellard
            /* find if the memory block is available on a virtual
5505 c88676f8 bellard
               block device */
5506 c88676f8 bellard
            sector_num = -1;
5507 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5508 c88676f8 bellard
                if (bs_table[j]) {
5509 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5510 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5511 c88676f8 bellard
                    if (sector_num >= 0)
5512 c88676f8 bellard
                        break;
5513 c88676f8 bellard
                }
5514 c88676f8 bellard
            }
5515 c88676f8 bellard
            if (j == MAX_DISKS)
5516 c88676f8 bellard
                goto normal_compress;
5517 c88676f8 bellard
            buf[0] = 1;
5518 c88676f8 bellard
            buf[1] = j;
5519 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5520 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5521 c88676f8 bellard
        } else 
5522 c88676f8 bellard
#endif
5523 c88676f8 bellard
        {
5524 c88676f8 bellard
            //        normal_compress:
5525 c88676f8 bellard
            buf[0] = 0;
5526 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5527 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5528 c88676f8 bellard
        }
5529 8a7ddc38 bellard
    }
5530 c88676f8 bellard
    ram_compress_close(s);
5531 8a7ddc38 bellard
}
5532 8a7ddc38 bellard
5533 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5534 8a7ddc38 bellard
{
5535 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5536 c88676f8 bellard
    uint8_t buf[10];
5537 c88676f8 bellard
    int i;
5538 8a7ddc38 bellard
5539 c88676f8 bellard
    if (version_id == 1)
5540 c88676f8 bellard
        return ram_load_v1(f, opaque);
5541 c88676f8 bellard
    if (version_id != 2)
5542 8a7ddc38 bellard
        return -EINVAL;
5543 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5544 8a7ddc38 bellard
        return -EINVAL;
5545 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5546 c88676f8 bellard
        return -EINVAL;
5547 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5548 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5549 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5550 c88676f8 bellard
            goto error;
5551 c88676f8 bellard
        }
5552 c88676f8 bellard
        if (buf[0] == 0) {
5553 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5554 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5555 c88676f8 bellard
                goto error;
5556 c88676f8 bellard
            }
5557 c88676f8 bellard
        } else 
5558 c88676f8 bellard
#if 0
5559 c88676f8 bellard
        if (buf[0] == 1) {
5560 c88676f8 bellard
            int bs_index;
5561 c88676f8 bellard
            int64_t sector_num;
5562 c88676f8 bellard

5563 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
5564 c88676f8 bellard
            bs_index = buf[1];
5565 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
5566 c88676f8 bellard
            if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
5567 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
5568 c88676f8 bellard
                goto error;
5569 c88676f8 bellard
            }
5570 c88676f8 bellard
            if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i, 
5571 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
5572 c88676f8 bellard
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n", 
5573 c88676f8 bellard
                        bs_index, sector_num);
5574 c88676f8 bellard
                goto error;
5575 c88676f8 bellard
            }
5576 c88676f8 bellard
        } else 
5577 c88676f8 bellard
#endif
5578 c88676f8 bellard
        {
5579 c88676f8 bellard
        error:
5580 c88676f8 bellard
            printf("Error block header\n");
5581 c88676f8 bellard
            return -EINVAL;
5582 c88676f8 bellard
        }
5583 8a7ddc38 bellard
    }
5584 c88676f8 bellard
    ram_decompress_close(s);
5585 8a7ddc38 bellard
    return 0;
5586 8a7ddc38 bellard
}
5587 8a7ddc38 bellard
5588 8a7ddc38 bellard
/***********************************************************/
5589 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
5590 83f64091 bellard
5591 83f64091 bellard
struct QEMUBH {
5592 83f64091 bellard
    QEMUBHFunc *cb;
5593 83f64091 bellard
    void *opaque;
5594 83f64091 bellard
    int scheduled;
5595 83f64091 bellard
    QEMUBH *next;
5596 83f64091 bellard
};
5597 83f64091 bellard
5598 83f64091 bellard
static QEMUBH *first_bh = NULL;
5599 83f64091 bellard
5600 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
5601 83f64091 bellard
{
5602 83f64091 bellard
    QEMUBH *bh;
5603 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
5604 83f64091 bellard
    if (!bh)
5605 83f64091 bellard
        return NULL;
5606 83f64091 bellard
    bh->cb = cb;
5607 83f64091 bellard
    bh->opaque = opaque;
5608 83f64091 bellard
    return bh;
5609 83f64091 bellard
}
5610 83f64091 bellard
5611 6eb5733a bellard
int qemu_bh_poll(void)
5612 83f64091 bellard
{
5613 83f64091 bellard
    QEMUBH *bh, **pbh;
5614 6eb5733a bellard
    int ret;
5615 83f64091 bellard
5616 6eb5733a bellard
    ret = 0;
5617 83f64091 bellard
    for(;;) {
5618 83f64091 bellard
        pbh = &first_bh;
5619 83f64091 bellard
        bh = *pbh;
5620 83f64091 bellard
        if (!bh)
5621 83f64091 bellard
            break;
5622 6eb5733a bellard
        ret = 1;
5623 83f64091 bellard
        *pbh = bh->next;
5624 83f64091 bellard
        bh->scheduled = 0;
5625 83f64091 bellard
        bh->cb(bh->opaque);
5626 83f64091 bellard
    }
5627 6eb5733a bellard
    return ret;
5628 83f64091 bellard
}
5629 83f64091 bellard
5630 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
5631 83f64091 bellard
{
5632 83f64091 bellard
    CPUState *env = cpu_single_env;
5633 83f64091 bellard
    if (bh->scheduled)
5634 83f64091 bellard
        return;
5635 83f64091 bellard
    bh->scheduled = 1;
5636 83f64091 bellard
    bh->next = first_bh;
5637 83f64091 bellard
    first_bh = bh;
5638 83f64091 bellard
5639 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
5640 83f64091 bellard
    if (env) {
5641 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
5642 83f64091 bellard
    }
5643 83f64091 bellard
}
5644 83f64091 bellard
5645 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
5646 83f64091 bellard
{
5647 83f64091 bellard
    QEMUBH **pbh;
5648 83f64091 bellard
    if (bh->scheduled) {
5649 83f64091 bellard
        pbh = &first_bh;
5650 83f64091 bellard
        while (*pbh != bh)
5651 83f64091 bellard
            pbh = &(*pbh)->next;
5652 83f64091 bellard
        *pbh = bh->next;
5653 83f64091 bellard
        bh->scheduled = 0;
5654 83f64091 bellard
    }
5655 83f64091 bellard
}
5656 83f64091 bellard
5657 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
5658 83f64091 bellard
{
5659 83f64091 bellard
    qemu_bh_cancel(bh);
5660 83f64091 bellard
    qemu_free(bh);
5661 83f64091 bellard
}
5662 83f64091 bellard
5663 83f64091 bellard
/***********************************************************/
5664 cc1daa40 bellard
/* machine registration */
5665 cc1daa40 bellard
5666 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
5667 cc1daa40 bellard
5668 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
5669 cc1daa40 bellard
{
5670 cc1daa40 bellard
    QEMUMachine **pm;
5671 cc1daa40 bellard
    pm = &first_machine;
5672 cc1daa40 bellard
    while (*pm != NULL)
5673 cc1daa40 bellard
        pm = &(*pm)->next;
5674 cc1daa40 bellard
    m->next = NULL;
5675 cc1daa40 bellard
    *pm = m;
5676 cc1daa40 bellard
    return 0;
5677 cc1daa40 bellard
}
5678 cc1daa40 bellard
5679 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
5680 cc1daa40 bellard
{
5681 cc1daa40 bellard
    QEMUMachine *m;
5682 cc1daa40 bellard
5683 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
5684 cc1daa40 bellard
        if (!strcmp(m->name, name))
5685 cc1daa40 bellard
            return m;
5686 cc1daa40 bellard
    }
5687 cc1daa40 bellard
    return NULL;
5688 cc1daa40 bellard
}
5689 cc1daa40 bellard
5690 cc1daa40 bellard
/***********************************************************/
5691 8a7ddc38 bellard
/* main execution loop */
5692 8a7ddc38 bellard
5693 8a7ddc38 bellard
void gui_update(void *opaque)
5694 8a7ddc38 bellard
{
5695 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
5696 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
5697 8a7ddc38 bellard
}
5698 8a7ddc38 bellard
5699 0bd48850 bellard
struct vm_change_state_entry {
5700 0bd48850 bellard
    VMChangeStateHandler *cb;
5701 0bd48850 bellard
    void *opaque;
5702 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
5703 0bd48850 bellard
};
5704 0bd48850 bellard
5705 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
5706 0bd48850 bellard
5707 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
5708 0bd48850 bellard
                                                     void *opaque)
5709 0bd48850 bellard
{
5710 0bd48850 bellard
    VMChangeStateEntry *e;
5711 0bd48850 bellard
5712 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
5713 0bd48850 bellard
    if (!e)
5714 0bd48850 bellard
        return NULL;
5715 0bd48850 bellard
5716 0bd48850 bellard
    e->cb = cb;
5717 0bd48850 bellard
    e->opaque = opaque;
5718 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
5719 0bd48850 bellard
    return e;
5720 0bd48850 bellard
}
5721 0bd48850 bellard
5722 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
5723 0bd48850 bellard
{
5724 0bd48850 bellard
    LIST_REMOVE (e, entries);
5725 0bd48850 bellard
    qemu_free (e);
5726 0bd48850 bellard
}
5727 0bd48850 bellard
5728 0bd48850 bellard
static void vm_state_notify(int running)
5729 0bd48850 bellard
{
5730 0bd48850 bellard
    VMChangeStateEntry *e;
5731 0bd48850 bellard
5732 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
5733 0bd48850 bellard
        e->cb(e->opaque, running);
5734 0bd48850 bellard
    }
5735 0bd48850 bellard
}
5736 0bd48850 bellard
5737 8a7ddc38 bellard
/* XXX: support several handlers */
5738 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
5739 0bd48850 bellard
static void *vm_stop_opaque;
5740 8a7ddc38 bellard
5741 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
5742 8a7ddc38 bellard
{
5743 8a7ddc38 bellard
    vm_stop_cb = cb;
5744 8a7ddc38 bellard
    vm_stop_opaque = opaque;
5745 8a7ddc38 bellard
    return 0;
5746 8a7ddc38 bellard
}
5747 8a7ddc38 bellard
5748 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
5749 8a7ddc38 bellard
{
5750 8a7ddc38 bellard
    vm_stop_cb = NULL;
5751 8a7ddc38 bellard
}
5752 8a7ddc38 bellard
5753 8a7ddc38 bellard
void vm_start(void)
5754 8a7ddc38 bellard
{
5755 8a7ddc38 bellard
    if (!vm_running) {
5756 8a7ddc38 bellard
        cpu_enable_ticks();
5757 8a7ddc38 bellard
        vm_running = 1;
5758 0bd48850 bellard
        vm_state_notify(1);
5759 8a7ddc38 bellard
    }
5760 8a7ddc38 bellard
}
5761 8a7ddc38 bellard
5762 8a7ddc38 bellard
void vm_stop(int reason) 
5763 8a7ddc38 bellard
{
5764 8a7ddc38 bellard
    if (vm_running) {
5765 8a7ddc38 bellard
        cpu_disable_ticks();
5766 8a7ddc38 bellard
        vm_running = 0;
5767 8a7ddc38 bellard
        if (reason != 0) {
5768 8a7ddc38 bellard
            if (vm_stop_cb) {
5769 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
5770 8a7ddc38 bellard
            }
5771 34865134 bellard
        }
5772 0bd48850 bellard
        vm_state_notify(0);
5773 8a7ddc38 bellard
    }
5774 8a7ddc38 bellard
}
5775 8a7ddc38 bellard
5776 bb0c6722 bellard
/* reset/shutdown handler */
5777 bb0c6722 bellard
5778 bb0c6722 bellard
typedef struct QEMUResetEntry {
5779 bb0c6722 bellard
    QEMUResetHandler *func;
5780 bb0c6722 bellard
    void *opaque;
5781 bb0c6722 bellard
    struct QEMUResetEntry *next;
5782 bb0c6722 bellard
} QEMUResetEntry;
5783 bb0c6722 bellard
5784 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
5785 bb0c6722 bellard
static int reset_requested;
5786 bb0c6722 bellard
static int shutdown_requested;
5787 3475187d bellard
static int powerdown_requested;
5788 bb0c6722 bellard
5789 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
5790 bb0c6722 bellard
{
5791 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
5792 bb0c6722 bellard
5793 bb0c6722 bellard
    pre = &first_reset_entry;
5794 bb0c6722 bellard
    while (*pre != NULL)
5795 bb0c6722 bellard
        pre = &(*pre)->next;
5796 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
5797 bb0c6722 bellard
    re->func = func;
5798 bb0c6722 bellard
    re->opaque = opaque;
5799 bb0c6722 bellard
    re->next = NULL;
5800 bb0c6722 bellard
    *pre = re;
5801 bb0c6722 bellard
}
5802 bb0c6722 bellard
5803 52f61fde ths
static void qemu_system_reset(void)
5804 bb0c6722 bellard
{
5805 bb0c6722 bellard
    QEMUResetEntry *re;
5806 bb0c6722 bellard
5807 bb0c6722 bellard
    /* reset all devices */
5808 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
5809 bb0c6722 bellard
        re->func(re->opaque);
5810 bb0c6722 bellard
    }
5811 bb0c6722 bellard
}
5812 bb0c6722 bellard
5813 bb0c6722 bellard
void qemu_system_reset_request(void)
5814 bb0c6722 bellard
{
5815 d1beab82 bellard
    if (no_reboot) {
5816 d1beab82 bellard
        shutdown_requested = 1;
5817 d1beab82 bellard
    } else {
5818 d1beab82 bellard
        reset_requested = 1;
5819 d1beab82 bellard
    }
5820 6a00d601 bellard
    if (cpu_single_env)
5821 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
5822 bb0c6722 bellard
}
5823 bb0c6722 bellard
5824 bb0c6722 bellard
void qemu_system_shutdown_request(void)
5825 bb0c6722 bellard
{
5826 bb0c6722 bellard
    shutdown_requested = 1;
5827 6a00d601 bellard
    if (cpu_single_env)
5828 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
5829 bb0c6722 bellard
}
5830 bb0c6722 bellard
5831 3475187d bellard
void qemu_system_powerdown_request(void)
5832 3475187d bellard
{
5833 3475187d bellard
    powerdown_requested = 1;
5834 6a00d601 bellard
    if (cpu_single_env)
5835 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
5836 bb0c6722 bellard
}
5837 bb0c6722 bellard
5838 5905b2e5 bellard
void main_loop_wait(int timeout)
5839 8a7ddc38 bellard
{
5840 8a7ddc38 bellard
    IOHandlerRecord *ioh, *ioh_next;
5841 e035649e bellard
    fd_set rfds, wfds, xfds;
5842 fd1dff4b bellard
    int ret, nfds;
5843 fd1dff4b bellard
    struct timeval tv;
5844 f331110f bellard
    PollingEntry *pe;
5845 f331110f bellard
5846 c4b1fcc0 bellard
5847 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
5848 f331110f bellard
    ret = 0;
5849 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
5850 f331110f bellard
        ret |= pe->func(pe->opaque);
5851 f331110f bellard
    }
5852 38e205a2 bellard
#ifdef _WIN32
5853 f331110f bellard
    if (ret == 0 && timeout > 0) {
5854 a18e524a bellard
        int err;
5855 a18e524a bellard
        WaitObjects *w = &wait_objects;
5856 a18e524a bellard
        
5857 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
5858 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
5859 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
5860 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
5861 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
5862 a18e524a bellard
        } else {
5863 a18e524a bellard
            err = GetLastError();
5864 a18e524a bellard
            fprintf(stderr, "Wait error %d %d\n", ret, err);
5865 a18e524a bellard
        }
5866 f331110f bellard
    }
5867 fd1dff4b bellard
#endif
5868 fd1dff4b bellard
    /* poll any events */
5869 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
5870 fd1dff4b bellard
    nfds = -1;
5871 fd1dff4b bellard
    FD_ZERO(&rfds);
5872 fd1dff4b bellard
    FD_ZERO(&wfds);
5873 e035649e bellard
    FD_ZERO(&xfds);
5874 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
5875 fd1dff4b bellard
        if (ioh->fd_read &&
5876 fd1dff4b bellard
            (!ioh->fd_read_poll ||
5877 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
5878 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
5879 fd1dff4b bellard
            if (ioh->fd > nfds)
5880 fd1dff4b bellard
                nfds = ioh->fd;
5881 fd1dff4b bellard
        }
5882 fd1dff4b bellard
        if (ioh->fd_write) {
5883 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
5884 fd1dff4b bellard
            if (ioh->fd > nfds)
5885 fd1dff4b bellard
                nfds = ioh->fd;
5886 fd1dff4b bellard
        }
5887 fd1dff4b bellard
    }
5888 fd1dff4b bellard
    
5889 fd1dff4b bellard
    tv.tv_sec = 0;
5890 fd1dff4b bellard
#ifdef _WIN32
5891 fd1dff4b bellard
    tv.tv_usec = 0;
5892 38e205a2 bellard
#else
5893 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
5894 fd1dff4b bellard
#endif
5895 e035649e bellard
#if defined(CONFIG_SLIRP)
5896 e035649e bellard
    if (slirp_inited) {
5897 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
5898 e035649e bellard
    }
5899 e035649e bellard
#endif
5900 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
5901 fd1dff4b bellard
    if (ret > 0) {
5902 fd1dff4b bellard
        /* XXX: better handling of removal */
5903 fd1dff4b bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
5904 fd1dff4b bellard
            ioh_next = ioh->next;
5905 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &rfds)) {
5906 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
5907 7c9d8e07 bellard
            }
5908 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &wfds)) {
5909 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
5910 c4b1fcc0 bellard
            }
5911 b4608c04 bellard
        }
5912 fd1dff4b bellard
    }
5913 c20709aa bellard
#if defined(CONFIG_SLIRP)
5914 fd1dff4b bellard
    if (slirp_inited) {
5915 e035649e bellard
        if (ret < 0) {
5916 e035649e bellard
            FD_ZERO(&rfds);
5917 e035649e bellard
            FD_ZERO(&wfds);
5918 e035649e bellard
            FD_ZERO(&xfds);
5919 c20709aa bellard
        }
5920 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
5921 fd1dff4b bellard
    }
5922 c20709aa bellard
#endif
5923 83f64091 bellard
    qemu_aio_poll();
5924 83f64091 bellard
    qemu_bh_poll();
5925 c20709aa bellard
5926 fd1dff4b bellard
    if (vm_running) {
5927 fd1dff4b bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
5928 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
5929 fd1dff4b bellard
        /* run dma transfers, if any */
5930 fd1dff4b bellard
        DMA_run();
5931 fd1dff4b bellard
    }
5932 fd1dff4b bellard
    
5933 fd1dff4b bellard
    /* real time timers */
5934 fd1dff4b bellard
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
5935 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
5936 5905b2e5 bellard
}
5937 5905b2e5 bellard
5938 6a00d601 bellard
static CPUState *cur_cpu;
5939 6a00d601 bellard
5940 5905b2e5 bellard
int main_loop(void)
5941 5905b2e5 bellard
{
5942 5905b2e5 bellard
    int ret, timeout;
5943 89bfc105 bellard
#ifdef CONFIG_PROFILER
5944 89bfc105 bellard
    int64_t ti;
5945 89bfc105 bellard
#endif
5946 6a00d601 bellard
    CPUState *env;
5947 5905b2e5 bellard
5948 6a00d601 bellard
    cur_cpu = first_cpu;
5949 5905b2e5 bellard
    for(;;) {
5950 5905b2e5 bellard
        if (vm_running) {
5951 15a76449 bellard
5952 15a76449 bellard
            env = cur_cpu;
5953 15a76449 bellard
            for(;;) {
5954 15a76449 bellard
                /* get next cpu */
5955 15a76449 bellard
                env = env->next_cpu;
5956 15a76449 bellard
                if (!env)
5957 15a76449 bellard
                    env = first_cpu;
5958 89bfc105 bellard
#ifdef CONFIG_PROFILER
5959 89bfc105 bellard
                ti = profile_getclock();
5960 89bfc105 bellard
#endif
5961 6a00d601 bellard
                ret = cpu_exec(env);
5962 89bfc105 bellard
#ifdef CONFIG_PROFILER
5963 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
5964 89bfc105 bellard
#endif
5965 15a76449 bellard
                if (ret != EXCP_HALTED)
5966 15a76449 bellard
                    break;
5967 15a76449 bellard
                /* all CPUs are halted ? */
5968 15a76449 bellard
                if (env == cur_cpu) {
5969 15a76449 bellard
                    ret = EXCP_HLT;
5970 15a76449 bellard
                    break;
5971 15a76449 bellard
                }
5972 15a76449 bellard
            }
5973 15a76449 bellard
            cur_cpu = env;
5974 15a76449 bellard
5975 5905b2e5 bellard
            if (shutdown_requested) {
5976 3475187d bellard
                ret = EXCP_INTERRUPT;
5977 5905b2e5 bellard
                break;
5978 5905b2e5 bellard
            }
5979 5905b2e5 bellard
            if (reset_requested) {
5980 5905b2e5 bellard
                reset_requested = 0;
5981 5905b2e5 bellard
                qemu_system_reset();
5982 3475187d bellard
                ret = EXCP_INTERRUPT;
5983 3475187d bellard
            }
5984 3475187d bellard
            if (powerdown_requested) {
5985 3475187d bellard
                powerdown_requested = 0;
5986 3475187d bellard
                qemu_system_powerdown();
5987 3475187d bellard
                ret = EXCP_INTERRUPT;
5988 5905b2e5 bellard
            }
5989 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
5990 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
5991 5905b2e5 bellard
            }
5992 5905b2e5 bellard
            /* if hlt instruction, we wait until the next IRQ */
5993 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
5994 3475187d bellard
            if (ret == EXCP_HLT)
5995 5905b2e5 bellard
                timeout = 10;
5996 5905b2e5 bellard
            else
5997 5905b2e5 bellard
                timeout = 0;
5998 5905b2e5 bellard
        } else {
5999 5905b2e5 bellard
            timeout = 10;
6000 5905b2e5 bellard
        }
6001 89bfc105 bellard
#ifdef CONFIG_PROFILER
6002 89bfc105 bellard
        ti = profile_getclock();
6003 89bfc105 bellard
#endif
6004 5905b2e5 bellard
        main_loop_wait(timeout);
6005 89bfc105 bellard
#ifdef CONFIG_PROFILER
6006 89bfc105 bellard
        dev_time += profile_getclock() - ti;
6007 89bfc105 bellard
#endif
6008 b4608c04 bellard
    }
6009 34865134 bellard
    cpu_disable_ticks();
6010 34865134 bellard
    return ret;
6011 b4608c04 bellard
}
6012 b4608c04 bellard
6013 0824d6fc bellard
void help(void)
6014 0824d6fc bellard
{
6015 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
6016 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
6017 0824d6fc bellard
           "\n"
6018 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
6019 fc01f7e7 bellard
           "\n"
6020 a20dd508 bellard
           "Standard options:\n"
6021 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
6022 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
6023 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
6024 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
6025 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
6026 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
6027 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
6028 667accab ths
#ifdef CONFIG_SDL
6029 667accab ths
           "-no-quit        disable SDL window close capability\n"
6030 667accab ths
#endif
6031 52ca8d6a bellard
#ifdef TARGET_I386
6032 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
6033 52ca8d6a bellard
#endif
6034 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
6035 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
6036 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
6037 4ca0074c bellard
#ifndef _WIN32
6038 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
6039 4ca0074c bellard
#endif
6040 1d14ffa9 bellard
#ifdef HAS_AUDIO
6041 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
6042 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
6043 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
6044 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
6045 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
6046 1d14ffa9 bellard
#endif
6047 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
6048 d63d307f bellard
           "-full-screen    start in full screen\n"
6049 a09db21f bellard
#ifdef TARGET_I386
6050 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
6051 a09db21f bellard
#endif
6052 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
6053 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
6054 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6055 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
6056 bb0c6722 bellard
#endif
6057 c4b1fcc0 bellard
           "\n"
6058 c4b1fcc0 bellard
           "Network options:\n"
6059 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
6060 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
6061 c20709aa bellard
#ifdef CONFIG_SLIRP
6062 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
6063 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
6064 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
6065 7c9d8e07 bellard
#endif
6066 7fb843f8 bellard
#ifdef _WIN32
6067 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
6068 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
6069 7fb843f8 bellard
#else
6070 7c9d8e07 bellard
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
6071 7c9d8e07 bellard
           "                connect the host TAP network interface to VLAN 'n' and use\n"
6072 7c9d8e07 bellard
           "                the network script 'file' (default=%s);\n"
6073 6a1cbf68 ths
           "                use 'script=no' to disable script execution;\n"
6074 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
6075 7fb843f8 bellard
#endif
6076 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
6077 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
6078 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
6079 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
6080 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
6081 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
6082 7c9d8e07 bellard
           "\n"
6083 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
6084 7c9d8e07 bellard
           "-tftp prefix    allow tftp access to files starting with prefix [-net user]\n"
6085 7c9d8e07 bellard
#ifndef _WIN32
6086 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
6087 c94c8d64 bellard
#endif
6088 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
6089 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
6090 c20709aa bellard
#endif
6091 a20dd508 bellard
           "\n"
6092 c4b1fcc0 bellard
           "Linux boot specific:\n"
6093 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
6094 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
6095 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
6096 fc01f7e7 bellard
           "\n"
6097 330d0414 bellard
           "Debug/Expert options:\n"
6098 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
6099 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
6100 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
6101 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
6102 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
6103 a20dd508 bellard
           "-s              wait gdb connection to port %d\n"
6104 a20dd508 bellard
           "-p port         change gdb connection port\n"
6105 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
6106 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
6107 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
6108 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
6109 d993e026 bellard
#ifdef USE_KQEMU
6110 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
6111 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
6112 d993e026 bellard
#endif
6113 77fef8c1 bellard
#ifdef USE_CODE_COPY
6114 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
6115 77fef8c1 bellard
#endif
6116 bb0c6722 bellard
#ifdef TARGET_I386
6117 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
6118 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
6119 6515b203 bellard
           "-no-acpi        disable ACPI\n"
6120 bb0c6722 bellard
#endif
6121 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
6122 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
6123 24236869 bellard
           "-vnc display    start a VNC server on display\n"
6124 71e3ceb8 ths
#ifndef _WIN32
6125 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
6126 71e3ceb8 ths
#endif
6127 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
6128 0824d6fc bellard
           "\n"
6129 82c643ff bellard
           "During emulation, the following keys are useful:\n"
6130 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
6131 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
6132 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
6133 82c643ff bellard
           "\n"
6134 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
6135 82c643ff bellard
           ,
6136 0db63474 bellard
           "qemu",
6137 a00bad7e bellard
           DEFAULT_RAM_SIZE,
6138 7c9d8e07 bellard
#ifndef _WIN32
6139 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
6140 7c9d8e07 bellard
#endif
6141 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
6142 6e44ba7f bellard
           "/tmp/qemu.log");
6143 0824d6fc bellard
    exit(1);
6144 0824d6fc bellard
}
6145 0824d6fc bellard
6146 cd6f1169 bellard
#define HAS_ARG 0x0001
6147 cd6f1169 bellard
6148 cd6f1169 bellard
enum {
6149 cd6f1169 bellard
    QEMU_OPTION_h,
6150 cd6f1169 bellard
6151 cc1daa40 bellard
    QEMU_OPTION_M,
6152 cd6f1169 bellard
    QEMU_OPTION_fda,
6153 cd6f1169 bellard
    QEMU_OPTION_fdb,
6154 cd6f1169 bellard
    QEMU_OPTION_hda,
6155 cd6f1169 bellard
    QEMU_OPTION_hdb,
6156 cd6f1169 bellard
    QEMU_OPTION_hdc,
6157 cd6f1169 bellard
    QEMU_OPTION_hdd,
6158 cd6f1169 bellard
    QEMU_OPTION_cdrom,
6159 cd6f1169 bellard
    QEMU_OPTION_boot,
6160 cd6f1169 bellard
    QEMU_OPTION_snapshot,
6161 52ca8d6a bellard
#ifdef TARGET_I386
6162 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
6163 52ca8d6a bellard
#endif
6164 cd6f1169 bellard
    QEMU_OPTION_m,
6165 cd6f1169 bellard
    QEMU_OPTION_nographic,
6166 1d14ffa9 bellard
#ifdef HAS_AUDIO
6167 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
6168 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
6169 1d14ffa9 bellard
#endif
6170 cd6f1169 bellard
6171 7c9d8e07 bellard
    QEMU_OPTION_net,
6172 c7f74643 bellard
    QEMU_OPTION_tftp,
6173 9d728e8c bellard
    QEMU_OPTION_smb,
6174 9bf05444 bellard
    QEMU_OPTION_redir,
6175 cd6f1169 bellard
6176 cd6f1169 bellard
    QEMU_OPTION_kernel,
6177 cd6f1169 bellard
    QEMU_OPTION_append,
6178 cd6f1169 bellard
    QEMU_OPTION_initrd,
6179 cd6f1169 bellard
6180 cd6f1169 bellard
    QEMU_OPTION_S,
6181 cd6f1169 bellard
    QEMU_OPTION_s,
6182 cd6f1169 bellard
    QEMU_OPTION_p,
6183 cd6f1169 bellard
    QEMU_OPTION_d,
6184 cd6f1169 bellard
    QEMU_OPTION_hdachs,
6185 cd6f1169 bellard
    QEMU_OPTION_L,
6186 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
6187 3d11d0eb bellard
    QEMU_OPTION_k,
6188 ee22c2f7 bellard
    QEMU_OPTION_localtime,
6189 1f04275e bellard
    QEMU_OPTION_cirrusvga,
6190 e9b137c2 bellard
    QEMU_OPTION_g,
6191 1bfe856e bellard
    QEMU_OPTION_std_vga,
6192 82c643ff bellard
    QEMU_OPTION_monitor,
6193 82c643ff bellard
    QEMU_OPTION_serial,
6194 6508fe59 bellard
    QEMU_OPTION_parallel,
6195 d63d307f bellard
    QEMU_OPTION_loadvm,
6196 d63d307f bellard
    QEMU_OPTION_full_screen,
6197 667accab ths
    QEMU_OPTION_no_quit,
6198 f7cce898 bellard
    QEMU_OPTION_pidfile,
6199 d993e026 bellard
    QEMU_OPTION_no_kqemu,
6200 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
6201 a09db21f bellard
    QEMU_OPTION_win2k_hack,
6202 bb36d470 bellard
    QEMU_OPTION_usb,
6203 a594cfbf bellard
    QEMU_OPTION_usbdevice,
6204 6a00d601 bellard
    QEMU_OPTION_smp,
6205 24236869 bellard
    QEMU_OPTION_vnc,
6206 6515b203 bellard
    QEMU_OPTION_no_acpi,
6207 d1beab82 bellard
    QEMU_OPTION_no_reboot,
6208 71e3ceb8 ths
    QEMU_OPTION_daemonize,
6209 9ae02555 ths
    QEMU_OPTION_option_rom,
6210 8e71621f pbrook
    QEMU_OPTION_semihosting
6211 cd6f1169 bellard
};
6212 cd6f1169 bellard
6213 cd6f1169 bellard
typedef struct QEMUOption {
6214 cd6f1169 bellard
    const char *name;
6215 cd6f1169 bellard
    int flags;
6216 cd6f1169 bellard
    int index;
6217 cd6f1169 bellard
} QEMUOption;
6218 cd6f1169 bellard
6219 cd6f1169 bellard
const QEMUOption qemu_options[] = {
6220 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
6221 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
6222 cd6f1169 bellard
6223 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
6224 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
6225 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
6226 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
6227 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
6228 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
6229 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
6230 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
6231 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
6232 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
6233 52ca8d6a bellard
#ifdef TARGET_I386
6234 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
6235 52ca8d6a bellard
#endif
6236 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
6237 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
6238 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
6239 1d14ffa9 bellard
#ifdef HAS_AUDIO
6240 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
6241 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
6242 1d14ffa9 bellard
#endif
6243 cd6f1169 bellard
6244 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
6245 158156d1 bellard
#ifdef CONFIG_SLIRP
6246 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
6247 c94c8d64 bellard
#ifndef _WIN32
6248 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
6249 c94c8d64 bellard
#endif
6250 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
6251 158156d1 bellard
#endif
6252 cd6f1169 bellard
6253 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
6254 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
6255 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
6256 cd6f1169 bellard
6257 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
6258 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
6259 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
6260 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
6261 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
6262 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
6263 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
6264 d993e026 bellard
#ifdef USE_KQEMU
6265 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
6266 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
6267 d993e026 bellard
#endif
6268 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6269 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
6270 77d4bc34 bellard
#endif
6271 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
6272 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
6273 82c643ff bellard
    { "monitor", 1, QEMU_OPTION_monitor },
6274 82c643ff bellard
    { "serial", 1, QEMU_OPTION_serial },
6275 6508fe59 bellard
    { "parallel", 1, QEMU_OPTION_parallel },
6276 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
6277 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
6278 667accab ths
#ifdef CONFIG_SDL
6279 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
6280 667accab ths
#endif
6281 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
6282 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
6283 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
6284 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
6285 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
6286 96d30e48 ths
6287 1f04275e bellard
    /* temporary options */
6288 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
6289 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
6290 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
6291 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
6292 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
6293 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
6294 8e71621f pbrook
#if defined(TARGET_ARM)
6295 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
6296 8e71621f pbrook
#endif
6297 cd6f1169 bellard
    { NULL },
6298 fc01f7e7 bellard
};
6299 fc01f7e7 bellard
6300 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
6301 77fef8c1 bellard
6302 77fef8c1 bellard
/* this stack is only used during signal handling */
6303 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
6304 77fef8c1 bellard
6305 77fef8c1 bellard
static uint8_t *signal_stack;
6306 77fef8c1 bellard
6307 77fef8c1 bellard
#endif
6308 77fef8c1 bellard
6309 5905b2e5 bellard
/* password input */
6310 5905b2e5 bellard
6311 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
6312 5905b2e5 bellard
{
6313 5905b2e5 bellard
    BlockDriverState *bs;
6314 5905b2e5 bellard
6315 5905b2e5 bellard
    if (index < 4) {
6316 5905b2e5 bellard
        bs = bs_table[index];
6317 5905b2e5 bellard
    } else if (index < 6) {
6318 5905b2e5 bellard
        bs = fd_table[index - 4];
6319 5905b2e5 bellard
    } else {
6320 5905b2e5 bellard
        bs = NULL;
6321 5905b2e5 bellard
    }
6322 5905b2e5 bellard
    return bs;
6323 5905b2e5 bellard
}
6324 5905b2e5 bellard
6325 5905b2e5 bellard
static void read_passwords(void)
6326 5905b2e5 bellard
{
6327 5905b2e5 bellard
    BlockDriverState *bs;
6328 5905b2e5 bellard
    int i, j;
6329 5905b2e5 bellard
    char password[256];
6330 5905b2e5 bellard
6331 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
6332 5905b2e5 bellard
        bs = get_bdrv(i);
6333 5905b2e5 bellard
        if (bs && bdrv_is_encrypted(bs)) {
6334 5905b2e5 bellard
            term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
6335 5905b2e5 bellard
            for(j = 0; j < 3; j++) {
6336 5905b2e5 bellard
                monitor_readline("Password: ", 
6337 5905b2e5 bellard
                                 1, password, sizeof(password));
6338 5905b2e5 bellard
                if (bdrv_set_key(bs, password) == 0)
6339 5905b2e5 bellard
                    break;
6340 5905b2e5 bellard
                term_printf("invalid password\n");
6341 5905b2e5 bellard
            }
6342 5905b2e5 bellard
        }
6343 5905b2e5 bellard
    }
6344 5905b2e5 bellard
}
6345 5905b2e5 bellard
6346 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
6347 cc1daa40 bellard
void register_machines(void)
6348 cc1daa40 bellard
{
6349 cc1daa40 bellard
#if defined(TARGET_I386)
6350 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
6351 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
6352 cc1daa40 bellard
#elif defined(TARGET_PPC)
6353 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
6354 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
6355 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
6356 6af0bf9c bellard
#elif defined(TARGET_MIPS)
6357 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
6358 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
6359 cc1daa40 bellard
#elif defined(TARGET_SPARC)
6360 3475187d bellard
#ifdef TARGET_SPARC64
6361 3475187d bellard
    qemu_register_machine(&sun4u_machine);
6362 3475187d bellard
#else
6363 cc1daa40 bellard
    qemu_register_machine(&sun4m_machine);
6364 cc1daa40 bellard
#endif
6365 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6366 40f137e1 pbrook
    qemu_register_machine(&integratorcp926_machine);
6367 40f137e1 pbrook
    qemu_register_machine(&integratorcp1026_machine);
6368 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
6369 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
6370 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
6371 27c7ca7e bellard
#elif defined(TARGET_SH4)
6372 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
6373 b5ff1b31 bellard
#else
6374 b5ff1b31 bellard
#error unsupported CPU
6375 3475187d bellard
#endif
6376 cc1daa40 bellard
}
6377 cc1daa40 bellard
6378 1d14ffa9 bellard
#ifdef HAS_AUDIO
6379 6a36d84e bellard
struct soundhw soundhw[] = {
6380 fd06c375 bellard
#ifdef TARGET_I386
6381 fd06c375 bellard
    {
6382 fd06c375 bellard
        "pcspk",
6383 fd06c375 bellard
        "PC speaker",
6384 fd06c375 bellard
        0,
6385 fd06c375 bellard
        1,
6386 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
6387 fd06c375 bellard
    },
6388 fd06c375 bellard
#endif
6389 6a36d84e bellard
    {
6390 6a36d84e bellard
        "sb16",
6391 6a36d84e bellard
        "Creative Sound Blaster 16",
6392 6a36d84e bellard
        0,
6393 6a36d84e bellard
        1,
6394 6a36d84e bellard
        { .init_isa = SB16_init }
6395 6a36d84e bellard
    },
6396 6a36d84e bellard
6397 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
6398 6a36d84e bellard
    {
6399 6a36d84e bellard
        "adlib",
6400 1d14ffa9 bellard
#ifdef HAS_YMF262
6401 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
6402 1d14ffa9 bellard
#else
6403 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
6404 1d14ffa9 bellard
#endif
6405 6a36d84e bellard
        0,
6406 6a36d84e bellard
        1,
6407 6a36d84e bellard
        { .init_isa = Adlib_init }
6408 6a36d84e bellard
    },
6409 1d14ffa9 bellard
#endif
6410 6a36d84e bellard
6411 1d14ffa9 bellard
#ifdef CONFIG_GUS
6412 6a36d84e bellard
    {
6413 6a36d84e bellard
        "gus",
6414 6a36d84e bellard
        "Gravis Ultrasound GF1",
6415 6a36d84e bellard
        0,
6416 6a36d84e bellard
        1,
6417 6a36d84e bellard
        { .init_isa = GUS_init }
6418 6a36d84e bellard
    },
6419 1d14ffa9 bellard
#endif
6420 6a36d84e bellard
6421 6a36d84e bellard
    {
6422 6a36d84e bellard
        "es1370",
6423 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
6424 6a36d84e bellard
        0,
6425 6a36d84e bellard
        0,
6426 6a36d84e bellard
        { .init_pci = es1370_init }
6427 6a36d84e bellard
    },
6428 6a36d84e bellard
6429 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
6430 6a36d84e bellard
};
6431 6a36d84e bellard
6432 6a36d84e bellard
static void select_soundhw (const char *optarg)
6433 6a36d84e bellard
{
6434 6a36d84e bellard
    struct soundhw *c;
6435 6a36d84e bellard
6436 6a36d84e bellard
    if (*optarg == '?') {
6437 6a36d84e bellard
    show_valid_cards:
6438 6a36d84e bellard
6439 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
6440 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
6441 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
6442 6a36d84e bellard
        }
6443 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
6444 1d14ffa9 bellard
        exit (*optarg != '?');
6445 1d14ffa9 bellard
    }
6446 1d14ffa9 bellard
    else {
6447 6a36d84e bellard
        size_t l;
6448 1d14ffa9 bellard
        const char *p;
6449 1d14ffa9 bellard
        char *e;
6450 1d14ffa9 bellard
        int bad_card = 0;
6451 1d14ffa9 bellard
6452 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
6453 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6454 6a36d84e bellard
                c->enabled = 1;
6455 6a36d84e bellard
            }
6456 6a36d84e bellard
            return;
6457 6a36d84e bellard
        }
6458 1d14ffa9 bellard
6459 6a36d84e bellard
        p = optarg;
6460 1d14ffa9 bellard
        while (*p) {
6461 1d14ffa9 bellard
            e = strchr (p, ',');
6462 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
6463 6a36d84e bellard
6464 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6465 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
6466 6a36d84e bellard
                    c->enabled = 1;
6467 1d14ffa9 bellard
                    break;
6468 1d14ffa9 bellard
                }
6469 1d14ffa9 bellard
            }
6470 6a36d84e bellard
6471 6a36d84e bellard
            if (!c->name) {
6472 1d14ffa9 bellard
                if (l > 80) {
6473 1d14ffa9 bellard
                    fprintf (stderr,
6474 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
6475 1d14ffa9 bellard
                }
6476 1d14ffa9 bellard
                else {
6477 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
6478 1d14ffa9 bellard
                             (int) l, p);
6479 1d14ffa9 bellard
                }
6480 1d14ffa9 bellard
                bad_card = 1;
6481 1d14ffa9 bellard
            }
6482 1d14ffa9 bellard
            p += l + (e != NULL);
6483 1d14ffa9 bellard
        }
6484 1d14ffa9 bellard
6485 1d14ffa9 bellard
        if (bad_card)
6486 1d14ffa9 bellard
            goto show_valid_cards;
6487 1d14ffa9 bellard
    }
6488 1d14ffa9 bellard
}
6489 1d14ffa9 bellard
#endif
6490 1d14ffa9 bellard
6491 3587d7e6 bellard
#ifdef _WIN32
6492 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
6493 3587d7e6 bellard
{
6494 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
6495 3587d7e6 bellard
    return TRUE;
6496 3587d7e6 bellard
}
6497 3587d7e6 bellard
#endif
6498 3587d7e6 bellard
6499 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
6500 c20709aa bellard
6501 0824d6fc bellard
int main(int argc, char **argv)
6502 0824d6fc bellard
{
6503 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6504 c636bb66 bellard
    int use_gdbstub, gdbstub_port;
6505 67b915a5 bellard
#endif
6506 cc1daa40 bellard
    int i, cdrom_index;
6507 1ccde1cb bellard
    int snapshot, linux_boot;
6508 7f7f9873 bellard
    const char *initrd_filename;
6509 96d30e48 ths
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
6510 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
6511 313aa567 bellard
    DisplayState *ds = &display_state;
6512 46d4767d bellard
    int cyls, heads, secs, translation;
6513 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
6514 7c9d8e07 bellard
    int nb_net_clients;
6515 cd6f1169 bellard
    int optind;
6516 cd6f1169 bellard
    const char *r, *optarg;
6517 82c643ff bellard
    CharDriverState *monitor_hd;
6518 82c643ff bellard
    char monitor_device[128];
6519 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
6520 8d11df9e bellard
    int serial_device_index;
6521 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
6522 6508fe59 bellard
    int parallel_device_index;
6523 d63d307f bellard
    const char *loadvm = NULL;
6524 cc1daa40 bellard
    QEMUMachine *machine;
6525 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
6526 a594cfbf bellard
    int usb_devices_index;
6527 71e3ceb8 ths
    int fds[2];
6528 0bd48850 bellard
6529 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
6530 be995c27 bellard
#ifndef _WIN32
6531 be995c27 bellard
    {
6532 be995c27 bellard
        struct sigaction act;
6533 be995c27 bellard
        sigfillset(&act.sa_mask);
6534 be995c27 bellard
        act.sa_flags = 0;
6535 be995c27 bellard
        act.sa_handler = SIG_IGN;
6536 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
6537 be995c27 bellard
    }
6538 3587d7e6 bellard
#else
6539 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
6540 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
6541 a8e5ac33 bellard
       QEMU to run on a single CPU */
6542 a8e5ac33 bellard
    {
6543 a8e5ac33 bellard
        HANDLE h;
6544 a8e5ac33 bellard
        DWORD mask, smask;
6545 a8e5ac33 bellard
        int i;
6546 a8e5ac33 bellard
        h = GetCurrentProcess();
6547 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
6548 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
6549 a8e5ac33 bellard
                if (mask & (1 << i))
6550 a8e5ac33 bellard
                    break;
6551 a8e5ac33 bellard
            }
6552 a8e5ac33 bellard
            if (i != 32) {
6553 a8e5ac33 bellard
                mask = 1 << i;
6554 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
6555 a8e5ac33 bellard
            }
6556 a8e5ac33 bellard
        }
6557 a8e5ac33 bellard
    }
6558 67b915a5 bellard
#endif
6559 be995c27 bellard
6560 cc1daa40 bellard
    register_machines();
6561 cc1daa40 bellard
    machine = first_machine;
6562 fc01f7e7 bellard
    initrd_filename = NULL;
6563 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
6564 c45886db bellard
        fd_filename[i] = NULL;
6565 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++)
6566 96d30e48 ths
        hd_filename[i] = NULL;
6567 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
6568 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
6569 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6570 b4608c04 bellard
    use_gdbstub = 0;
6571 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
6572 67b915a5 bellard
#endif
6573 33e3963e bellard
    snapshot = 0;
6574 a20dd508 bellard
    nographic = 0;
6575 a20dd508 bellard
    kernel_filename = NULL;
6576 a20dd508 bellard
    kernel_cmdline = "";
6577 cc1daa40 bellard
#ifdef TARGET_PPC
6578 cc1daa40 bellard
    cdrom_index = 1;
6579 cc1daa40 bellard
#else
6580 cc1daa40 bellard
    cdrom_index = 2;
6581 cc1daa40 bellard
#endif
6582 c4b1fcc0 bellard
    cyls = heads = secs = 0;
6583 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
6584 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
6585 c4b1fcc0 bellard
6586 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
6587 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
6588 8d11df9e bellard
        serial_devices[i][0] = '\0';
6589 8d11df9e bellard
    serial_device_index = 0;
6590 8d11df9e bellard
    
6591 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
6592 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
6593 6508fe59 bellard
        parallel_devices[i][0] = '\0';
6594 6508fe59 bellard
    parallel_device_index = 0;
6595 6508fe59 bellard
    
6596 a594cfbf bellard
    usb_devices_index = 0;
6597 a594cfbf bellard
    
6598 7c9d8e07 bellard
    nb_net_clients = 0;
6599 7c9d8e07 bellard
6600 7c9d8e07 bellard
    nb_nics = 0;
6601 702c651c bellard
    /* default mac address of the first network interface */
6602 82c643ff bellard
    
6603 cd6f1169 bellard
    optind = 1;
6604 0824d6fc bellard
    for(;;) {
6605 cd6f1169 bellard
        if (optind >= argc)
6606 0824d6fc bellard
            break;
6607 cd6f1169 bellard
        r = argv[optind];
6608 cd6f1169 bellard
        if (r[0] != '-') {
6609 96d30e48 ths
            hd_filename[0] = argv[optind++];
6610 cd6f1169 bellard
        } else {
6611 cd6f1169 bellard
            const QEMUOption *popt;
6612 cd6f1169 bellard
6613 cd6f1169 bellard
            optind++;
6614 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
6615 dff5efc8 pbrook
            if (r[1] == '-')
6616 dff5efc8 pbrook
                r++;
6617 cd6f1169 bellard
            popt = qemu_options;
6618 cd6f1169 bellard
            for(;;) {
6619 cd6f1169 bellard
                if (!popt->name) {
6620 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
6621 cd6f1169 bellard
                            argv[0], r);
6622 cd6f1169 bellard
                    exit(1);
6623 cd6f1169 bellard
                }
6624 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
6625 cd6f1169 bellard
                    break;
6626 cd6f1169 bellard
                popt++;
6627 cd6f1169 bellard
            }
6628 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
6629 cd6f1169 bellard
                if (optind >= argc) {
6630 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
6631 cd6f1169 bellard
                            argv[0], r);
6632 cd6f1169 bellard
                    exit(1);
6633 cd6f1169 bellard
                }
6634 cd6f1169 bellard
                optarg = argv[optind++];
6635 cd6f1169 bellard
            } else {
6636 cd6f1169 bellard
                optarg = NULL;
6637 cd6f1169 bellard
            }
6638 cd6f1169 bellard
6639 cd6f1169 bellard
            switch(popt->index) {
6640 cc1daa40 bellard
            case QEMU_OPTION_M:
6641 cc1daa40 bellard
                machine = find_machine(optarg);
6642 cc1daa40 bellard
                if (!machine) {
6643 cc1daa40 bellard
                    QEMUMachine *m;
6644 cc1daa40 bellard
                    printf("Supported machines are:\n");
6645 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
6646 cc1daa40 bellard
                        printf("%-10s %s%s\n",
6647 cc1daa40 bellard
                               m->name, m->desc, 
6648 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
6649 cc1daa40 bellard
                    }
6650 cc1daa40 bellard
                    exit(1);
6651 cc1daa40 bellard
                }
6652 cc1daa40 bellard
                break;
6653 cd6f1169 bellard
            case QEMU_OPTION_initrd:
6654 fc01f7e7 bellard
                initrd_filename = optarg;
6655 fc01f7e7 bellard
                break;
6656 cd6f1169 bellard
            case QEMU_OPTION_hda:
6657 cd6f1169 bellard
            case QEMU_OPTION_hdb:
6658 cc1daa40 bellard
            case QEMU_OPTION_hdc:
6659 cc1daa40 bellard
            case QEMU_OPTION_hdd:
6660 cc1daa40 bellard
                {
6661 cc1daa40 bellard
                    int hd_index;
6662 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
6663 96d30e48 ths
                    hd_filename[hd_index] = optarg;
6664 96d30e48 ths
                    if (hd_index == cdrom_index)
6665 96d30e48 ths
                        cdrom_index = -1;
6666 cc1daa40 bellard
                }
6667 fc01f7e7 bellard
                break;
6668 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
6669 33e3963e bellard
                snapshot = 1;
6670 33e3963e bellard
                break;
6671 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
6672 330d0414 bellard
                {
6673 330d0414 bellard
                    const char *p;
6674 330d0414 bellard
                    p = optarg;
6675 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
6676 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
6677 46d4767d bellard
                        goto chs_fail;
6678 330d0414 bellard
                    if (*p != ',')
6679 330d0414 bellard
                        goto chs_fail;
6680 330d0414 bellard
                    p++;
6681 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
6682 46d4767d bellard
                    if (heads < 1 || heads > 16)
6683 46d4767d bellard
                        goto chs_fail;
6684 330d0414 bellard
                    if (*p != ',')
6685 330d0414 bellard
                        goto chs_fail;
6686 330d0414 bellard
                    p++;
6687 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
6688 46d4767d bellard
                    if (secs < 1 || secs > 63)
6689 46d4767d bellard
                        goto chs_fail;
6690 46d4767d bellard
                    if (*p == ',') {
6691 46d4767d bellard
                        p++;
6692 46d4767d bellard
                        if (!strcmp(p, "none"))
6693 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
6694 46d4767d bellard
                        else if (!strcmp(p, "lba"))
6695 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
6696 46d4767d bellard
                        else if (!strcmp(p, "auto"))
6697 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
6698 46d4767d bellard
                        else
6699 46d4767d bellard
                            goto chs_fail;
6700 46d4767d bellard
                    } else if (*p != '\0') {
6701 c4b1fcc0 bellard
                    chs_fail:
6702 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
6703 46d4767d bellard
                        exit(1);
6704 c4b1fcc0 bellard
                    }
6705 330d0414 bellard
                }
6706 330d0414 bellard
                break;
6707 cd6f1169 bellard
            case QEMU_OPTION_nographic:
6708 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
6709 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
6710 a20dd508 bellard
                nographic = 1;
6711 a20dd508 bellard
                break;
6712 cd6f1169 bellard
            case QEMU_OPTION_kernel:
6713 a20dd508 bellard
                kernel_filename = optarg;
6714 a20dd508 bellard
                break;
6715 cd6f1169 bellard
            case QEMU_OPTION_append:
6716 a20dd508 bellard
                kernel_cmdline = optarg;
6717 313aa567 bellard
                break;
6718 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
6719 96d30e48 ths
                if (cdrom_index >= 0) {
6720 96d30e48 ths
                    hd_filename[cdrom_index] = optarg;
6721 fa1fb14c ths
                }
6722 36b486bb bellard
                break;
6723 cd6f1169 bellard
            case QEMU_OPTION_boot:
6724 36b486bb bellard
                boot_device = optarg[0];
6725 9e89a4be bellard
                if (boot_device != 'a' && 
6726 eec85c2a ths
#if defined(TARGET_SPARC) || defined(TARGET_I386)
6727 6f7e9aec bellard
                    // Network boot
6728 6f7e9aec bellard
                    boot_device != 'n' &&
6729 6f7e9aec bellard
#endif
6730 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
6731 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
6732 36b486bb bellard
                    exit(1);
6733 36b486bb bellard
                }
6734 36b486bb bellard
                break;
6735 cd6f1169 bellard
            case QEMU_OPTION_fda:
6736 c45886db bellard
                fd_filename[0] = optarg;
6737 c45886db bellard
                break;
6738 cd6f1169 bellard
            case QEMU_OPTION_fdb:
6739 c45886db bellard
                fd_filename[1] = optarg;
6740 c45886db bellard
                break;
6741 52ca8d6a bellard
#ifdef TARGET_I386
6742 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
6743 52ca8d6a bellard
                fd_bootchk = 0;
6744 52ca8d6a bellard
                break;
6745 52ca8d6a bellard
#endif
6746 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
6747 77fef8c1 bellard
                code_copy_enabled = 0;
6748 77fef8c1 bellard
                break;
6749 7c9d8e07 bellard
            case QEMU_OPTION_net:
6750 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
6751 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
6752 c4b1fcc0 bellard
                    exit(1);
6753 c4b1fcc0 bellard
                }
6754 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
6755 7c9d8e07 bellard
                        sizeof(net_clients[0]),
6756 7c9d8e07 bellard
                        optarg);
6757 7c9d8e07 bellard
                nb_net_clients++;
6758 702c651c bellard
                break;
6759 c7f74643 bellard
#ifdef CONFIG_SLIRP
6760 c7f74643 bellard
            case QEMU_OPTION_tftp:
6761 c7f74643 bellard
                tftp_prefix = optarg;
6762 9bf05444 bellard
                break;
6763 c94c8d64 bellard
#ifndef _WIN32
6764 9d728e8c bellard
            case QEMU_OPTION_smb:
6765 9d728e8c bellard
                net_slirp_smb(optarg);
6766 9d728e8c bellard
                break;
6767 c94c8d64 bellard
#endif
6768 9bf05444 bellard
            case QEMU_OPTION_redir:
6769 9bf05444 bellard
                net_slirp_redir(optarg);                
6770 9bf05444 bellard
                break;
6771 c7f74643 bellard
#endif
6772 1d14ffa9 bellard
#ifdef HAS_AUDIO
6773 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
6774 1d14ffa9 bellard
                AUD_help ();
6775 1d14ffa9 bellard
                exit (0);
6776 1d14ffa9 bellard
                break;
6777 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
6778 1d14ffa9 bellard
                select_soundhw (optarg);
6779 1d14ffa9 bellard
                break;
6780 1d14ffa9 bellard
#endif
6781 cd6f1169 bellard
            case QEMU_OPTION_h:
6782 0824d6fc bellard
                help();
6783 cd6f1169 bellard
                break;
6784 cd6f1169 bellard
            case QEMU_OPTION_m:
6785 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
6786 cd6f1169 bellard
                if (ram_size <= 0)
6787 cd6f1169 bellard
                    help();
6788 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
6789 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
6790 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
6791 cd6f1169 bellard
                    exit(1);
6792 cd6f1169 bellard
                }
6793 cd6f1169 bellard
                break;
6794 cd6f1169 bellard
            case QEMU_OPTION_d:
6795 cd6f1169 bellard
                {
6796 cd6f1169 bellard
                    int mask;
6797 cd6f1169 bellard
                    CPULogItem *item;
6798 cd6f1169 bellard
                    
6799 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
6800 cd6f1169 bellard
                    if (!mask) {
6801 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
6802 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
6803 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
6804 f193c797 bellard
                    }
6805 f193c797 bellard
                    exit(1);
6806 cd6f1169 bellard
                    }
6807 cd6f1169 bellard
                    cpu_set_log(mask);
6808 f193c797 bellard
                }
6809 cd6f1169 bellard
                break;
6810 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6811 cd6f1169 bellard
            case QEMU_OPTION_s:
6812 cd6f1169 bellard
                use_gdbstub = 1;
6813 cd6f1169 bellard
                break;
6814 cd6f1169 bellard
            case QEMU_OPTION_p:
6815 c636bb66 bellard
                gdbstub_port = atoi(optarg);
6816 cd6f1169 bellard
                break;
6817 67b915a5 bellard
#endif
6818 cd6f1169 bellard
            case QEMU_OPTION_L:
6819 cd6f1169 bellard
                bios_dir = optarg;
6820 cd6f1169 bellard
                break;
6821 cd6f1169 bellard
            case QEMU_OPTION_S:
6822 3c07f8e8 pbrook
                autostart = 0;
6823 cd6f1169 bellard
                break;
6824 3d11d0eb bellard
            case QEMU_OPTION_k:
6825 3d11d0eb bellard
                keyboard_layout = optarg;
6826 3d11d0eb bellard
                break;
6827 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
6828 ee22c2f7 bellard
                rtc_utc = 0;
6829 ee22c2f7 bellard
                break;
6830 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
6831 1f04275e bellard
                cirrus_vga_enabled = 1;
6832 1f04275e bellard
                break;
6833 1bfe856e bellard
            case QEMU_OPTION_std_vga:
6834 1bfe856e bellard
                cirrus_vga_enabled = 0;
6835 1bfe856e bellard
                break;
6836 e9b137c2 bellard
            case QEMU_OPTION_g:
6837 e9b137c2 bellard
                {
6838 e9b137c2 bellard
                    const char *p;
6839 e9b137c2 bellard
                    int w, h, depth;
6840 e9b137c2 bellard
                    p = optarg;
6841 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
6842 e9b137c2 bellard
                    if (w <= 0) {
6843 e9b137c2 bellard
                    graphic_error:
6844 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
6845 e9b137c2 bellard
                        exit(1);
6846 e9b137c2 bellard
                    }
6847 e9b137c2 bellard
                    if (*p != 'x')
6848 e9b137c2 bellard
                        goto graphic_error;
6849 e9b137c2 bellard
                    p++;
6850 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
6851 e9b137c2 bellard
                    if (h <= 0)
6852 e9b137c2 bellard
                        goto graphic_error;
6853 e9b137c2 bellard
                    if (*p == 'x') {
6854 e9b137c2 bellard
                        p++;
6855 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
6856 e9b137c2 bellard
                        if (depth != 8 && depth != 15 && depth != 16 && 
6857 e9b137c2 bellard
                            depth != 24 && depth != 32)
6858 e9b137c2 bellard
                            goto graphic_error;
6859 e9b137c2 bellard
                    } else if (*p == '\0') {
6860 e9b137c2 bellard
                        depth = graphic_depth;
6861 e9b137c2 bellard
                    } else {
6862 e9b137c2 bellard
                        goto graphic_error;
6863 e9b137c2 bellard
                    }
6864 e9b137c2 bellard
                    
6865 e9b137c2 bellard
                    graphic_width = w;
6866 e9b137c2 bellard
                    graphic_height = h;
6867 e9b137c2 bellard
                    graphic_depth = depth;
6868 e9b137c2 bellard
                }
6869 e9b137c2 bellard
                break;
6870 82c643ff bellard
            case QEMU_OPTION_monitor:
6871 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
6872 82c643ff bellard
                break;
6873 82c643ff bellard
            case QEMU_OPTION_serial:
6874 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
6875 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
6876 8d11df9e bellard
                    exit(1);
6877 8d11df9e bellard
                }
6878 8d11df9e bellard
                pstrcpy(serial_devices[serial_device_index], 
6879 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
6880 8d11df9e bellard
                serial_device_index++;
6881 82c643ff bellard
                break;
6882 6508fe59 bellard
            case QEMU_OPTION_parallel:
6883 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
6884 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
6885 6508fe59 bellard
                    exit(1);
6886 6508fe59 bellard
                }
6887 6508fe59 bellard
                pstrcpy(parallel_devices[parallel_device_index], 
6888 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
6889 6508fe59 bellard
                parallel_device_index++;
6890 6508fe59 bellard
                break;
6891 d63d307f bellard
            case QEMU_OPTION_loadvm:
6892 d63d307f bellard
                loadvm = optarg;
6893 d63d307f bellard
                break;
6894 d63d307f bellard
            case QEMU_OPTION_full_screen:
6895 d63d307f bellard
                full_screen = 1;
6896 d63d307f bellard
                break;
6897 667accab ths
#ifdef CONFIG_SDL
6898 667accab ths
            case QEMU_OPTION_no_quit:
6899 667accab ths
                no_quit = 1;
6900 667accab ths
                break;
6901 667accab ths
#endif
6902 f7cce898 bellard
            case QEMU_OPTION_pidfile:
6903 f7cce898 bellard
                create_pidfile(optarg);
6904 f7cce898 bellard
                break;
6905 a09db21f bellard
#ifdef TARGET_I386
6906 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
6907 a09db21f bellard
                win2k_install_hack = 1;
6908 a09db21f bellard
                break;
6909 a09db21f bellard
#endif
6910 d993e026 bellard
#ifdef USE_KQEMU
6911 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
6912 d993e026 bellard
                kqemu_allowed = 0;
6913 d993e026 bellard
                break;
6914 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
6915 89bfc105 bellard
                kqemu_allowed = 2;
6916 89bfc105 bellard
                break;
6917 d993e026 bellard
#endif
6918 bb36d470 bellard
            case QEMU_OPTION_usb:
6919 bb36d470 bellard
                usb_enabled = 1;
6920 bb36d470 bellard
                break;
6921 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
6922 a594cfbf bellard
                usb_enabled = 1;
6923 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
6924 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
6925 a594cfbf bellard
                    exit(1);
6926 a594cfbf bellard
                }
6927 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
6928 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
6929 a594cfbf bellard
                        optarg);
6930 a594cfbf bellard
                usb_devices_index++;
6931 a594cfbf bellard
                break;
6932 6a00d601 bellard
            case QEMU_OPTION_smp:
6933 6a00d601 bellard
                smp_cpus = atoi(optarg);
6934 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
6935 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
6936 6a00d601 bellard
                    exit(1);
6937 6a00d601 bellard
                }
6938 6a00d601 bellard
                break;
6939 24236869 bellard
            case QEMU_OPTION_vnc:
6940 73fc9742 ths
                vnc_display = optarg;
6941 24236869 bellard
                break;
6942 6515b203 bellard
            case QEMU_OPTION_no_acpi:
6943 6515b203 bellard
                acpi_enabled = 0;
6944 6515b203 bellard
                break;
6945 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
6946 d1beab82 bellard
                no_reboot = 1;
6947 d1beab82 bellard
                break;
6948 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
6949 71e3ceb8 ths
                daemonize = 1;
6950 71e3ceb8 ths
                break;
6951 9ae02555 ths
            case QEMU_OPTION_option_rom:
6952 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
6953 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
6954 9ae02555 ths
                    exit(1);
6955 9ae02555 ths
                }
6956 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
6957 9ae02555 ths
                nb_option_roms++;
6958 9ae02555 ths
                break;
6959 8e71621f pbrook
            case QEMU_OPTION_semihosting:
6960 8e71621f pbrook
                semihosting_enabled = 1;
6961 8e71621f pbrook
                break;
6962 cd6f1169 bellard
            }
6963 0824d6fc bellard
        }
6964 0824d6fc bellard
    }
6965 330d0414 bellard
6966 71e3ceb8 ths
#ifndef _WIN32
6967 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
6968 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
6969 71e3ceb8 ths
        daemonize = 0;
6970 71e3ceb8 ths
    }
6971 71e3ceb8 ths
6972 71e3ceb8 ths
    if (daemonize) {
6973 71e3ceb8 ths
        pid_t pid;
6974 71e3ceb8 ths
6975 71e3ceb8 ths
        if (pipe(fds) == -1)
6976 71e3ceb8 ths
            exit(1);
6977 71e3ceb8 ths
6978 71e3ceb8 ths
        pid = fork();
6979 71e3ceb8 ths
        if (pid > 0) {
6980 71e3ceb8 ths
            uint8_t status;
6981 71e3ceb8 ths
            ssize_t len;
6982 71e3ceb8 ths
6983 71e3ceb8 ths
            close(fds[1]);
6984 71e3ceb8 ths
6985 71e3ceb8 ths
        again:
6986 71e3ceb8 ths
            len = read(fds[0], &status, 1);
6987 71e3ceb8 ths
            if (len == -1 && (errno == EINTR))
6988 71e3ceb8 ths
                goto again;
6989 71e3ceb8 ths
            
6990 71e3ceb8 ths
            if (len != 1 || status != 0)
6991 71e3ceb8 ths
                exit(1);
6992 71e3ceb8 ths
            else
6993 71e3ceb8 ths
                exit(0);
6994 71e3ceb8 ths
        } else if (pid < 0)
6995 71e3ceb8 ths
            exit(1);
6996 71e3ceb8 ths
6997 71e3ceb8 ths
        setsid();
6998 71e3ceb8 ths
6999 71e3ceb8 ths
        pid = fork();
7000 71e3ceb8 ths
        if (pid > 0)
7001 71e3ceb8 ths
            exit(0);
7002 71e3ceb8 ths
        else if (pid < 0)
7003 71e3ceb8 ths
            exit(1);
7004 71e3ceb8 ths
7005 71e3ceb8 ths
        umask(027);
7006 71e3ceb8 ths
        chdir("/");
7007 71e3ceb8 ths
7008 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
7009 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
7010 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
7011 71e3ceb8 ths
    }
7012 71e3ceb8 ths
#endif
7013 71e3ceb8 ths
7014 ff3fbb30 bellard
#ifdef USE_KQEMU
7015 ff3fbb30 bellard
    if (smp_cpus > 1)
7016 ff3fbb30 bellard
        kqemu_allowed = 0;
7017 ff3fbb30 bellard
#endif
7018 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
7019 42550fde ths
7020 42550fde ths
    if (!linux_boot &&
7021 96d30e48 ths
        hd_filename[0] == '\0' && 
7022 96d30e48 ths
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
7023 c45886db bellard
        fd_filename[0] == '\0')
7024 0824d6fc bellard
        help();
7025 0824d6fc bellard
7026 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
7027 96d30e48 ths
    if (hd_filename[0] == '\0' && boot_device == 'c') {
7028 96d30e48 ths
        if (fd_filename[0] != '\0')
7029 96d30e48 ths
            boot_device = 'a';
7030 96d30e48 ths
        else
7031 96d30e48 ths
            boot_device = 'd';
7032 96d30e48 ths
    }
7033 96d30e48 ths
7034 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
7035 7c9d8e07 bellard
    
7036 634fce96 pbrook
    init_timers();
7037 634fce96 pbrook
    init_timer_alarm();
7038 83f64091 bellard
    qemu_aio_init();
7039 634fce96 pbrook
7040 fd1dff4b bellard
#ifdef _WIN32
7041 fd1dff4b bellard
    socket_init();
7042 fd1dff4b bellard
#endif
7043 fd1dff4b bellard
7044 7c9d8e07 bellard
    /* init network clients */
7045 7c9d8e07 bellard
    if (nb_net_clients == 0) {
7046 7c9d8e07 bellard
        /* if no clients, we use a default config */
7047 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
7048 7c9d8e07 bellard
                "nic");
7049 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
7050 7c9d8e07 bellard
                "user");
7051 7c9d8e07 bellard
        nb_net_clients = 2;
7052 c20709aa bellard
    }
7053 c20709aa bellard
7054 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
7055 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
7056 7c9d8e07 bellard
            exit(1);
7057 702c651c bellard
    }
7058 f1510b2c bellard
7059 eec85c2a ths
#ifdef TARGET_I386
7060 eec85c2a ths
    if (boot_device == 'n') {
7061 eec85c2a ths
        for (i = 0; i < nb_nics; i++) {
7062 eec85c2a ths
            const char *model = nd_table[i].model;
7063 eec85c2a ths
            char buf[1024];
7064 eec85c2a ths
            if (model == NULL)
7065 eec85c2a ths
                model = "ne2k_pci";
7066 eec85c2a ths
            snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
7067 eec85c2a ths
            if (get_image_size(buf) > 0) {
7068 eec85c2a ths
                option_rom[nb_option_roms] = strdup(buf);
7069 eec85c2a ths
                nb_option_roms++;
7070 eec85c2a ths
                break;
7071 eec85c2a ths
            }
7072 eec85c2a ths
        }
7073 eec85c2a ths
        if (i == nb_nics) {
7074 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
7075 eec85c2a ths
            exit(1);
7076 eec85c2a ths
        }
7077 eec85c2a ths
        boot_device = 'c'; /* to prevent confusion by the BIOS */
7078 eec85c2a ths
    }
7079 eec85c2a ths
#endif
7080 eec85c2a ths
7081 0824d6fc bellard
    /* init the memory */
7082 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
7083 9ae02555 ths
7084 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
7085 7f7f9873 bellard
    if (!phys_ram_base) {
7086 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
7087 0824d6fc bellard
        exit(1);
7088 0824d6fc bellard
    }
7089 0824d6fc bellard
7090 96d30e48 ths
    /* we always create the cdrom drive, even if no disk is there */
7091 5905b2e5 bellard
    bdrv_init();
7092 96d30e48 ths
    if (cdrom_index >= 0) {
7093 96d30e48 ths
        bs_table[cdrom_index] = bdrv_new("cdrom");
7094 96d30e48 ths
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
7095 c4b1fcc0 bellard
    }
7096 c4b1fcc0 bellard
7097 96d30e48 ths
    /* open the virtual block devices */
7098 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++) {
7099 96d30e48 ths
        if (hd_filename[i]) {
7100 96d30e48 ths
            if (!bs_table[i]) {
7101 96d30e48 ths
                char buf[64];
7102 96d30e48 ths
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
7103 96d30e48 ths
                bs_table[i] = bdrv_new(buf);
7104 96d30e48 ths
            }
7105 96d30e48 ths
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7106 96d30e48 ths
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
7107 96d30e48 ths
                        hd_filename[i]);
7108 96d30e48 ths
                exit(1);
7109 96d30e48 ths
            }
7110 96d30e48 ths
            if (i == 0 && cyls != 0) {
7111 96d30e48 ths
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
7112 96d30e48 ths
                bdrv_set_translation_hint(bs_table[i], translation);
7113 96d30e48 ths
            }
7114 96d30e48 ths
        }
7115 c4b1fcc0 bellard
    }
7116 c4b1fcc0 bellard
7117 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
7118 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
7119 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
7120 c4b1fcc0 bellard
7121 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
7122 c4b1fcc0 bellard
        if (fd_filename[i]) {
7123 c4b1fcc0 bellard
            if (!fd_table[i]) {
7124 c4b1fcc0 bellard
                char buf[64];
7125 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
7126 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
7127 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
7128 c4b1fcc0 bellard
            }
7129 c4b1fcc0 bellard
            if (fd_filename[i] != '\0') {
7130 83f64091 bellard
                if (bdrv_open(fd_table[i], fd_filename[i],
7131 83f64091 bellard
                              snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7132 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
7133 c4b1fcc0 bellard
                            fd_filename[i]);
7134 c4b1fcc0 bellard
                    exit(1);
7135 c4b1fcc0 bellard
                }
7136 c4b1fcc0 bellard
            }
7137 33e3963e bellard
        }
7138 33e3963e bellard
    }
7139 33e3963e bellard
7140 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
7141 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
7142 8a7ddc38 bellard
7143 330d0414 bellard
    init_ioports();
7144 0824d6fc bellard
7145 313aa567 bellard
    /* terminal init */
7146 a20dd508 bellard
    if (nographic) {
7147 313aa567 bellard
        dumb_display_init(ds);
7148 73fc9742 ths
    } else if (vnc_display != NULL) {
7149 24236869 bellard
        vnc_display_init(ds, vnc_display);
7150 313aa567 bellard
    } else {
7151 5b0753e0 bellard
#if defined(CONFIG_SDL)
7152 d63d307f bellard
        sdl_display_init(ds, full_screen);
7153 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
7154 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
7155 313aa567 bellard
#else
7156 313aa567 bellard
        dumb_display_init(ds);
7157 313aa567 bellard
#endif
7158 313aa567 bellard
    }
7159 0824d6fc bellard
7160 82c643ff bellard
    monitor_hd = qemu_chr_open(monitor_device);
7161 82c643ff bellard
    if (!monitor_hd) {
7162 82c643ff bellard
        fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
7163 82c643ff bellard
        exit(1);
7164 82c643ff bellard
    }
7165 82c643ff bellard
    monitor_init(monitor_hd, !nographic);
7166 82c643ff bellard
7167 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
7168 c03b0f0f bellard
        const char *devname = serial_devices[i];
7169 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7170 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
7171 8d11df9e bellard
            if (!serial_hds[i]) {
7172 8d11df9e bellard
                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
7173 c03b0f0f bellard
                        devname);
7174 8d11df9e bellard
                exit(1);
7175 8d11df9e bellard
            }
7176 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7177 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
7178 8d11df9e bellard
        }
7179 82c643ff bellard
    }
7180 82c643ff bellard
7181 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
7182 c03b0f0f bellard
        const char *devname = parallel_devices[i];
7183 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7184 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
7185 6508fe59 bellard
            if (!parallel_hds[i]) {
7186 6508fe59 bellard
                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
7187 c03b0f0f bellard
                        devname);
7188 6508fe59 bellard
                exit(1);
7189 6508fe59 bellard
            }
7190 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7191 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
7192 6508fe59 bellard
        }
7193 6508fe59 bellard
    }
7194 6508fe59 bellard
7195 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
7196 cc1daa40 bellard
                  ds, fd_filename, snapshot,
7197 cc1daa40 bellard
                  kernel_filename, kernel_cmdline, initrd_filename);
7198 73332e5c bellard
7199 0d92ed30 pbrook
    /* init USB devices */
7200 0d92ed30 pbrook
    if (usb_enabled) {
7201 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
7202 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
7203 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
7204 0d92ed30 pbrook
                        usb_devices[i]);
7205 0d92ed30 pbrook
            }
7206 0d92ed30 pbrook
        }
7207 0d92ed30 pbrook
    }
7208 0d92ed30 pbrook
7209 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
7210 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
7211 7f7f9873 bellard
7212 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7213 b4608c04 bellard
    if (use_gdbstub) {
7214 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
7215 c636bb66 bellard
           accordingly. */
7216 c636bb66 bellard
        if (gdbserver_start_port(gdbstub_port) < 0) {
7217 c636bb66 bellard
            fprintf(stderr, "qemu: could not open gdbstub device on port '%d'\n",
7218 c636bb66 bellard
                    gdbstub_port);
7219 8a7ddc38 bellard
            exit(1);
7220 8a7ddc38 bellard
        }
7221 67b915a5 bellard
    } else 
7222 67b915a5 bellard
#endif
7223 d63d307f bellard
    if (loadvm)
7224 faea38e7 bellard
        do_loadvm(loadvm);
7225 d63d307f bellard
7226 67b915a5 bellard
    {
7227 5905b2e5 bellard
        /* XXX: simplify init */
7228 5905b2e5 bellard
        read_passwords();
7229 3c07f8e8 pbrook
        if (autostart) {
7230 5905b2e5 bellard
            vm_start();
7231 5905b2e5 bellard
        }
7232 0824d6fc bellard
    }
7233 ffd843bc ths
7234 71e3ceb8 ths
    if (daemonize) {
7235 71e3ceb8 ths
        uint8_t status = 0;
7236 71e3ceb8 ths
        ssize_t len;
7237 71e3ceb8 ths
        int fd;
7238 71e3ceb8 ths
7239 71e3ceb8 ths
    again1:
7240 71e3ceb8 ths
        len = write(fds[1], &status, 1);
7241 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
7242 71e3ceb8 ths
            goto again1;
7243 71e3ceb8 ths
7244 71e3ceb8 ths
        if (len != 1)
7245 71e3ceb8 ths
            exit(1);
7246 71e3ceb8 ths
7247 71e3ceb8 ths
        fd = open("/dev/null", O_RDWR);
7248 71e3ceb8 ths
        if (fd == -1)
7249 71e3ceb8 ths
            exit(1);
7250 71e3ceb8 ths
7251 71e3ceb8 ths
        dup2(fd, 0);
7252 71e3ceb8 ths
        dup2(fd, 1);
7253 71e3ceb8 ths
        dup2(fd, 2);
7254 71e3ceb8 ths
7255 71e3ceb8 ths
        close(fd);
7256 71e3ceb8 ths
    }
7257 71e3ceb8 ths
7258 8a7ddc38 bellard
    main_loop();
7259 40c3bac3 bellard
    quit_timers();
7260 0824d6fc bellard
    return 0;
7261 0824d6fc bellard
}