Statistics
| Branch: | Revision:

root / vl.c @ d796321b

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