Statistics
| Branch: | Revision:

root / vl.c @ 188157fe

History | View | Annotate | Download (177.1 kB)

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

5325 c88676f8 bellard
            /* find if the memory block is available on a virtual
5326 c88676f8 bellard
               block device */
5327 c88676f8 bellard
            sector_num = -1;
5328 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5329 c88676f8 bellard
                if (bs_table[j]) {
5330 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5331 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5332 c88676f8 bellard
                    if (sector_num >= 0)
5333 c88676f8 bellard
                        break;
5334 c88676f8 bellard
                }
5335 c88676f8 bellard
            }
5336 c88676f8 bellard
            if (j == MAX_DISKS)
5337 c88676f8 bellard
                goto normal_compress;
5338 c88676f8 bellard
            buf[0] = 1;
5339 c88676f8 bellard
            buf[1] = j;
5340 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5341 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5342 c88676f8 bellard
        } else 
5343 c88676f8 bellard
#endif
5344 c88676f8 bellard
        {
5345 c88676f8 bellard
            //        normal_compress:
5346 c88676f8 bellard
            buf[0] = 0;
5347 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5348 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5349 c88676f8 bellard
        }
5350 8a7ddc38 bellard
    }
5351 c88676f8 bellard
    ram_compress_close(s);
5352 8a7ddc38 bellard
}
5353 8a7ddc38 bellard
5354 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5355 8a7ddc38 bellard
{
5356 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5357 c88676f8 bellard
    uint8_t buf[10];
5358 c88676f8 bellard
    int i;
5359 8a7ddc38 bellard
5360 c88676f8 bellard
    if (version_id == 1)
5361 c88676f8 bellard
        return ram_load_v1(f, opaque);
5362 c88676f8 bellard
    if (version_id != 2)
5363 8a7ddc38 bellard
        return -EINVAL;
5364 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5365 8a7ddc38 bellard
        return -EINVAL;
5366 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5367 c88676f8 bellard
        return -EINVAL;
5368 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5369 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5370 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5371 c88676f8 bellard
            goto error;
5372 c88676f8 bellard
        }
5373 c88676f8 bellard
        if (buf[0] == 0) {
5374 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5375 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5376 c88676f8 bellard
                goto error;
5377 c88676f8 bellard
            }
5378 c88676f8 bellard
        } else 
5379 c88676f8 bellard
#if 0
5380 c88676f8 bellard
        if (buf[0] == 1) {
5381 c88676f8 bellard
            int bs_index;
5382 c88676f8 bellard
            int64_t sector_num;
5383 c88676f8 bellard

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