Statistics
| Branch: | Revision:

root / vl.c @ 83f64091

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