Statistics
| Branch: | Revision:

root / vl.c @ 215cf0be

History | View | Annotate | Download (145 kB)

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