Statistics
| Branch: | Revision:

root / vl.c @ 95219897

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