Statistics
| Branch: | Revision:

root / vl.c @ 94ac5158

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