Statistics
| Branch: | Revision:

root / vl.c @ 5fe141fd

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