Statistics
| Branch: | Revision:

root / vl.c @ 3dbbdc25

History | View | Annotate | Download (106.5 kB)

1 0824d6fc bellard
/*
2 80cabfad bellard
 * QEMU System Emulator
3 0824d6fc bellard
 * 
4 d827220b bellard
 * Copyright (c) 2003-2005 Fabrice Bellard
5 0824d6fc bellard
 * 
6 1df912cf bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1df912cf bellard
 * of this software and associated documentation files (the "Software"), to deal
8 1df912cf bellard
 * in the Software without restriction, including without limitation the rights
9 1df912cf bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1df912cf bellard
 * copies of the Software, and to permit persons to whom the Software is
11 1df912cf bellard
 * furnished to do so, subject to the following conditions:
12 1df912cf bellard
 *
13 1df912cf bellard
 * The above copyright notice and this permission notice shall be included in
14 1df912cf bellard
 * all copies or substantial portions of the Software.
15 1df912cf bellard
 *
16 1df912cf bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1df912cf bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1df912cf bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1df912cf bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1df912cf bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1df912cf bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1df912cf bellard
 * THE SOFTWARE.
23 0824d6fc bellard
 */
24 67b915a5 bellard
#include "vl.h"
25 67b915a5 bellard
26 0824d6fc bellard
#include <unistd.h>
27 0824d6fc bellard
#include <fcntl.h>
28 0824d6fc bellard
#include <signal.h>
29 0824d6fc bellard
#include <time.h>
30 0824d6fc bellard
#include <errno.h>
31 67b915a5 bellard
#include <sys/time.h>
32 67b915a5 bellard
33 67b915a5 bellard
#ifndef _WIN32
34 67b915a5 bellard
#include <sys/times.h>
35 f1510b2c bellard
#include <sys/wait.h>
36 67b915a5 bellard
#include <termios.h>
37 67b915a5 bellard
#include <sys/poll.h>
38 67b915a5 bellard
#include <sys/mman.h>
39 f1510b2c bellard
#include <sys/ioctl.h>
40 f1510b2c bellard
#include <sys/socket.h>
41 c94c8d64 bellard
#include <netinet/in.h>
42 9d728e8c bellard
#include <dirent.h>
43 7d3505c5 bellard
#ifdef _BSD
44 7d3505c5 bellard
#include <sys/stat.h>
45 83fb7adf bellard
#ifndef __APPLE__
46 7d3505c5 bellard
#include <libutil.h>
47 83fb7adf bellard
#endif
48 7d3505c5 bellard
#else
49 f1510b2c bellard
#include <linux/if.h>
50 f1510b2c bellard
#include <linux/if_tun.h>
51 7d3505c5 bellard
#include <pty.h>
52 7d3505c5 bellard
#include <malloc.h>
53 fd872598 bellard
#include <linux/rtc.h>
54 67b915a5 bellard
#endif
55 7d3505c5 bellard
#endif
56 67b915a5 bellard
57 c20709aa bellard
#if defined(CONFIG_SLIRP)
58 c20709aa bellard
#include "libslirp.h"
59 c20709aa bellard
#endif
60 c20709aa bellard
61 67b915a5 bellard
#ifdef _WIN32
62 7d3505c5 bellard
#include <malloc.h>
63 67b915a5 bellard
#include <sys/timeb.h>
64 67b915a5 bellard
#include <windows.h>
65 67b915a5 bellard
#define getopt_long_only getopt_long
66 67b915a5 bellard
#define memalign(align, size) malloc(size)
67 67b915a5 bellard
#endif
68 67b915a5 bellard
69 73332e5c bellard
#ifdef CONFIG_SDL
70 96bcd4f8 bellard
#ifdef __APPLE__
71 83fb7adf bellard
#include <SDL/SDL.h>
72 96bcd4f8 bellard
#endif
73 73332e5c bellard
#endif /* CONFIG_SDL */
74 0824d6fc bellard
75 5b0753e0 bellard
#ifdef CONFIG_COCOA
76 5b0753e0 bellard
#undef main
77 5b0753e0 bellard
#define main qemu_main
78 5b0753e0 bellard
#endif /* CONFIG_COCOA */
79 5b0753e0 bellard
80 0824d6fc bellard
#include "disas.h"
81 fc01f7e7 bellard
82 8a7ddc38 bellard
#include "exec-all.h"
83 0824d6fc bellard
84 a541f297 bellard
//#define DO_TB_FLUSH
85 a541f297 bellard
86 5a67135a bellard
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
87 f1510b2c bellard
88 0824d6fc bellard
//#define DEBUG_UNUSED_IOPORT
89 fd872598 bellard
//#define DEBUG_IOPORT
90 330d0414 bellard
91 bb551faa bellard
#if !defined(CONFIG_SOFTMMU)
92 7916e224 bellard
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
93 bb551faa bellard
#else
94 bb551faa bellard
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
95 bb551faa bellard
#endif
96 7916e224 bellard
97 77d4bc34 bellard
#ifdef TARGET_PPC
98 77d4bc34 bellard
#define DEFAULT_RAM_SIZE 144
99 77d4bc34 bellard
#else
100 1bfe856e bellard
#define DEFAULT_RAM_SIZE 128
101 77d4bc34 bellard
#endif
102 8a7ddc38 bellard
/* in ms */
103 8a7ddc38 bellard
#define GUI_REFRESH_INTERVAL 30
104 313aa567 bellard
105 7dea1da4 bellard
/* XXX: use a two level table to limit memory usage */
106 7dea1da4 bellard
#define MAX_IOPORTS 65536
107 0824d6fc bellard
108 80cabfad bellard
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
109 0824d6fc bellard
char phys_ram_file[1024];
110 c45886db bellard
CPUState *global_env;
111 c45886db bellard
CPUState *cpu_single_env;
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
static char network_script[1024];
125 80cabfad bellard
int pit_min_timer_count = 0;
126 c4b1fcc0 bellard
int nb_nics;
127 c4b1fcc0 bellard
NetDriverState nd_table[MAX_NICS];
128 8a7ddc38 bellard
QEMUTimer *gui_timer;
129 8a7ddc38 bellard
int vm_running;
130 1d14ffa9 bellard
#ifdef HAS_AUDIO
131 aaaa7df6 bellard
int audio_enabled = 0;
132 1d14ffa9 bellard
int sb16_enabled = 0;
133 1d14ffa9 bellard
int adlib_enabled = 0;
134 1d14ffa9 bellard
int gus_enabled = 0;
135 1d14ffa9 bellard
int es1370_enabled = 0;
136 1d14ffa9 bellard
#endif
137 ee22c2f7 bellard
int rtc_utc = 1;
138 1bfe856e bellard
int cirrus_vga_enabled = 1;
139 d827220b bellard
#ifdef TARGET_SPARC
140 d827220b bellard
int graphic_width = 1024;
141 d827220b bellard
int graphic_height = 768;
142 d827220b bellard
#else
143 1bfe856e bellard
int graphic_width = 800;
144 1bfe856e bellard
int graphic_height = 600;
145 d827220b bellard
#endif
146 e9b137c2 bellard
int graphic_depth = 15;
147 d63d307f bellard
int full_screen = 0;
148 82c643ff bellard
TextConsole *vga_console;
149 8d11df9e bellard
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
150 6508fe59 bellard
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
151 a09db21f bellard
#ifdef TARGET_I386
152 a09db21f bellard
int win2k_install_hack = 0;
153 a09db21f bellard
#endif
154 bb36d470 bellard
int usb_enabled = 0;
155 a594cfbf bellard
USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
156 a594cfbf bellard
USBDevice *vm_usb_hub;
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 0824d6fc bellard
}
372 0824d6fc bellard
373 c45886db bellard
void cpu_outw(CPUState *env, int addr, int val)
374 0824d6fc bellard
{
375 fd872598 bellard
#ifdef DEBUG_IOPORT
376 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
377 fd872598 bellard
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
378 fd872598 bellard
#endif    
379 c4b1fcc0 bellard
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
380 0824d6fc bellard
}
381 0824d6fc bellard
382 c45886db bellard
void cpu_outl(CPUState *env, int addr, int val)
383 0824d6fc bellard
{
384 fd872598 bellard
#ifdef DEBUG_IOPORT
385 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
386 fd872598 bellard
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
387 fd872598 bellard
#endif
388 c4b1fcc0 bellard
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
389 0824d6fc bellard
}
390 0824d6fc bellard
391 c45886db bellard
int cpu_inb(CPUState *env, int addr)
392 0824d6fc bellard
{
393 fd872598 bellard
    int val;
394 fd872598 bellard
    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
395 fd872598 bellard
#ifdef DEBUG_IOPORT
396 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
397 fd872598 bellard
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
398 fd872598 bellard
#endif
399 fd872598 bellard
    return val;
400 0824d6fc bellard
}
401 0824d6fc bellard
402 c45886db bellard
int cpu_inw(CPUState *env, int addr)
403 0824d6fc bellard
{
404 fd872598 bellard
    int val;
405 fd872598 bellard
    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
406 fd872598 bellard
#ifdef DEBUG_IOPORT
407 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
408 fd872598 bellard
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
409 fd872598 bellard
#endif
410 fd872598 bellard
    return val;
411 0824d6fc bellard
}
412 0824d6fc bellard
413 c45886db bellard
int cpu_inl(CPUState *env, int addr)
414 0824d6fc bellard
{
415 fd872598 bellard
    int val;
416 fd872598 bellard
    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
417 fd872598 bellard
#ifdef DEBUG_IOPORT
418 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
419 fd872598 bellard
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
420 fd872598 bellard
#endif
421 fd872598 bellard
    return val;
422 0824d6fc bellard
}
423 0824d6fc bellard
424 0824d6fc bellard
/***********************************************************/
425 0824d6fc bellard
void hw_error(const char *fmt, ...)
426 0824d6fc bellard
{
427 0824d6fc bellard
    va_list ap;
428 0824d6fc bellard
429 0824d6fc bellard
    va_start(ap, fmt);
430 0824d6fc bellard
    fprintf(stderr, "qemu: hardware error: ");
431 0824d6fc bellard
    vfprintf(stderr, fmt, ap);
432 0824d6fc bellard
    fprintf(stderr, "\n");
433 0824d6fc bellard
#ifdef TARGET_I386
434 7fe48483 bellard
    cpu_dump_state(global_env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
435 c45886db bellard
#else
436 7fe48483 bellard
    cpu_dump_state(global_env, stderr, fprintf, 0);
437 0824d6fc bellard
#endif
438 0824d6fc bellard
    va_end(ap);
439 0824d6fc bellard
    abort();
440 0824d6fc bellard
}
441 0824d6fc bellard
442 8a7ddc38 bellard
/***********************************************************/
443 63066f4f bellard
/* keyboard/mouse */
444 63066f4f bellard
445 63066f4f bellard
static QEMUPutKBDEvent *qemu_put_kbd_event;
446 63066f4f bellard
static void *qemu_put_kbd_event_opaque;
447 63066f4f bellard
static QEMUPutMouseEvent *qemu_put_mouse_event;
448 63066f4f bellard
static void *qemu_put_mouse_event_opaque;
449 63066f4f bellard
450 63066f4f bellard
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
451 63066f4f bellard
{
452 63066f4f bellard
    qemu_put_kbd_event_opaque = opaque;
453 63066f4f bellard
    qemu_put_kbd_event = func;
454 63066f4f bellard
}
455 63066f4f bellard
456 63066f4f bellard
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
457 63066f4f bellard
{
458 63066f4f bellard
    qemu_put_mouse_event_opaque = opaque;
459 63066f4f bellard
    qemu_put_mouse_event = func;
460 63066f4f bellard
}
461 63066f4f bellard
462 63066f4f bellard
void kbd_put_keycode(int keycode)
463 63066f4f bellard
{
464 63066f4f bellard
    if (qemu_put_kbd_event) {
465 63066f4f bellard
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
466 63066f4f bellard
    }
467 63066f4f bellard
}
468 63066f4f bellard
469 63066f4f bellard
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
470 63066f4f bellard
{
471 63066f4f bellard
    if (qemu_put_mouse_event) {
472 63066f4f bellard
        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
473 63066f4f bellard
                             dx, dy, dz, buttons_state);
474 63066f4f bellard
    }
475 63066f4f bellard
}
476 63066f4f bellard
477 63066f4f bellard
/***********************************************************/
478 8a7ddc38 bellard
/* timers */
479 8a7ddc38 bellard
480 34865134 bellard
#if defined(__powerpc__)
481 34865134 bellard
482 34865134 bellard
static inline uint32_t get_tbl(void) 
483 0824d6fc bellard
{
484 34865134 bellard
    uint32_t tbl;
485 34865134 bellard
    asm volatile("mftb %0" : "=r" (tbl));
486 34865134 bellard
    return tbl;
487 0824d6fc bellard
}
488 0824d6fc bellard
489 34865134 bellard
static inline uint32_t get_tbu(void) 
490 34865134 bellard
{
491 34865134 bellard
        uint32_t tbl;
492 34865134 bellard
        asm volatile("mftbu %0" : "=r" (tbl));
493 34865134 bellard
        return tbl;
494 34865134 bellard
}
495 34865134 bellard
496 34865134 bellard
int64_t cpu_get_real_ticks(void)
497 34865134 bellard
{
498 34865134 bellard
    uint32_t l, h, h1;
499 34865134 bellard
    /* NOTE: we test if wrapping has occurred */
500 34865134 bellard
    do {
501 34865134 bellard
        h = get_tbu();
502 34865134 bellard
        l = get_tbl();
503 34865134 bellard
        h1 = get_tbu();
504 34865134 bellard
    } while (h != h1);
505 34865134 bellard
    return ((int64_t)h << 32) | l;
506 34865134 bellard
}
507 34865134 bellard
508 34865134 bellard
#elif defined(__i386__)
509 34865134 bellard
510 34865134 bellard
int64_t cpu_get_real_ticks(void)
511 0824d6fc bellard
{
512 0824d6fc bellard
    int64_t val;
513 e463b581 bellard
    asm volatile ("rdtsc" : "=A" (val));
514 0824d6fc bellard
    return val;
515 0824d6fc bellard
}
516 0824d6fc bellard
517 1115dde7 bellard
#elif defined(__x86_64__)
518 1115dde7 bellard
519 1115dde7 bellard
int64_t cpu_get_real_ticks(void)
520 1115dde7 bellard
{
521 1115dde7 bellard
    uint32_t low,high;
522 1115dde7 bellard
    int64_t val;
523 1115dde7 bellard
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
524 1115dde7 bellard
    val = high;
525 1115dde7 bellard
    val <<= 32;
526 1115dde7 bellard
    val |= low;
527 1115dde7 bellard
    return val;
528 1115dde7 bellard
}
529 1115dde7 bellard
530 b8076a74 bellard
#elif defined(__ia64)
531 b8076a74 bellard
532 b8076a74 bellard
int64_t cpu_get_real_ticks(void)
533 b8076a74 bellard
{
534 b8076a74 bellard
        int64_t val;
535 b8076a74 bellard
        asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
536 b8076a74 bellard
        return val;
537 b8076a74 bellard
}
538 b8076a74 bellard
539 90cb9493 bellard
#elif defined(__s390__)
540 90cb9493 bellard
541 90cb9493 bellard
int64_t cpu_get_real_ticks(void)
542 90cb9493 bellard
{
543 90cb9493 bellard
    int64_t val;
544 90cb9493 bellard
    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
545 90cb9493 bellard
    return val;
546 90cb9493 bellard
}
547 90cb9493 bellard
548 34865134 bellard
#else
549 34865134 bellard
#error unsupported CPU
550 34865134 bellard
#endif
551 34865134 bellard
552 34865134 bellard
static int64_t cpu_ticks_offset;
553 8a7ddc38 bellard
static int cpu_ticks_enabled;
554 34865134 bellard
555 8a7ddc38 bellard
static inline int64_t cpu_get_ticks(void)
556 34865134 bellard
{
557 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
558 8a7ddc38 bellard
        return cpu_ticks_offset;
559 8a7ddc38 bellard
    } else {
560 8a7ddc38 bellard
        return cpu_get_real_ticks() + cpu_ticks_offset;
561 8a7ddc38 bellard
    }
562 34865134 bellard
}
563 34865134 bellard
564 34865134 bellard
/* enable cpu_get_ticks() */
565 34865134 bellard
void cpu_enable_ticks(void)
566 34865134 bellard
{
567 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
568 8a7ddc38 bellard
        cpu_ticks_offset -= cpu_get_real_ticks();
569 8a7ddc38 bellard
        cpu_ticks_enabled = 1;
570 8a7ddc38 bellard
    }
571 34865134 bellard
}
572 34865134 bellard
573 34865134 bellard
/* disable cpu_get_ticks() : the clock is stopped. You must not call
574 34865134 bellard
   cpu_get_ticks() after that.  */
575 34865134 bellard
void cpu_disable_ticks(void)
576 34865134 bellard
{
577 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
578 8a7ddc38 bellard
        cpu_ticks_offset = cpu_get_ticks();
579 8a7ddc38 bellard
        cpu_ticks_enabled = 0;
580 8a7ddc38 bellard
    }
581 34865134 bellard
}
582 34865134 bellard
583 67b915a5 bellard
static int64_t get_clock(void)
584 34865134 bellard
{
585 67b915a5 bellard
#ifdef _WIN32
586 67b915a5 bellard
    struct _timeb tb;
587 67b915a5 bellard
    _ftime(&tb);
588 67b915a5 bellard
    return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
589 67b915a5 bellard
#else
590 34865134 bellard
    struct timeval tv;
591 34865134 bellard
    gettimeofday(&tv, NULL);
592 34865134 bellard
    return tv.tv_sec * 1000000LL + tv.tv_usec;
593 67b915a5 bellard
#endif
594 34865134 bellard
}
595 34865134 bellard
596 0824d6fc bellard
void cpu_calibrate_ticks(void)
597 0824d6fc bellard
{
598 0824d6fc bellard
    int64_t usec, ticks;
599 0824d6fc bellard
600 0824d6fc bellard
    usec = get_clock();
601 8a7ddc38 bellard
    ticks = cpu_get_real_ticks();
602 67b915a5 bellard
#ifdef _WIN32
603 67b915a5 bellard
    Sleep(50);
604 67b915a5 bellard
#else
605 0824d6fc bellard
    usleep(50 * 1000);
606 67b915a5 bellard
#endif
607 0824d6fc bellard
    usec = get_clock() - usec;
608 8a7ddc38 bellard
    ticks = cpu_get_real_ticks() - ticks;
609 0824d6fc bellard
    ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
610 0824d6fc bellard
}
611 0824d6fc bellard
612 87858c89 bellard
/* compute with 96 bit intermediate result: (a*b)/c */
613 80cabfad bellard
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
614 87858c89 bellard
{
615 87858c89 bellard
    union {
616 87858c89 bellard
        uint64_t ll;
617 87858c89 bellard
        struct {
618 87858c89 bellard
#ifdef WORDS_BIGENDIAN
619 87858c89 bellard
            uint32_t high, low;
620 87858c89 bellard
#else
621 87858c89 bellard
            uint32_t low, high;
622 87858c89 bellard
#endif            
623 87858c89 bellard
        } l;
624 87858c89 bellard
    } u, res;
625 87858c89 bellard
    uint64_t rl, rh;
626 87858c89 bellard
627 87858c89 bellard
    u.ll = a;
628 87858c89 bellard
    rl = (uint64_t)u.l.low * (uint64_t)b;
629 87858c89 bellard
    rh = (uint64_t)u.l.high * (uint64_t)b;
630 87858c89 bellard
    rh += (rl >> 32);
631 87858c89 bellard
    res.l.high = rh / c;
632 87858c89 bellard
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
633 87858c89 bellard
    return res.ll;
634 87858c89 bellard
}
635 87858c89 bellard
636 8a7ddc38 bellard
#define QEMU_TIMER_REALTIME 0
637 8a7ddc38 bellard
#define QEMU_TIMER_VIRTUAL  1
638 8a7ddc38 bellard
639 8a7ddc38 bellard
struct QEMUClock {
640 8a7ddc38 bellard
    int type;
641 8a7ddc38 bellard
    /* XXX: add frequency */
642 8a7ddc38 bellard
};
643 8a7ddc38 bellard
644 8a7ddc38 bellard
struct QEMUTimer {
645 8a7ddc38 bellard
    QEMUClock *clock;
646 8a7ddc38 bellard
    int64_t expire_time;
647 8a7ddc38 bellard
    QEMUTimerCB *cb;
648 8a7ddc38 bellard
    void *opaque;
649 8a7ddc38 bellard
    struct QEMUTimer *next;
650 8a7ddc38 bellard
};
651 8a7ddc38 bellard
652 8a7ddc38 bellard
QEMUClock *rt_clock;
653 8a7ddc38 bellard
QEMUClock *vm_clock;
654 8a7ddc38 bellard
655 8a7ddc38 bellard
static QEMUTimer *active_timers[2];
656 40c3bac3 bellard
#ifdef _WIN32
657 40c3bac3 bellard
static MMRESULT timerID;
658 40c3bac3 bellard
#else
659 8a7ddc38 bellard
/* frequency of the times() clock tick */
660 8a7ddc38 bellard
static int timer_freq;
661 67b915a5 bellard
#endif
662 8a7ddc38 bellard
663 8a7ddc38 bellard
QEMUClock *qemu_new_clock(int type)
664 8a7ddc38 bellard
{
665 8a7ddc38 bellard
    QEMUClock *clock;
666 8a7ddc38 bellard
    clock = qemu_mallocz(sizeof(QEMUClock));
667 8a7ddc38 bellard
    if (!clock)
668 8a7ddc38 bellard
        return NULL;
669 8a7ddc38 bellard
    clock->type = type;
670 8a7ddc38 bellard
    return clock;
671 8a7ddc38 bellard
}
672 8a7ddc38 bellard
673 8a7ddc38 bellard
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
674 8a7ddc38 bellard
{
675 8a7ddc38 bellard
    QEMUTimer *ts;
676 8a7ddc38 bellard
677 8a7ddc38 bellard
    ts = qemu_mallocz(sizeof(QEMUTimer));
678 8a7ddc38 bellard
    ts->clock = clock;
679 8a7ddc38 bellard
    ts->cb = cb;
680 8a7ddc38 bellard
    ts->opaque = opaque;
681 8a7ddc38 bellard
    return ts;
682 8a7ddc38 bellard
}
683 8a7ddc38 bellard
684 8a7ddc38 bellard
void qemu_free_timer(QEMUTimer *ts)
685 8a7ddc38 bellard
{
686 8a7ddc38 bellard
    qemu_free(ts);
687 8a7ddc38 bellard
}
688 8a7ddc38 bellard
689 8a7ddc38 bellard
/* stop a timer, but do not dealloc it */
690 8a7ddc38 bellard
void qemu_del_timer(QEMUTimer *ts)
691 8a7ddc38 bellard
{
692 8a7ddc38 bellard
    QEMUTimer **pt, *t;
693 8a7ddc38 bellard
694 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
695 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
696 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
697 8a7ddc38 bellard
    for(;;) {
698 8a7ddc38 bellard
        t = *pt;
699 8a7ddc38 bellard
        if (!t)
700 8a7ddc38 bellard
            break;
701 8a7ddc38 bellard
        if (t == ts) {
702 8a7ddc38 bellard
            *pt = t->next;
703 8a7ddc38 bellard
            break;
704 8a7ddc38 bellard
        }
705 8a7ddc38 bellard
        pt = &t->next;
706 8a7ddc38 bellard
    }
707 8a7ddc38 bellard
}
708 8a7ddc38 bellard
709 8a7ddc38 bellard
/* modify the current timer so that it will be fired when current_time
710 8a7ddc38 bellard
   >= expire_time. The corresponding callback will be called. */
711 8a7ddc38 bellard
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
712 8a7ddc38 bellard
{
713 8a7ddc38 bellard
    QEMUTimer **pt, *t;
714 8a7ddc38 bellard
715 8a7ddc38 bellard
    qemu_del_timer(ts);
716 8a7ddc38 bellard
717 8a7ddc38 bellard
    /* add the timer in the sorted list */
718 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
719 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
720 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
721 8a7ddc38 bellard
    for(;;) {
722 8a7ddc38 bellard
        t = *pt;
723 8a7ddc38 bellard
        if (!t)
724 8a7ddc38 bellard
            break;
725 8a7ddc38 bellard
        if (t->expire_time > expire_time) 
726 8a7ddc38 bellard
            break;
727 8a7ddc38 bellard
        pt = &t->next;
728 8a7ddc38 bellard
    }
729 8a7ddc38 bellard
    ts->expire_time = expire_time;
730 8a7ddc38 bellard
    ts->next = *pt;
731 8a7ddc38 bellard
    *pt = ts;
732 8a7ddc38 bellard
}
733 8a7ddc38 bellard
734 8a7ddc38 bellard
int qemu_timer_pending(QEMUTimer *ts)
735 8a7ddc38 bellard
{
736 8a7ddc38 bellard
    QEMUTimer *t;
737 8a7ddc38 bellard
    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
738 8a7ddc38 bellard
        if (t == ts)
739 8a7ddc38 bellard
            return 1;
740 8a7ddc38 bellard
    }
741 8a7ddc38 bellard
    return 0;
742 8a7ddc38 bellard
}
743 8a7ddc38 bellard
744 8a7ddc38 bellard
static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
745 8a7ddc38 bellard
{
746 8a7ddc38 bellard
    if (!timer_head)
747 8a7ddc38 bellard
        return 0;
748 8a7ddc38 bellard
    return (timer_head->expire_time <= current_time);
749 8a7ddc38 bellard
}
750 8a7ddc38 bellard
751 8a7ddc38 bellard
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
752 8a7ddc38 bellard
{
753 8a7ddc38 bellard
    QEMUTimer *ts;
754 8a7ddc38 bellard
    
755 8a7ddc38 bellard
    for(;;) {
756 8a7ddc38 bellard
        ts = *ptimer_head;
757 e95c8d51 bellard
        if (!ts || ts->expire_time > current_time)
758 8a7ddc38 bellard
            break;
759 8a7ddc38 bellard
        /* remove timer from the list before calling the callback */
760 8a7ddc38 bellard
        *ptimer_head = ts->next;
761 8a7ddc38 bellard
        ts->next = NULL;
762 8a7ddc38 bellard
        
763 8a7ddc38 bellard
        /* run the callback (the timer list can be modified) */
764 8a7ddc38 bellard
        ts->cb(ts->opaque);
765 8a7ddc38 bellard
    }
766 8a7ddc38 bellard
}
767 8a7ddc38 bellard
768 8a7ddc38 bellard
int64_t qemu_get_clock(QEMUClock *clock)
769 8a7ddc38 bellard
{
770 8a7ddc38 bellard
    switch(clock->type) {
771 8a7ddc38 bellard
    case QEMU_TIMER_REALTIME:
772 67b915a5 bellard
#ifdef _WIN32
773 67b915a5 bellard
        return GetTickCount();
774 67b915a5 bellard
#else
775 7d3505c5 bellard
        {
776 7d3505c5 bellard
            struct tms tp;
777 7d3505c5 bellard
778 7d3505c5 bellard
            /* Note that using gettimeofday() is not a good solution
779 7d3505c5 bellard
               for timers because its value change when the date is
780 7d3505c5 bellard
               modified. */
781 7d3505c5 bellard
            if (timer_freq == 100) {
782 7d3505c5 bellard
                return times(&tp) * 10;
783 7d3505c5 bellard
            } else {
784 7d3505c5 bellard
                return ((int64_t)times(&tp) * 1000) / timer_freq;
785 7d3505c5 bellard
            }
786 8a7ddc38 bellard
        }
787 67b915a5 bellard
#endif
788 8a7ddc38 bellard
    default:
789 8a7ddc38 bellard
    case QEMU_TIMER_VIRTUAL:
790 8a7ddc38 bellard
        return cpu_get_ticks();
791 8a7ddc38 bellard
    }
792 8a7ddc38 bellard
}
793 8a7ddc38 bellard
794 8a7ddc38 bellard
/* save a timer */
795 8a7ddc38 bellard
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
796 8a7ddc38 bellard
{
797 8a7ddc38 bellard
    uint64_t expire_time;
798 8a7ddc38 bellard
799 8a7ddc38 bellard
    if (qemu_timer_pending(ts)) {
800 8a7ddc38 bellard
        expire_time = ts->expire_time;
801 8a7ddc38 bellard
    } else {
802 8a7ddc38 bellard
        expire_time = -1;
803 8a7ddc38 bellard
    }
804 8a7ddc38 bellard
    qemu_put_be64(f, expire_time);
805 8a7ddc38 bellard
}
806 8a7ddc38 bellard
807 8a7ddc38 bellard
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
808 8a7ddc38 bellard
{
809 8a7ddc38 bellard
    uint64_t expire_time;
810 8a7ddc38 bellard
811 8a7ddc38 bellard
    expire_time = qemu_get_be64(f);
812 8a7ddc38 bellard
    if (expire_time != -1) {
813 8a7ddc38 bellard
        qemu_mod_timer(ts, expire_time);
814 8a7ddc38 bellard
    } else {
815 8a7ddc38 bellard
        qemu_del_timer(ts);
816 8a7ddc38 bellard
    }
817 8a7ddc38 bellard
}
818 8a7ddc38 bellard
819 8a7ddc38 bellard
static void timer_save(QEMUFile *f, void *opaque)
820 8a7ddc38 bellard
{
821 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
822 8a7ddc38 bellard
        hw_error("cannot save state if virtual timers are running");
823 8a7ddc38 bellard
    }
824 8a7ddc38 bellard
    qemu_put_be64s(f, &cpu_ticks_offset);
825 8a7ddc38 bellard
    qemu_put_be64s(f, &ticks_per_sec);
826 8a7ddc38 bellard
}
827 8a7ddc38 bellard
828 8a7ddc38 bellard
static int timer_load(QEMUFile *f, void *opaque, int version_id)
829 8a7ddc38 bellard
{
830 8a7ddc38 bellard
    if (version_id != 1)
831 8a7ddc38 bellard
        return -EINVAL;
832 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
833 8a7ddc38 bellard
        return -EINVAL;
834 8a7ddc38 bellard
    }
835 8a7ddc38 bellard
    qemu_get_be64s(f, &cpu_ticks_offset);
836 8a7ddc38 bellard
    qemu_get_be64s(f, &ticks_per_sec);
837 8a7ddc38 bellard
    return 0;
838 8a7ddc38 bellard
}
839 8a7ddc38 bellard
840 67b915a5 bellard
#ifdef _WIN32
841 67b915a5 bellard
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, 
842 67b915a5 bellard
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
843 67b915a5 bellard
#else
844 8a7ddc38 bellard
static void host_alarm_handler(int host_signum)
845 67b915a5 bellard
#endif
846 8a7ddc38 bellard
{
847 02ba45c5 bellard
#if 0
848 02ba45c5 bellard
#define DISP_FREQ 1000
849 02ba45c5 bellard
    {
850 02ba45c5 bellard
        static int64_t delta_min = INT64_MAX;
851 02ba45c5 bellard
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
852 02ba45c5 bellard
        static int count;
853 02ba45c5 bellard
        ti = qemu_get_clock(vm_clock);
854 02ba45c5 bellard
        if (last_clock != 0) {
855 02ba45c5 bellard
            delta = ti - last_clock;
856 02ba45c5 bellard
            if (delta < delta_min)
857 02ba45c5 bellard
                delta_min = delta;
858 02ba45c5 bellard
            if (delta > delta_max)
859 02ba45c5 bellard
                delta_max = delta;
860 02ba45c5 bellard
            delta_cum += delta;
861 02ba45c5 bellard
            if (++count == DISP_FREQ) {
862 02ba45c5 bellard
                printf("timer: min=%lld us max=%lld us avg=%lld us avg_freq=%0.3f Hz\n",
863 02ba45c5 bellard
                       muldiv64(delta_min, 1000000, ticks_per_sec),
864 02ba45c5 bellard
                       muldiv64(delta_max, 1000000, ticks_per_sec),
865 02ba45c5 bellard
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
866 02ba45c5 bellard
                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
867 02ba45c5 bellard
                count = 0;
868 02ba45c5 bellard
                delta_min = INT64_MAX;
869 02ba45c5 bellard
                delta_max = 0;
870 02ba45c5 bellard
                delta_cum = 0;
871 02ba45c5 bellard
            }
872 02ba45c5 bellard
        }
873 02ba45c5 bellard
        last_clock = ti;
874 02ba45c5 bellard
    }
875 02ba45c5 bellard
#endif
876 8a7ddc38 bellard
    if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
877 8a7ddc38 bellard
                           qemu_get_clock(vm_clock)) ||
878 8a7ddc38 bellard
        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
879 8a7ddc38 bellard
                           qemu_get_clock(rt_clock))) {
880 8a7ddc38 bellard
        /* stop the cpu because a timer occured */
881 8a7ddc38 bellard
        cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
882 a332e112 bellard
#ifdef USE_KQEMU
883 8289336c bellard
        if (global_env->kqemu_enabled) {
884 8289336c bellard
            kqemu_cpu_interrupt(global_env);
885 8289336c bellard
        }
886 a332e112 bellard
#endif
887 8a7ddc38 bellard
    }
888 8a7ddc38 bellard
}
889 8a7ddc38 bellard
890 fd872598 bellard
#ifndef _WIN32
891 fd872598 bellard
892 829309c7 bellard
#if defined(__linux__)
893 829309c7 bellard
894 fd872598 bellard
#define RTC_FREQ 1024
895 fd872598 bellard
896 fd872598 bellard
static int rtc_fd;
897 829309c7 bellard
898 fd872598 bellard
static int start_rtc_timer(void)
899 fd872598 bellard
{
900 fd872598 bellard
    rtc_fd = open("/dev/rtc", O_RDONLY);
901 fd872598 bellard
    if (rtc_fd < 0)
902 fd872598 bellard
        return -1;
903 fd872598 bellard
    if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
904 fd872598 bellard
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
905 fd872598 bellard
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
906 fd872598 bellard
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
907 fd872598 bellard
        goto fail;
908 fd872598 bellard
    }
909 fd872598 bellard
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
910 fd872598 bellard
    fail:
911 fd872598 bellard
        close(rtc_fd);
912 fd872598 bellard
        return -1;
913 fd872598 bellard
    }
914 fd872598 bellard
    pit_min_timer_count = PIT_FREQ / RTC_FREQ;
915 fd872598 bellard
    return 0;
916 fd872598 bellard
}
917 fd872598 bellard
918 829309c7 bellard
#else
919 829309c7 bellard
920 829309c7 bellard
static int start_rtc_timer(void)
921 829309c7 bellard
{
922 829309c7 bellard
    return -1;
923 829309c7 bellard
}
924 829309c7 bellard
925 829309c7 bellard
#endif /* !defined(__linux__) */
926 829309c7 bellard
927 829309c7 bellard
#endif /* !defined(_WIN32) */
928 fd872598 bellard
929 8a7ddc38 bellard
static void init_timers(void)
930 8a7ddc38 bellard
{
931 8a7ddc38 bellard
    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
932 8a7ddc38 bellard
    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
933 8a7ddc38 bellard
934 67b915a5 bellard
#ifdef _WIN32
935 67b915a5 bellard
    {
936 67b915a5 bellard
        int count=0;
937 1d14ffa9 bellard
        timerID = timeSetEvent(1,     // interval (ms)
938 40c3bac3 bellard
                               0,     // resolution
939 40c3bac3 bellard
                               host_alarm_handler, // function
940 40c3bac3 bellard
                               (DWORD)&count,  // user parameter
941 40c3bac3 bellard
                               TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
942 67b915a5 bellard
         if( !timerID ) {
943 67b915a5 bellard
            perror("failed timer alarm");
944 67b915a5 bellard
            exit(1);
945 67b915a5 bellard
         }
946 67b915a5 bellard
    }
947 67b915a5 bellard
    pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
948 67b915a5 bellard
#else
949 67b915a5 bellard
    {
950 67b915a5 bellard
        struct sigaction act;
951 67b915a5 bellard
        struct itimerval itv;
952 67b915a5 bellard
        
953 67b915a5 bellard
        /* get times() syscall frequency */
954 67b915a5 bellard
        timer_freq = sysconf(_SC_CLK_TCK);
955 67b915a5 bellard
        
956 67b915a5 bellard
        /* timer signal */
957 67b915a5 bellard
        sigfillset(&act.sa_mask);
958 a09db21f bellard
       act.sa_flags = 0;
959 8a7ddc38 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
960 67b915a5 bellard
        act.sa_flags |= SA_ONSTACK;
961 67b915a5 bellard
#endif
962 67b915a5 bellard
        act.sa_handler = host_alarm_handler;
963 67b915a5 bellard
        sigaction(SIGALRM, &act, NULL);
964 fd872598 bellard
965 67b915a5 bellard
        itv.it_interval.tv_sec = 0;
966 d79284e0 bellard
        itv.it_interval.tv_usec = 999; /* for i386 kernel 2.6 to get 1 ms */
967 67b915a5 bellard
        itv.it_value.tv_sec = 0;
968 67b915a5 bellard
        itv.it_value.tv_usec = 10 * 1000;
969 67b915a5 bellard
        setitimer(ITIMER_REAL, &itv, NULL);
970 67b915a5 bellard
        /* we probe the tick duration of the kernel to inform the user if
971 67b915a5 bellard
           the emulated kernel requested a too high timer frequency */
972 67b915a5 bellard
        getitimer(ITIMER_REAL, &itv);
973 fd872598 bellard
974 83fb7adf bellard
#if defined(__linux__)
975 fd872598 bellard
        if (itv.it_interval.tv_usec > 1000) {
976 fd872598 bellard
            /* try to use /dev/rtc to have a faster timer */
977 fd872598 bellard
            if (start_rtc_timer() < 0)
978 fd872598 bellard
                goto use_itimer;
979 fd872598 bellard
            /* disable itimer */
980 fd872598 bellard
            itv.it_interval.tv_sec = 0;
981 fd872598 bellard
            itv.it_interval.tv_usec = 0;
982 fd872598 bellard
            itv.it_value.tv_sec = 0;
983 fd872598 bellard
            itv.it_value.tv_usec = 0;
984 fd872598 bellard
            setitimer(ITIMER_REAL, &itv, NULL);
985 fd872598 bellard
986 fd872598 bellard
            /* use the RTC */
987 a1968d71 bellard
            sigaction(SIGIO, &act, NULL);
988 fd872598 bellard
            fcntl(rtc_fd, F_SETFL, O_ASYNC);
989 fd872598 bellard
            fcntl(rtc_fd, F_SETOWN, getpid());
990 83fb7adf bellard
        } else 
991 83fb7adf bellard
#endif /* defined(__linux__) */
992 83fb7adf bellard
        {
993 fd872598 bellard
        use_itimer:
994 fd872598 bellard
            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
995 fd872598 bellard
                                   PIT_FREQ) / 1000000;
996 fd872598 bellard
        }
997 67b915a5 bellard
    }
998 8a7ddc38 bellard
#endif
999 8a7ddc38 bellard
}
1000 8a7ddc38 bellard
1001 40c3bac3 bellard
void quit_timers(void)
1002 40c3bac3 bellard
{
1003 40c3bac3 bellard
#ifdef _WIN32
1004 40c3bac3 bellard
    timeKillEvent(timerID);
1005 40c3bac3 bellard
#endif
1006 40c3bac3 bellard
}
1007 40c3bac3 bellard
1008 c4b1fcc0 bellard
/***********************************************************/
1009 82c643ff bellard
/* character device */
1010 313aa567 bellard
1011 82c643ff bellard
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
1012 82c643ff bellard
{
1013 82c643ff bellard
    return s->chr_write(s, buf, len);
1014 82c643ff bellard
}
1015 67b915a5 bellard
1016 82c643ff bellard
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1017 67b915a5 bellard
{
1018 82c643ff bellard
    char buf[4096];
1019 82c643ff bellard
    va_list ap;
1020 82c643ff bellard
    va_start(ap, fmt);
1021 82c643ff bellard
    vsnprintf(buf, sizeof(buf), fmt, ap);
1022 82c643ff bellard
    qemu_chr_write(s, buf, strlen(buf));
1023 82c643ff bellard
    va_end(ap);
1024 67b915a5 bellard
}
1025 67b915a5 bellard
1026 5905b2e5 bellard
void qemu_chr_send_event(CharDriverState *s, int event)
1027 5905b2e5 bellard
{
1028 5905b2e5 bellard
    if (s->chr_send_event)
1029 5905b2e5 bellard
        s->chr_send_event(s, event);
1030 5905b2e5 bellard
}
1031 5905b2e5 bellard
1032 82c643ff bellard
void qemu_chr_add_read_handler(CharDriverState *s, 
1033 82c643ff bellard
                               IOCanRWHandler *fd_can_read, 
1034 82c643ff bellard
                               IOReadHandler *fd_read, void *opaque)
1035 82c643ff bellard
{
1036 82c643ff bellard
    s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
1037 82c643ff bellard
}
1038 82c643ff bellard
             
1039 82c643ff bellard
void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
1040 82c643ff bellard
{
1041 82c643ff bellard
    s->chr_event = chr_event;
1042 82c643ff bellard
}
1043 67b915a5 bellard
1044 82c643ff bellard
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1045 313aa567 bellard
{
1046 82c643ff bellard
    return len;
1047 82c643ff bellard
}
1048 82c643ff bellard
1049 82c643ff bellard
static void null_chr_add_read_handler(CharDriverState *chr, 
1050 82c643ff bellard
                                    IOCanRWHandler *fd_can_read, 
1051 82c643ff bellard
                                    IOReadHandler *fd_read, void *opaque)
1052 82c643ff bellard
{
1053 82c643ff bellard
}
1054 82c643ff bellard
1055 82c643ff bellard
CharDriverState *qemu_chr_open_null(void)
1056 82c643ff bellard
{
1057 82c643ff bellard
    CharDriverState *chr;
1058 82c643ff bellard
1059 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1060 82c643ff bellard
    if (!chr)
1061 82c643ff bellard
        return NULL;
1062 82c643ff bellard
    chr->chr_write = null_chr_write;
1063 82c643ff bellard
    chr->chr_add_read_handler = null_chr_add_read_handler;
1064 82c643ff bellard
    return chr;
1065 82c643ff bellard
}
1066 82c643ff bellard
1067 82c643ff bellard
#ifndef _WIN32
1068 82c643ff bellard
1069 82c643ff bellard
typedef struct {
1070 82c643ff bellard
    int fd_in, fd_out;
1071 82c643ff bellard
    /* for nographic stdio only */
1072 82c643ff bellard
    IOCanRWHandler *fd_can_read; 
1073 82c643ff bellard
    IOReadHandler *fd_read;
1074 82c643ff bellard
    void *fd_opaque;
1075 82c643ff bellard
} FDCharDriver;
1076 82c643ff bellard
1077 82c643ff bellard
#define STDIO_MAX_CLIENTS 2
1078 82c643ff bellard
1079 82c643ff bellard
static int stdio_nb_clients;
1080 82c643ff bellard
static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
1081 82c643ff bellard
1082 1d96905d bellard
static int unix_write(int fd, const uint8_t *buf, int len1)
1083 1d96905d bellard
{
1084 1d96905d bellard
    int ret, len;
1085 1d96905d bellard
1086 1d96905d bellard
    len = len1;
1087 1d96905d bellard
    while (len > 0) {
1088 1d96905d bellard
        ret = write(fd, buf, len);
1089 1d96905d bellard
        if (ret < 0) {
1090 1d96905d bellard
            if (errno != EINTR && errno != EAGAIN)
1091 1d96905d bellard
                return -1;
1092 1d96905d bellard
        } else if (ret == 0) {
1093 1d96905d bellard
            break;
1094 1d96905d bellard
        } else {
1095 1d96905d bellard
            buf += ret;
1096 1d96905d bellard
            len -= ret;
1097 1d96905d bellard
        }
1098 1d96905d bellard
    }
1099 1d96905d bellard
    return len1 - len;
1100 1d96905d bellard
}
1101 1d96905d bellard
1102 82c643ff bellard
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1103 82c643ff bellard
{
1104 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1105 1d96905d bellard
    return unix_write(s->fd_out, buf, len);
1106 82c643ff bellard
}
1107 82c643ff bellard
1108 82c643ff bellard
static void fd_chr_add_read_handler(CharDriverState *chr, 
1109 82c643ff bellard
                                    IOCanRWHandler *fd_can_read, 
1110 82c643ff bellard
                                    IOReadHandler *fd_read, void *opaque)
1111 82c643ff bellard
{
1112 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1113 82c643ff bellard
1114 82c643ff bellard
    if (nographic && s->fd_in == 0) {
1115 82c643ff bellard
        s->fd_can_read = fd_can_read;
1116 82c643ff bellard
        s->fd_read = fd_read;
1117 82c643ff bellard
        s->fd_opaque = opaque;
1118 80cabfad bellard
    } else {
1119 82c643ff bellard
        qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
1120 82c643ff bellard
    }
1121 82c643ff bellard
}
1122 82c643ff bellard
1123 82c643ff bellard
/* open a character device to a unix fd */
1124 82c643ff bellard
CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
1125 82c643ff bellard
{
1126 82c643ff bellard
    CharDriverState *chr;
1127 82c643ff bellard
    FDCharDriver *s;
1128 82c643ff bellard
1129 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1130 82c643ff bellard
    if (!chr)
1131 82c643ff bellard
        return NULL;
1132 82c643ff bellard
    s = qemu_mallocz(sizeof(FDCharDriver));
1133 82c643ff bellard
    if (!s) {
1134 82c643ff bellard
        free(chr);
1135 82c643ff bellard
        return NULL;
1136 82c643ff bellard
    }
1137 82c643ff bellard
    s->fd_in = fd_in;
1138 82c643ff bellard
    s->fd_out = fd_out;
1139 82c643ff bellard
    chr->opaque = s;
1140 82c643ff bellard
    chr->chr_write = fd_chr_write;
1141 82c643ff bellard
    chr->chr_add_read_handler = fd_chr_add_read_handler;
1142 82c643ff bellard
    return chr;
1143 82c643ff bellard
}
1144 82c643ff bellard
1145 82c643ff bellard
/* for STDIO, we handle the case where several clients use it
1146 82c643ff bellard
   (nographic mode) */
1147 82c643ff bellard
1148 82c643ff bellard
#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
1149 82c643ff bellard
1150 aa0bc6b6 bellard
#define TERM_FIFO_MAX_SIZE 1
1151 aa0bc6b6 bellard
1152 82c643ff bellard
static int term_got_escape, client_index;
1153 aa0bc6b6 bellard
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
1154 aa0bc6b6 bellard
int term_fifo_size;
1155 82c643ff bellard
1156 82c643ff bellard
void term_print_help(void)
1157 82c643ff bellard
{
1158 82c643ff bellard
    printf("\n"
1159 82c643ff bellard
           "C-a h    print this help\n"
1160 82c643ff bellard
           "C-a x    exit emulator\n"
1161 82c643ff bellard
           "C-a s    save disk data back to file (if -snapshot)\n"
1162 82c643ff bellard
           "C-a b    send break (magic sysrq)\n"
1163 82c643ff bellard
           "C-a c    switch between console and monitor\n"
1164 82c643ff bellard
           "C-a C-a  send C-a\n"
1165 82c643ff bellard
           );
1166 82c643ff bellard
}
1167 82c643ff bellard
1168 82c643ff bellard
/* called when a char is received */
1169 82c643ff bellard
static void stdio_received_byte(int ch)
1170 82c643ff bellard
{
1171 82c643ff bellard
    if (term_got_escape) {
1172 82c643ff bellard
        term_got_escape = 0;
1173 82c643ff bellard
        switch(ch) {
1174 82c643ff bellard
        case 'h':
1175 82c643ff bellard
            term_print_help();
1176 82c643ff bellard
            break;
1177 82c643ff bellard
        case 'x':
1178 82c643ff bellard
            exit(0);
1179 82c643ff bellard
            break;
1180 82c643ff bellard
        case 's': 
1181 82c643ff bellard
            {
1182 82c643ff bellard
                int i;
1183 82c643ff bellard
                for (i = 0; i < MAX_DISKS; i++) {
1184 82c643ff bellard
                    if (bs_table[i])
1185 82c643ff bellard
                        bdrv_commit(bs_table[i]);
1186 82c643ff bellard
                }
1187 82c643ff bellard
            }
1188 82c643ff bellard
            break;
1189 82c643ff bellard
        case 'b':
1190 82c643ff bellard
            if (client_index < stdio_nb_clients) {
1191 82c643ff bellard
                CharDriverState *chr;
1192 82c643ff bellard
                FDCharDriver *s;
1193 82c643ff bellard
1194 82c643ff bellard
                chr = stdio_clients[client_index];
1195 82c643ff bellard
                s = chr->opaque;
1196 82c643ff bellard
                chr->chr_event(s->fd_opaque, CHR_EVENT_BREAK);
1197 82c643ff bellard
            }
1198 82c643ff bellard
            break;
1199 82c643ff bellard
        case 'c':
1200 82c643ff bellard
            client_index++;
1201 82c643ff bellard
            if (client_index >= stdio_nb_clients)
1202 82c643ff bellard
                client_index = 0;
1203 82c643ff bellard
            if (client_index == 0) {
1204 82c643ff bellard
                /* send a new line in the monitor to get the prompt */
1205 82c643ff bellard
                ch = '\r';
1206 82c643ff bellard
                goto send_char;
1207 82c643ff bellard
            }
1208 82c643ff bellard
            break;
1209 82c643ff bellard
        case TERM_ESCAPE:
1210 82c643ff bellard
            goto send_char;
1211 82c643ff bellard
        }
1212 82c643ff bellard
    } else if (ch == TERM_ESCAPE) {
1213 82c643ff bellard
        term_got_escape = 1;
1214 82c643ff bellard
    } else {
1215 82c643ff bellard
    send_char:
1216 82c643ff bellard
        if (client_index < stdio_nb_clients) {
1217 82c643ff bellard
            uint8_t buf[1];
1218 82c643ff bellard
            CharDriverState *chr;
1219 82c643ff bellard
            FDCharDriver *s;
1220 82c643ff bellard
            
1221 82c643ff bellard
            chr = stdio_clients[client_index];
1222 82c643ff bellard
            s = chr->opaque;
1223 aa0bc6b6 bellard
            if (s->fd_can_read(s->fd_opaque) > 0) {
1224 aa0bc6b6 bellard
                buf[0] = ch;
1225 82c643ff bellard
                s->fd_read(s->fd_opaque, buf, 1);
1226 aa0bc6b6 bellard
            } else if (term_fifo_size == 0) {
1227 aa0bc6b6 bellard
                term_fifo[term_fifo_size++] = ch;
1228 aa0bc6b6 bellard
            }
1229 c4b1fcc0 bellard
        }
1230 330d0414 bellard
    }
1231 330d0414 bellard
}
1232 330d0414 bellard
1233 82c643ff bellard
static int stdio_can_read(void *opaque)
1234 82c643ff bellard
{
1235 aa0bc6b6 bellard
    CharDriverState *chr;
1236 aa0bc6b6 bellard
    FDCharDriver *s;
1237 aa0bc6b6 bellard
1238 aa0bc6b6 bellard
    if (client_index < stdio_nb_clients) {
1239 aa0bc6b6 bellard
        chr = stdio_clients[client_index];
1240 aa0bc6b6 bellard
        s = chr->opaque;
1241 aa0bc6b6 bellard
        /* try to flush the queue if needed */
1242 aa0bc6b6 bellard
        if (term_fifo_size != 0 && s->fd_can_read(s->fd_opaque) > 0) {
1243 aa0bc6b6 bellard
            s->fd_read(s->fd_opaque, term_fifo, 1);
1244 aa0bc6b6 bellard
            term_fifo_size = 0;
1245 aa0bc6b6 bellard
        }
1246 aa0bc6b6 bellard
        /* see if we can absorb more chars */
1247 aa0bc6b6 bellard
        if (term_fifo_size == 0)
1248 aa0bc6b6 bellard
            return 1;
1249 aa0bc6b6 bellard
        else
1250 aa0bc6b6 bellard
            return 0;
1251 aa0bc6b6 bellard
    } else {
1252 aa0bc6b6 bellard
        return 1;
1253 aa0bc6b6 bellard
    }
1254 82c643ff bellard
}
1255 82c643ff bellard
1256 82c643ff bellard
static void stdio_read(void *opaque, const uint8_t *buf, int size)
1257 82c643ff bellard
{
1258 82c643ff bellard
    int i;
1259 82c643ff bellard
    for(i = 0; i < size; i++)
1260 82c643ff bellard
        stdio_received_byte(buf[i]);
1261 82c643ff bellard
}
1262 82c643ff bellard
1263 8d11df9e bellard
/* init terminal so that we can grab keys */
1264 8d11df9e bellard
static struct termios oldtty;
1265 8d11df9e bellard
static int old_fd0_flags;
1266 8d11df9e bellard
1267 8d11df9e bellard
static void term_exit(void)
1268 8d11df9e bellard
{
1269 8d11df9e bellard
    tcsetattr (0, TCSANOW, &oldtty);
1270 8d11df9e bellard
    fcntl(0, F_SETFL, old_fd0_flags);
1271 8d11df9e bellard
}
1272 8d11df9e bellard
1273 8d11df9e bellard
static void term_init(void)
1274 8d11df9e bellard
{
1275 8d11df9e bellard
    struct termios tty;
1276 8d11df9e bellard
1277 8d11df9e bellard
    tcgetattr (0, &tty);
1278 8d11df9e bellard
    oldtty = tty;
1279 8d11df9e bellard
    old_fd0_flags = fcntl(0, F_GETFL);
1280 8d11df9e bellard
1281 8d11df9e bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1282 8d11df9e bellard
                          |INLCR|IGNCR|ICRNL|IXON);
1283 8d11df9e bellard
    tty.c_oflag |= OPOST;
1284 8d11df9e bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1285 8d11df9e bellard
    /* if graphical mode, we allow Ctrl-C handling */
1286 8d11df9e bellard
    if (nographic)
1287 8d11df9e bellard
        tty.c_lflag &= ~ISIG;
1288 8d11df9e bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
1289 8d11df9e bellard
    tty.c_cflag |= CS8;
1290 8d11df9e bellard
    tty.c_cc[VMIN] = 1;
1291 8d11df9e bellard
    tty.c_cc[VTIME] = 0;
1292 8d11df9e bellard
    
1293 8d11df9e bellard
    tcsetattr (0, TCSANOW, &tty);
1294 8d11df9e bellard
1295 8d11df9e bellard
    atexit(term_exit);
1296 8d11df9e bellard
1297 8d11df9e bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
1298 8d11df9e bellard
}
1299 8d11df9e bellard
1300 82c643ff bellard
CharDriverState *qemu_chr_open_stdio(void)
1301 82c643ff bellard
{
1302 82c643ff bellard
    CharDriverState *chr;
1303 82c643ff bellard
1304 82c643ff bellard
    if (nographic) {
1305 82c643ff bellard
        if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
1306 82c643ff bellard
            return NULL;
1307 82c643ff bellard
        chr = qemu_chr_open_fd(0, 1);
1308 82c643ff bellard
        if (stdio_nb_clients == 0)
1309 82c643ff bellard
            qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);
1310 82c643ff bellard
        client_index = stdio_nb_clients;
1311 82c643ff bellard
    } else {
1312 82c643ff bellard
        if (stdio_nb_clients != 0)
1313 82c643ff bellard
            return NULL;
1314 82c643ff bellard
        chr = qemu_chr_open_fd(0, 1);
1315 82c643ff bellard
    }
1316 82c643ff bellard
    stdio_clients[stdio_nb_clients++] = chr;
1317 8d11df9e bellard
    if (stdio_nb_clients == 1) {
1318 8d11df9e bellard
        /* set the terminal in raw mode */
1319 8d11df9e bellard
        term_init();
1320 8d11df9e bellard
    }
1321 82c643ff bellard
    return chr;
1322 82c643ff bellard
}
1323 82c643ff bellard
1324 82c643ff bellard
#if defined(__linux__)
1325 82c643ff bellard
CharDriverState *qemu_chr_open_pty(void)
1326 82c643ff bellard
{
1327 82c643ff bellard
    char slave_name[1024];
1328 82c643ff bellard
    int master_fd, slave_fd;
1329 82c643ff bellard
    
1330 82c643ff bellard
    /* Not satisfying */
1331 82c643ff bellard
    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
1332 82c643ff bellard
        return NULL;
1333 82c643ff bellard
    }
1334 82c643ff bellard
    fprintf(stderr, "char device redirected to %s\n", slave_name);
1335 82c643ff bellard
    return qemu_chr_open_fd(master_fd, master_fd);
1336 82c643ff bellard
}
1337 82c643ff bellard
#else
1338 82c643ff bellard
CharDriverState *qemu_chr_open_pty(void)
1339 82c643ff bellard
{
1340 82c643ff bellard
    return NULL;
1341 82c643ff bellard
}
1342 67b915a5 bellard
#endif
1343 67b915a5 bellard
1344 82c643ff bellard
#endif /* !defined(_WIN32) */
1345 82c643ff bellard
1346 82c643ff bellard
CharDriverState *qemu_chr_open(const char *filename)
1347 82c643ff bellard
{
1348 82c643ff bellard
    if (!strcmp(filename, "vc")) {
1349 82c643ff bellard
        return text_console_init(&display_state);
1350 82c643ff bellard
    } else if (!strcmp(filename, "null")) {
1351 82c643ff bellard
        return qemu_chr_open_null();
1352 82c643ff bellard
    } else 
1353 82c643ff bellard
#ifndef _WIN32
1354 82c643ff bellard
    if (!strcmp(filename, "pty")) {
1355 82c643ff bellard
        return qemu_chr_open_pty();
1356 82c643ff bellard
    } else if (!strcmp(filename, "stdio")) {
1357 82c643ff bellard
        return qemu_chr_open_stdio();
1358 82c643ff bellard
    } else 
1359 82c643ff bellard
#endif
1360 82c643ff bellard
    {
1361 82c643ff bellard
        return NULL;
1362 82c643ff bellard
    }
1363 82c643ff bellard
}
1364 82c643ff bellard
1365 80cabfad bellard
/***********************************************************/
1366 c20709aa bellard
/* Linux network device redirectors */
1367 330d0414 bellard
1368 c20709aa bellard
void hex_dump(FILE *f, const uint8_t *buf, int size)
1369 c20709aa bellard
{
1370 c20709aa bellard
    int len, i, j, c;
1371 c20709aa bellard
1372 c20709aa bellard
    for(i=0;i<size;i+=16) {
1373 c20709aa bellard
        len = size - i;
1374 c20709aa bellard
        if (len > 16)
1375 c20709aa bellard
            len = 16;
1376 c20709aa bellard
        fprintf(f, "%08x ", i);
1377 c20709aa bellard
        for(j=0;j<16;j++) {
1378 c20709aa bellard
            if (j < len)
1379 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
1380 c20709aa bellard
            else
1381 c20709aa bellard
                fprintf(f, "   ");
1382 c20709aa bellard
        }
1383 c20709aa bellard
        fprintf(f, " ");
1384 c20709aa bellard
        for(j=0;j<len;j++) {
1385 c20709aa bellard
            c = buf[i+j];
1386 c20709aa bellard
            if (c < ' ' || c > '~')
1387 c20709aa bellard
                c = '.';
1388 c20709aa bellard
            fprintf(f, "%c", c);
1389 c20709aa bellard
        }
1390 c20709aa bellard
        fprintf(f, "\n");
1391 c20709aa bellard
    }
1392 c20709aa bellard
}
1393 c20709aa bellard
1394 c20709aa bellard
void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1395 c20709aa bellard
{
1396 c20709aa bellard
    nd->send_packet(nd, buf, size);
1397 c20709aa bellard
}
1398 67b915a5 bellard
1399 c20709aa bellard
void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, 
1400 c20709aa bellard
                          IOReadHandler *fd_read, void *opaque)
1401 67b915a5 bellard
{
1402 c20709aa bellard
    nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
1403 c20709aa bellard
}
1404 c20709aa bellard
1405 c20709aa bellard
/* dummy network adapter */
1406 c20709aa bellard
1407 c20709aa bellard
static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1408 c20709aa bellard
{
1409 c20709aa bellard
}
1410 c20709aa bellard
1411 c20709aa bellard
static void dummy_add_read_packet(NetDriverState *nd, 
1412 c20709aa bellard
                                  IOCanRWHandler *fd_can_read, 
1413 c20709aa bellard
                                  IOReadHandler *fd_read, void *opaque)
1414 c20709aa bellard
{
1415 c20709aa bellard
}
1416 c20709aa bellard
1417 c20709aa bellard
static int net_dummy_init(NetDriverState *nd)
1418 c20709aa bellard
{
1419 c20709aa bellard
    nd->send_packet = dummy_send_packet;
1420 c20709aa bellard
    nd->add_read_packet = dummy_add_read_packet;
1421 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
1422 67b915a5 bellard
    return 0;
1423 67b915a5 bellard
}
1424 67b915a5 bellard
1425 c20709aa bellard
#if defined(CONFIG_SLIRP)
1426 c20709aa bellard
1427 c20709aa bellard
/* slirp network adapter */
1428 c20709aa bellard
1429 c20709aa bellard
static void *slirp_fd_opaque;
1430 c20709aa bellard
static IOCanRWHandler *slirp_fd_can_read;
1431 c20709aa bellard
static IOReadHandler *slirp_fd_read;
1432 c20709aa bellard
static int slirp_inited;
1433 c20709aa bellard
1434 c20709aa bellard
int slirp_can_output(void)
1435 c20709aa bellard
{
1436 c20709aa bellard
    return slirp_fd_can_read(slirp_fd_opaque);
1437 c20709aa bellard
}
1438 c20709aa bellard
1439 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
1440 67b915a5 bellard
{
1441 c20709aa bellard
#if 0
1442 c20709aa bellard
    printf("output:\n");
1443 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
1444 c20709aa bellard
#endif
1445 c20709aa bellard
    slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
1446 67b915a5 bellard
}
1447 67b915a5 bellard
1448 c20709aa bellard
static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1449 c20709aa bellard
{
1450 c20709aa bellard
#if 0
1451 c20709aa bellard
    printf("input:\n");
1452 c20709aa bellard
    hex_dump(stdout, buf, size);
1453 c20709aa bellard
#endif
1454 c20709aa bellard
    slirp_input(buf, size);
1455 c20709aa bellard
}
1456 c20709aa bellard
1457 c20709aa bellard
static void slirp_add_read_packet(NetDriverState *nd, 
1458 c20709aa bellard
                                  IOCanRWHandler *fd_can_read, 
1459 c20709aa bellard
                                  IOReadHandler *fd_read, void *opaque)
1460 c20709aa bellard
{
1461 c20709aa bellard
    slirp_fd_opaque = opaque;
1462 c20709aa bellard
    slirp_fd_can_read = fd_can_read;
1463 c20709aa bellard
    slirp_fd_read = fd_read;
1464 c20709aa bellard
}
1465 c20709aa bellard
1466 c20709aa bellard
static int net_slirp_init(NetDriverState *nd)
1467 c20709aa bellard
{
1468 c20709aa bellard
    if (!slirp_inited) {
1469 c20709aa bellard
        slirp_inited = 1;
1470 c20709aa bellard
        slirp_init();
1471 c20709aa bellard
    }
1472 c20709aa bellard
    nd->send_packet = slirp_send_packet;
1473 c20709aa bellard
    nd->add_read_packet = slirp_add_read_packet;
1474 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
1475 c20709aa bellard
    return 0;
1476 c20709aa bellard
}
1477 c20709aa bellard
1478 9bf05444 bellard
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
1479 9bf05444 bellard
{
1480 9bf05444 bellard
    const char *p, *p1;
1481 9bf05444 bellard
    int len;
1482 9bf05444 bellard
    p = *pp;
1483 9bf05444 bellard
    p1 = strchr(p, sep);
1484 9bf05444 bellard
    if (!p1)
1485 9bf05444 bellard
        return -1;
1486 9bf05444 bellard
    len = p1 - p;
1487 9bf05444 bellard
    p1++;
1488 9bf05444 bellard
    if (buf_size > 0) {
1489 9bf05444 bellard
        if (len > buf_size - 1)
1490 9bf05444 bellard
            len = buf_size - 1;
1491 9bf05444 bellard
        memcpy(buf, p, len);
1492 9bf05444 bellard
        buf[len] = '\0';
1493 9bf05444 bellard
    }
1494 9bf05444 bellard
    *pp = p1;
1495 9bf05444 bellard
    return 0;
1496 9bf05444 bellard
}
1497 9bf05444 bellard
1498 9bf05444 bellard
static void net_slirp_redir(const char *redir_str)
1499 9bf05444 bellard
{
1500 9bf05444 bellard
    int is_udp;
1501 9bf05444 bellard
    char buf[256], *r;
1502 9bf05444 bellard
    const char *p;
1503 9bf05444 bellard
    struct in_addr guest_addr;
1504 9bf05444 bellard
    int host_port, guest_port;
1505 9bf05444 bellard
    
1506 9bf05444 bellard
    if (!slirp_inited) {
1507 9bf05444 bellard
        slirp_inited = 1;
1508 9bf05444 bellard
        slirp_init();
1509 9bf05444 bellard
    }
1510 9bf05444 bellard
1511 9bf05444 bellard
    p = redir_str;
1512 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1513 9bf05444 bellard
        goto fail;
1514 9bf05444 bellard
    if (!strcmp(buf, "tcp")) {
1515 9bf05444 bellard
        is_udp = 0;
1516 9bf05444 bellard
    } else if (!strcmp(buf, "udp")) {
1517 9bf05444 bellard
        is_udp = 1;
1518 9bf05444 bellard
    } else {
1519 9bf05444 bellard
        goto fail;
1520 9bf05444 bellard
    }
1521 9bf05444 bellard
1522 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1523 9bf05444 bellard
        goto fail;
1524 9bf05444 bellard
    host_port = strtol(buf, &r, 0);
1525 9bf05444 bellard
    if (r == buf)
1526 9bf05444 bellard
        goto fail;
1527 9bf05444 bellard
1528 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1529 9bf05444 bellard
        goto fail;
1530 9bf05444 bellard
    if (buf[0] == '\0') {
1531 9bf05444 bellard
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
1532 9bf05444 bellard
    }
1533 9bf05444 bellard
    if (!inet_aton(buf, &guest_addr))
1534 9bf05444 bellard
        goto fail;
1535 9bf05444 bellard
    
1536 9bf05444 bellard
    guest_port = strtol(p, &r, 0);
1537 9bf05444 bellard
    if (r == p)
1538 9bf05444 bellard
        goto fail;
1539 9bf05444 bellard
    
1540 9bf05444 bellard
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
1541 9bf05444 bellard
        fprintf(stderr, "qemu: could not set up redirection\n");
1542 9bf05444 bellard
        exit(1);
1543 9bf05444 bellard
    }
1544 9bf05444 bellard
    return;
1545 9bf05444 bellard
 fail:
1546 9bf05444 bellard
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
1547 9bf05444 bellard
    exit(1);
1548 9bf05444 bellard
}
1549 9d728e8c bellard
    
1550 c94c8d64 bellard
#ifndef _WIN32
1551 c94c8d64 bellard
1552 9d728e8c bellard
char smb_dir[1024];
1553 9d728e8c bellard
1554 9d728e8c bellard
static void smb_exit(void)
1555 9d728e8c bellard
{
1556 9d728e8c bellard
    DIR *d;
1557 9d728e8c bellard
    struct dirent *de;
1558 9d728e8c bellard
    char filename[1024];
1559 9d728e8c bellard
1560 9d728e8c bellard
    /* erase all the files in the directory */
1561 9d728e8c bellard
    d = opendir(smb_dir);
1562 9d728e8c bellard
    for(;;) {
1563 9d728e8c bellard
        de = readdir(d);
1564 9d728e8c bellard
        if (!de)
1565 9d728e8c bellard
            break;
1566 9d728e8c bellard
        if (strcmp(de->d_name, ".") != 0 &&
1567 9d728e8c bellard
            strcmp(de->d_name, "..") != 0) {
1568 9d728e8c bellard
            snprintf(filename, sizeof(filename), "%s/%s", 
1569 9d728e8c bellard
                     smb_dir, de->d_name);
1570 9d728e8c bellard
            unlink(filename);
1571 9d728e8c bellard
        }
1572 9d728e8c bellard
    }
1573 03ffbb69 bellard
    closedir(d);
1574 9d728e8c bellard
    rmdir(smb_dir);
1575 9d728e8c bellard
}
1576 9d728e8c bellard
1577 9d728e8c bellard
/* automatic user mode samba server configuration */
1578 9d728e8c bellard
void net_slirp_smb(const char *exported_dir)
1579 9d728e8c bellard
{
1580 9d728e8c bellard
    char smb_conf[1024];
1581 9d728e8c bellard
    char smb_cmdline[1024];
1582 9d728e8c bellard
    FILE *f;
1583 9d728e8c bellard
1584 9d728e8c bellard
    if (!slirp_inited) {
1585 9d728e8c bellard
        slirp_inited = 1;
1586 9d728e8c bellard
        slirp_init();
1587 9d728e8c bellard
    }
1588 9d728e8c bellard
1589 9d728e8c bellard
    /* XXX: better tmp dir construction */
1590 9d728e8c bellard
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
1591 9d728e8c bellard
    if (mkdir(smb_dir, 0700) < 0) {
1592 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
1593 9d728e8c bellard
        exit(1);
1594 9d728e8c bellard
    }
1595 9d728e8c bellard
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
1596 9d728e8c bellard
    
1597 9d728e8c bellard
    f = fopen(smb_conf, "w");
1598 9d728e8c bellard
    if (!f) {
1599 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
1600 9d728e8c bellard
        exit(1);
1601 9d728e8c bellard
    }
1602 9d728e8c bellard
    fprintf(f, 
1603 9d728e8c bellard
            "[global]\n"
1604 157777ef bellard
            "private dir=%s\n"
1605 157777ef bellard
            "smb ports=0\n"
1606 157777ef bellard
            "socket address=127.0.0.1\n"
1607 9d728e8c bellard
            "pid directory=%s\n"
1608 9d728e8c bellard
            "lock directory=%s\n"
1609 9d728e8c bellard
            "log file=%s/log.smbd\n"
1610 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
1611 03ffbb69 bellard
            "security = share\n"
1612 9d728e8c bellard
            "[qemu]\n"
1613 9d728e8c bellard
            "path=%s\n"
1614 9d728e8c bellard
            "read only=no\n"
1615 9d728e8c bellard
            "guest ok=yes\n",
1616 9d728e8c bellard
            smb_dir,
1617 157777ef bellard
            smb_dir,
1618 9d728e8c bellard
            smb_dir,
1619 9d728e8c bellard
            smb_dir,
1620 9d728e8c bellard
            smb_dir,
1621 9d728e8c bellard
            exported_dir
1622 9d728e8c bellard
            );
1623 9d728e8c bellard
    fclose(f);
1624 9d728e8c bellard
    atexit(smb_exit);
1625 9d728e8c bellard
1626 9d728e8c bellard
    snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
1627 9d728e8c bellard
             smb_conf);
1628 9d728e8c bellard
    
1629 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
1630 9d728e8c bellard
}
1631 9bf05444 bellard
1632 c94c8d64 bellard
#endif /* !defined(_WIN32) */
1633 c94c8d64 bellard
1634 c20709aa bellard
#endif /* CONFIG_SLIRP */
1635 c20709aa bellard
1636 c20709aa bellard
#if !defined(_WIN32)
1637 7d3505c5 bellard
#ifdef _BSD
1638 7d3505c5 bellard
static int tun_open(char *ifname, int ifname_size)
1639 7d3505c5 bellard
{
1640 7d3505c5 bellard
    int fd;
1641 7d3505c5 bellard
    char *dev;
1642 7d3505c5 bellard
    struct stat s;
1643 67b915a5 bellard
1644 7d3505c5 bellard
    fd = open("/dev/tap", O_RDWR);
1645 7d3505c5 bellard
    if (fd < 0) {
1646 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
1647 7d3505c5 bellard
        return -1;
1648 7d3505c5 bellard
    }
1649 7d3505c5 bellard
1650 7d3505c5 bellard
    fstat(fd, &s);
1651 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
1652 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
1653 7d3505c5 bellard
1654 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1655 7d3505c5 bellard
    return fd;
1656 7d3505c5 bellard
}
1657 7d3505c5 bellard
#else
1658 c4b1fcc0 bellard
static int tun_open(char *ifname, int ifname_size)
1659 330d0414 bellard
{
1660 80cabfad bellard
    struct ifreq ifr;
1661 c4b1fcc0 bellard
    int fd, ret;
1662 80cabfad bellard
    
1663 80cabfad bellard
    fd = open("/dev/net/tun", O_RDWR);
1664 80cabfad bellard
    if (fd < 0) {
1665 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1666 80cabfad bellard
        return -1;
1667 330d0414 bellard
    }
1668 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
1669 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1670 80cabfad bellard
    pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1671 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1672 80cabfad bellard
    if (ret != 0) {
1673 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1674 80cabfad bellard
        close(fd);
1675 80cabfad bellard
        return -1;
1676 80cabfad bellard
    }
1677 80cabfad bellard
    printf("Connected to host network interface: %s\n", ifr.ifr_name);
1678 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
1679 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1680 c4b1fcc0 bellard
    return fd;
1681 c4b1fcc0 bellard
}
1682 7d3505c5 bellard
#endif
1683 330d0414 bellard
1684 c20709aa bellard
static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1685 c20709aa bellard
{
1686 c20709aa bellard
    write(nd->fd, buf, size);
1687 c20709aa bellard
}
1688 c20709aa bellard
1689 c20709aa bellard
static void tun_add_read_packet(NetDriverState *nd, 
1690 c20709aa bellard
                                IOCanRWHandler *fd_can_read, 
1691 c20709aa bellard
                                IOReadHandler *fd_read, void *opaque)
1692 c4b1fcc0 bellard
{
1693 c20709aa bellard
    qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
1694 c20709aa bellard
}
1695 c20709aa bellard
1696 c20709aa bellard
static int net_tun_init(NetDriverState *nd)
1697 c20709aa bellard
{
1698 c20709aa bellard
    int pid, status;
1699 c20709aa bellard
    char *args[3];
1700 c4b1fcc0 bellard
    char **parg;
1701 c4b1fcc0 bellard
1702 c20709aa bellard
    nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
1703 c20709aa bellard
    if (nd->fd < 0)
1704 c20709aa bellard
        return -1;
1705 c4b1fcc0 bellard
1706 c20709aa bellard
    /* try to launch network init script */
1707 c20709aa bellard
    pid = fork();
1708 c20709aa bellard
    if (pid >= 0) {
1709 c20709aa bellard
        if (pid == 0) {
1710 c20709aa bellard
            parg = args;
1711 c20709aa bellard
            *parg++ = network_script;
1712 c20709aa bellard
            *parg++ = nd->ifname;
1713 c20709aa bellard
            *parg++ = NULL;
1714 c20709aa bellard
            execv(network_script, args);
1715 c20709aa bellard
            exit(1);
1716 c20709aa bellard
        }
1717 c20709aa bellard
        while (waitpid(pid, &status, 0) != pid);
1718 c20709aa bellard
        if (!WIFEXITED(status) ||
1719 c20709aa bellard
            WEXITSTATUS(status) != 0) {
1720 c20709aa bellard
            fprintf(stderr, "%s: could not launch network script\n",
1721 c20709aa bellard
                    network_script);
1722 80cabfad bellard
        }
1723 330d0414 bellard
    }
1724 c20709aa bellard
    nd->send_packet = tun_send_packet;
1725 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1726 80cabfad bellard
    return 0;
1727 330d0414 bellard
}
1728 330d0414 bellard
1729 c20709aa bellard
static int net_fd_init(NetDriverState *nd, int fd)
1730 330d0414 bellard
{
1731 c20709aa bellard
    nd->fd = fd;
1732 c20709aa bellard
    nd->send_packet = tun_send_packet;
1733 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1734 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
1735 c20709aa bellard
    return 0;
1736 80cabfad bellard
}
1737 330d0414 bellard
1738 c20709aa bellard
#endif /* !_WIN32 */
1739 67b915a5 bellard
1740 330d0414 bellard
/***********************************************************/
1741 a594cfbf bellard
/* USB devices */
1742 a594cfbf bellard
1743 a594cfbf bellard
static int usb_device_add(const char *devname)
1744 a594cfbf bellard
{
1745 a594cfbf bellard
    const char *p;
1746 a594cfbf bellard
    USBDevice *dev;
1747 a594cfbf bellard
    int i;
1748 a594cfbf bellard
1749 a594cfbf bellard
    if (!vm_usb_hub)
1750 a594cfbf bellard
        return -1;
1751 a594cfbf bellard
    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
1752 a594cfbf bellard
        if (!vm_usb_ports[i]->dev)
1753 a594cfbf bellard
            break;
1754 a594cfbf bellard
    }
1755 a594cfbf bellard
    if (i == MAX_VM_USB_PORTS)
1756 a594cfbf bellard
        return -1;
1757 a594cfbf bellard
1758 a594cfbf bellard
    if (strstart(devname, "host:", &p)) {
1759 a594cfbf bellard
        dev = usb_host_device_open(p);
1760 a594cfbf bellard
        if (!dev)
1761 a594cfbf bellard
            return -1;
1762 a594cfbf bellard
    } else if (!strcmp(devname, "mouse")) {
1763 a594cfbf bellard
        dev = usb_mouse_init();
1764 a594cfbf bellard
        if (!dev)
1765 a594cfbf bellard
            return -1;
1766 a594cfbf bellard
    } else {
1767 a594cfbf bellard
        return -1;
1768 a594cfbf bellard
    }
1769 a594cfbf bellard
    usb_attach(vm_usb_ports[i], dev);
1770 a594cfbf bellard
    return 0;
1771 a594cfbf bellard
}
1772 a594cfbf bellard
1773 a594cfbf bellard
static int usb_device_del(const char *devname)
1774 a594cfbf bellard
{
1775 a594cfbf bellard
    USBDevice *dev;
1776 a594cfbf bellard
    int bus_num, addr, i;
1777 a594cfbf bellard
    const char *p;
1778 a594cfbf bellard
1779 a594cfbf bellard
    if (!vm_usb_hub)
1780 a594cfbf bellard
        return -1;
1781 a594cfbf bellard
1782 a594cfbf bellard
    p = strchr(devname, '.');
1783 a594cfbf bellard
    if (!p) 
1784 a594cfbf bellard
        return -1;
1785 a594cfbf bellard
    bus_num = strtoul(devname, NULL, 0);
1786 a594cfbf bellard
    addr = strtoul(p + 1, NULL, 0);
1787 a594cfbf bellard
    if (bus_num != 0)
1788 a594cfbf bellard
        return -1;
1789 a594cfbf bellard
    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
1790 a594cfbf bellard
        dev = vm_usb_ports[i]->dev;
1791 a594cfbf bellard
        if (dev && dev->addr == addr)
1792 a594cfbf bellard
            break;
1793 a594cfbf bellard
    }
1794 a594cfbf bellard
    if (i == MAX_VM_USB_PORTS)
1795 a594cfbf bellard
        return -1;
1796 a594cfbf bellard
    usb_attach(vm_usb_ports[i], NULL);
1797 a594cfbf bellard
    return 0;
1798 a594cfbf bellard
}
1799 a594cfbf bellard
1800 a594cfbf bellard
void do_usb_add(const char *devname)
1801 a594cfbf bellard
{
1802 a594cfbf bellard
    int ret;
1803 a594cfbf bellard
    ret = usb_device_add(devname);
1804 a594cfbf bellard
    if (ret < 0) 
1805 a594cfbf bellard
        term_printf("Could not add USB device '%s'\n", devname);
1806 a594cfbf bellard
}
1807 a594cfbf bellard
1808 a594cfbf bellard
void do_usb_del(const char *devname)
1809 a594cfbf bellard
{
1810 a594cfbf bellard
    int ret;
1811 a594cfbf bellard
    ret = usb_device_del(devname);
1812 a594cfbf bellard
    if (ret < 0) 
1813 a594cfbf bellard
        term_printf("Could not remove USB device '%s'\n", devname);
1814 a594cfbf bellard
}
1815 a594cfbf bellard
1816 a594cfbf bellard
void usb_info(void)
1817 a594cfbf bellard
{
1818 a594cfbf bellard
    USBDevice *dev;
1819 a594cfbf bellard
    int i;
1820 a594cfbf bellard
    const char *speed_str;
1821 a594cfbf bellard
1822 a594cfbf bellard
    if (!vm_usb_hub) {
1823 a594cfbf bellard
        term_printf("USB support not enabled\n");
1824 a594cfbf bellard
        return;
1825 a594cfbf bellard
    }
1826 a594cfbf bellard
1827 a594cfbf bellard
    for(i = 0; i < MAX_VM_USB_PORTS; i++) {
1828 a594cfbf bellard
        dev = vm_usb_ports[i]->dev;
1829 a594cfbf bellard
        if (dev) {
1830 a594cfbf bellard
            term_printf("Hub port %d:\n", i);
1831 a594cfbf bellard
            switch(dev->speed) {
1832 a594cfbf bellard
            case USB_SPEED_LOW: 
1833 a594cfbf bellard
                speed_str = "1.5"; 
1834 a594cfbf bellard
                break;
1835 a594cfbf bellard
            case USB_SPEED_FULL: 
1836 a594cfbf bellard
                speed_str = "12"; 
1837 a594cfbf bellard
                break;
1838 a594cfbf bellard
            case USB_SPEED_HIGH: 
1839 a594cfbf bellard
                speed_str = "480"; 
1840 a594cfbf bellard
                break;
1841 a594cfbf bellard
            default:
1842 a594cfbf bellard
                speed_str = "?"; 
1843 a594cfbf bellard
                break;
1844 a594cfbf bellard
            }
1845 a594cfbf bellard
            term_printf("  Device %d.%d, speed %s Mb/s\n", 
1846 a594cfbf bellard
                        0, dev->addr, speed_str);
1847 a594cfbf bellard
        }
1848 a594cfbf bellard
    }
1849 a594cfbf bellard
}
1850 a594cfbf bellard
1851 a594cfbf bellard
/***********************************************************/
1852 f7cce898 bellard
/* pid file */
1853 f7cce898 bellard
1854 f7cce898 bellard
static char *pid_filename;
1855 f7cce898 bellard
1856 f7cce898 bellard
/* Remove PID file. Called on normal exit */
1857 f7cce898 bellard
1858 f7cce898 bellard
static void remove_pidfile(void) 
1859 f7cce898 bellard
{
1860 f7cce898 bellard
    unlink (pid_filename);
1861 f7cce898 bellard
}
1862 f7cce898 bellard
1863 f7cce898 bellard
static void create_pidfile(const char *filename)
1864 f7cce898 bellard
{
1865 f7cce898 bellard
    struct stat pidstat;
1866 f7cce898 bellard
    FILE *f;
1867 f7cce898 bellard
1868 f7cce898 bellard
    /* Try to write our PID to the named file */
1869 f7cce898 bellard
    if (stat(filename, &pidstat) < 0) {
1870 f7cce898 bellard
        if (errno == ENOENT) {
1871 f7cce898 bellard
            if ((f = fopen (filename, "w")) == NULL) {
1872 f7cce898 bellard
                perror("Opening pidfile");
1873 f7cce898 bellard
                exit(1);
1874 f7cce898 bellard
            }
1875 f7cce898 bellard
            fprintf(f, "%d\n", getpid());
1876 f7cce898 bellard
            fclose(f);
1877 f7cce898 bellard
            pid_filename = qemu_strdup(filename);
1878 f7cce898 bellard
            if (!pid_filename) {
1879 f7cce898 bellard
                fprintf(stderr, "Could not save PID filename");
1880 f7cce898 bellard
                exit(1);
1881 f7cce898 bellard
            }
1882 f7cce898 bellard
            atexit(remove_pidfile);
1883 f7cce898 bellard
        }
1884 f7cce898 bellard
    } else {
1885 f7cce898 bellard
        fprintf(stderr, "%s already exists. Remove it and try again.\n", 
1886 f7cce898 bellard
                filename);
1887 f7cce898 bellard
        exit(1);
1888 f7cce898 bellard
    }
1889 f7cce898 bellard
}
1890 f7cce898 bellard
1891 f7cce898 bellard
/***********************************************************/
1892 313aa567 bellard
/* dumb display */
1893 313aa567 bellard
1894 313aa567 bellard
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
1895 313aa567 bellard
{
1896 313aa567 bellard
}
1897 313aa567 bellard
1898 313aa567 bellard
static void dumb_resize(DisplayState *ds, int w, int h)
1899 313aa567 bellard
{
1900 313aa567 bellard
}
1901 313aa567 bellard
1902 313aa567 bellard
static void dumb_refresh(DisplayState *ds)
1903 313aa567 bellard
{
1904 313aa567 bellard
    vga_update_display();
1905 313aa567 bellard
}
1906 313aa567 bellard
1907 313aa567 bellard
void dumb_display_init(DisplayState *ds)
1908 313aa567 bellard
{
1909 313aa567 bellard
    ds->data = NULL;
1910 313aa567 bellard
    ds->linesize = 0;
1911 313aa567 bellard
    ds->depth = 0;
1912 313aa567 bellard
    ds->dpy_update = dumb_update;
1913 313aa567 bellard
    ds->dpy_resize = dumb_resize;
1914 313aa567 bellard
    ds->dpy_refresh = dumb_refresh;
1915 313aa567 bellard
}
1916 313aa567 bellard
1917 3a51dee6 bellard
#if !defined(CONFIG_SOFTMMU)
1918 313aa567 bellard
/***********************************************************/
1919 0824d6fc bellard
/* cpu signal handler */
1920 0824d6fc bellard
static void host_segv_handler(int host_signum, siginfo_t *info, 
1921 0824d6fc bellard
                              void *puc)
1922 0824d6fc bellard
{
1923 0824d6fc bellard
    if (cpu_signal_handler(host_signum, info, puc))
1924 0824d6fc bellard
        return;
1925 8d11df9e bellard
    if (stdio_nb_clients > 0)
1926 8d11df9e bellard
        term_exit();
1927 0824d6fc bellard
    abort();
1928 0824d6fc bellard
}
1929 3a51dee6 bellard
#endif
1930 0824d6fc bellard
1931 8a7ddc38 bellard
/***********************************************************/
1932 8a7ddc38 bellard
/* I/O handling */
1933 0824d6fc bellard
1934 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
1935 c4b1fcc0 bellard
1936 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
1937 c4b1fcc0 bellard
    int fd;
1938 c4b1fcc0 bellard
    IOCanRWHandler *fd_can_read;
1939 c4b1fcc0 bellard
    IOReadHandler *fd_read;
1940 c4b1fcc0 bellard
    void *opaque;
1941 c4b1fcc0 bellard
    /* temporary data */
1942 c4b1fcc0 bellard
    struct pollfd *ufd;
1943 c4b1fcc0 bellard
    int max_size;
1944 8a7ddc38 bellard
    struct IOHandlerRecord *next;
1945 c4b1fcc0 bellard
} IOHandlerRecord;
1946 c4b1fcc0 bellard
1947 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
1948 c4b1fcc0 bellard
1949 8a7ddc38 bellard
int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
1950 8a7ddc38 bellard
                             IOReadHandler *fd_read, void *opaque)
1951 c4b1fcc0 bellard
{
1952 c4b1fcc0 bellard
    IOHandlerRecord *ioh;
1953 c4b1fcc0 bellard
1954 8a7ddc38 bellard
    ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1955 8a7ddc38 bellard
    if (!ioh)
1956 c4b1fcc0 bellard
        return -1;
1957 c4b1fcc0 bellard
    ioh->fd = fd;
1958 c4b1fcc0 bellard
    ioh->fd_can_read = fd_can_read;
1959 c4b1fcc0 bellard
    ioh->fd_read = fd_read;
1960 c4b1fcc0 bellard
    ioh->opaque = opaque;
1961 8a7ddc38 bellard
    ioh->next = first_io_handler;
1962 8a7ddc38 bellard
    first_io_handler = ioh;
1963 c4b1fcc0 bellard
    return 0;
1964 c4b1fcc0 bellard
}
1965 c4b1fcc0 bellard
1966 8a7ddc38 bellard
void qemu_del_fd_read_handler(int fd)
1967 8a7ddc38 bellard
{
1968 8a7ddc38 bellard
    IOHandlerRecord **pioh, *ioh;
1969 b4608c04 bellard
1970 8a7ddc38 bellard
    pioh = &first_io_handler;
1971 8a7ddc38 bellard
    for(;;) {
1972 8a7ddc38 bellard
        ioh = *pioh;
1973 8a7ddc38 bellard
        if (ioh == NULL)
1974 8a7ddc38 bellard
            break;
1975 8a7ddc38 bellard
        if (ioh->fd == fd) {
1976 8a7ddc38 bellard
            *pioh = ioh->next;
1977 8a7ddc38 bellard
            break;
1978 8a7ddc38 bellard
        }
1979 8a7ddc38 bellard
        pioh = &ioh->next;
1980 8a7ddc38 bellard
    }
1981 8a7ddc38 bellard
}
1982 8a7ddc38 bellard
1983 8a7ddc38 bellard
/***********************************************************/
1984 8a7ddc38 bellard
/* savevm/loadvm support */
1985 8a7ddc38 bellard
1986 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
1987 b4608c04 bellard
{
1988 8a7ddc38 bellard
    fwrite(buf, 1, size, f);
1989 b4608c04 bellard
}
1990 b4608c04 bellard
1991 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
1992 b4608c04 bellard
{
1993 8a7ddc38 bellard
    fputc(v, f);
1994 8a7ddc38 bellard
}
1995 8a7ddc38 bellard
1996 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
1997 8a7ddc38 bellard
{
1998 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
1999 8a7ddc38 bellard
    qemu_put_byte(f, v);
2000 8a7ddc38 bellard
}
2001 8a7ddc38 bellard
2002 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
2003 8a7ddc38 bellard
{
2004 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
2005 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
2006 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
2007 8a7ddc38 bellard
    qemu_put_byte(f, v);
2008 8a7ddc38 bellard
}
2009 8a7ddc38 bellard
2010 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
2011 8a7ddc38 bellard
{
2012 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
2013 8a7ddc38 bellard
    qemu_put_be32(f, v);
2014 8a7ddc38 bellard
}
2015 8a7ddc38 bellard
2016 8a7ddc38 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
2017 8a7ddc38 bellard
{
2018 8a7ddc38 bellard
    return fread(buf, 1, size, f);
2019 8a7ddc38 bellard
}
2020 8a7ddc38 bellard
2021 8a7ddc38 bellard
int qemu_get_byte(QEMUFile *f)
2022 8a7ddc38 bellard
{
2023 8a7ddc38 bellard
    int v;
2024 8a7ddc38 bellard
    v = fgetc(f);
2025 8a7ddc38 bellard
    if (v == EOF)
2026 8a7ddc38 bellard
        return 0;
2027 8a7ddc38 bellard
    else
2028 8a7ddc38 bellard
        return v;
2029 8a7ddc38 bellard
}
2030 8a7ddc38 bellard
2031 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
2032 8a7ddc38 bellard
{
2033 8a7ddc38 bellard
    unsigned int v;
2034 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
2035 8a7ddc38 bellard
    v |= qemu_get_byte(f);
2036 8a7ddc38 bellard
    return v;
2037 8a7ddc38 bellard
}
2038 8a7ddc38 bellard
2039 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
2040 8a7ddc38 bellard
{
2041 8a7ddc38 bellard
    unsigned int v;
2042 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
2043 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
2044 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
2045 8a7ddc38 bellard
    v |= qemu_get_byte(f);
2046 8a7ddc38 bellard
    return v;
2047 8a7ddc38 bellard
}
2048 8a7ddc38 bellard
2049 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
2050 8a7ddc38 bellard
{
2051 8a7ddc38 bellard
    uint64_t v;
2052 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
2053 8a7ddc38 bellard
    v |= qemu_get_be32(f);
2054 8a7ddc38 bellard
    return v;
2055 8a7ddc38 bellard
}
2056 8a7ddc38 bellard
2057 8a7ddc38 bellard
int64_t qemu_ftell(QEMUFile *f)
2058 8a7ddc38 bellard
{
2059 8a7ddc38 bellard
    return ftell(f);
2060 8a7ddc38 bellard
}
2061 8a7ddc38 bellard
2062 8a7ddc38 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
2063 8a7ddc38 bellard
{
2064 8a7ddc38 bellard
    if (fseek(f, pos, whence) < 0)
2065 8a7ddc38 bellard
        return -1;
2066 8a7ddc38 bellard
    return ftell(f);
2067 8a7ddc38 bellard
}
2068 8a7ddc38 bellard
2069 8a7ddc38 bellard
typedef struct SaveStateEntry {
2070 8a7ddc38 bellard
    char idstr[256];
2071 8a7ddc38 bellard
    int instance_id;
2072 8a7ddc38 bellard
    int version_id;
2073 8a7ddc38 bellard
    SaveStateHandler *save_state;
2074 8a7ddc38 bellard
    LoadStateHandler *load_state;
2075 8a7ddc38 bellard
    void *opaque;
2076 8a7ddc38 bellard
    struct SaveStateEntry *next;
2077 8a7ddc38 bellard
} SaveStateEntry;
2078 b4608c04 bellard
2079 8a7ddc38 bellard
static SaveStateEntry *first_se;
2080 8a7ddc38 bellard
2081 8a7ddc38 bellard
int register_savevm(const char *idstr, 
2082 8a7ddc38 bellard
                    int instance_id, 
2083 8a7ddc38 bellard
                    int version_id,
2084 8a7ddc38 bellard
                    SaveStateHandler *save_state,
2085 8a7ddc38 bellard
                    LoadStateHandler *load_state,
2086 8a7ddc38 bellard
                    void *opaque)
2087 8a7ddc38 bellard
{
2088 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
2089 8a7ddc38 bellard
2090 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
2091 8a7ddc38 bellard
    if (!se)
2092 8a7ddc38 bellard
        return -1;
2093 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
2094 8a7ddc38 bellard
    se->instance_id = instance_id;
2095 8a7ddc38 bellard
    se->version_id = version_id;
2096 8a7ddc38 bellard
    se->save_state = save_state;
2097 8a7ddc38 bellard
    se->load_state = load_state;
2098 8a7ddc38 bellard
    se->opaque = opaque;
2099 8a7ddc38 bellard
    se->next = NULL;
2100 8a7ddc38 bellard
2101 8a7ddc38 bellard
    /* add at the end of list */
2102 8a7ddc38 bellard
    pse = &first_se;
2103 8a7ddc38 bellard
    while (*pse != NULL)
2104 8a7ddc38 bellard
        pse = &(*pse)->next;
2105 8a7ddc38 bellard
    *pse = se;
2106 8a7ddc38 bellard
    return 0;
2107 8a7ddc38 bellard
}
2108 8a7ddc38 bellard
2109 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
2110 8a7ddc38 bellard
#define QEMU_VM_FILE_VERSION 0x00000001
2111 8a7ddc38 bellard
2112 8a7ddc38 bellard
int qemu_savevm(const char *filename)
2113 8a7ddc38 bellard
{
2114 8a7ddc38 bellard
    SaveStateEntry *se;
2115 8a7ddc38 bellard
    QEMUFile *f;
2116 8a7ddc38 bellard
    int len, len_pos, cur_pos, saved_vm_running, ret;
2117 8a7ddc38 bellard
2118 8a7ddc38 bellard
    saved_vm_running = vm_running;
2119 8a7ddc38 bellard
    vm_stop(0);
2120 8a7ddc38 bellard
2121 8a7ddc38 bellard
    f = fopen(filename, "wb");
2122 8a7ddc38 bellard
    if (!f) {
2123 8a7ddc38 bellard
        ret = -1;
2124 8a7ddc38 bellard
        goto the_end;
2125 313aa567 bellard
    }
2126 313aa567 bellard
2127 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
2128 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
2129 8a7ddc38 bellard
2130 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
2131 8a7ddc38 bellard
        /* ID string */
2132 8a7ddc38 bellard
        len = strlen(se->idstr);
2133 8a7ddc38 bellard
        qemu_put_byte(f, len);
2134 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
2135 8a7ddc38 bellard
2136 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
2137 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
2138 8a7ddc38 bellard
2139 8a7ddc38 bellard
        /* record size: filled later */
2140 8a7ddc38 bellard
        len_pos = ftell(f);
2141 8a7ddc38 bellard
        qemu_put_be32(f, 0);
2142 8a7ddc38 bellard
        
2143 8a7ddc38 bellard
        se->save_state(f, se->opaque);
2144 8a7ddc38 bellard
2145 8a7ddc38 bellard
        /* fill record size */
2146 8a7ddc38 bellard
        cur_pos = ftell(f);
2147 8a7ddc38 bellard
        len = ftell(f) - len_pos - 4;
2148 8a7ddc38 bellard
        fseek(f, len_pos, SEEK_SET);
2149 8a7ddc38 bellard
        qemu_put_be32(f, len);
2150 8a7ddc38 bellard
        fseek(f, cur_pos, SEEK_SET);
2151 8a7ddc38 bellard
    }
2152 8a7ddc38 bellard
2153 8a7ddc38 bellard
    fclose(f);
2154 8a7ddc38 bellard
    ret = 0;
2155 8a7ddc38 bellard
 the_end:
2156 8a7ddc38 bellard
    if (saved_vm_running)
2157 8a7ddc38 bellard
        vm_start();
2158 8a7ddc38 bellard
    return ret;
2159 8a7ddc38 bellard
}
2160 8a7ddc38 bellard
2161 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
2162 8a7ddc38 bellard
{
2163 8a7ddc38 bellard
    SaveStateEntry *se;
2164 8a7ddc38 bellard
2165 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
2166 8a7ddc38 bellard
        if (!strcmp(se->idstr, idstr) && 
2167 8a7ddc38 bellard
            instance_id == se->instance_id)
2168 8a7ddc38 bellard
            return se;
2169 8a7ddc38 bellard
    }
2170 8a7ddc38 bellard
    return NULL;
2171 8a7ddc38 bellard
}
2172 8a7ddc38 bellard
2173 8a7ddc38 bellard
int qemu_loadvm(const char *filename)
2174 8a7ddc38 bellard
{
2175 8a7ddc38 bellard
    SaveStateEntry *se;
2176 8a7ddc38 bellard
    QEMUFile *f;
2177 8a7ddc38 bellard
    int len, cur_pos, ret, instance_id, record_len, version_id;
2178 8a7ddc38 bellard
    int saved_vm_running;
2179 8a7ddc38 bellard
    unsigned int v;
2180 8a7ddc38 bellard
    char idstr[256];
2181 8a7ddc38 bellard
    
2182 8a7ddc38 bellard
    saved_vm_running = vm_running;
2183 8a7ddc38 bellard
    vm_stop(0);
2184 8a7ddc38 bellard
2185 8a7ddc38 bellard
    f = fopen(filename, "rb");
2186 8a7ddc38 bellard
    if (!f) {
2187 8a7ddc38 bellard
        ret = -1;
2188 8a7ddc38 bellard
        goto the_end;
2189 8a7ddc38 bellard
    }
2190 8a7ddc38 bellard
2191 8a7ddc38 bellard
    v = qemu_get_be32(f);
2192 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
2193 8a7ddc38 bellard
        goto fail;
2194 8a7ddc38 bellard
    v = qemu_get_be32(f);
2195 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
2196 8a7ddc38 bellard
    fail:
2197 8a7ddc38 bellard
        fclose(f);
2198 8a7ddc38 bellard
        ret = -1;
2199 8a7ddc38 bellard
        goto the_end;
2200 8a7ddc38 bellard
    }
2201 b4608c04 bellard
    for(;;) {
2202 a541f297 bellard
#if defined (DO_TB_FLUSH)
2203 d927637d bellard
        tb_flush(global_env);
2204 a541f297 bellard
#endif
2205 8a7ddc38 bellard
        len = qemu_get_byte(f);
2206 8a7ddc38 bellard
        if (feof(f))
2207 cd4c3e88 bellard
            break;
2208 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
2209 8a7ddc38 bellard
        idstr[len] = '\0';
2210 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
2211 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
2212 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
2213 8a7ddc38 bellard
#if 0
2214 8a7ddc38 bellard
        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
2215 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
2216 8a7ddc38 bellard
#endif
2217 8a7ddc38 bellard
        cur_pos = ftell(f);
2218 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
2219 8a7ddc38 bellard
        if (!se) {
2220 8a7ddc38 bellard
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
2221 8a7ddc38 bellard
                    instance_id, idstr);
2222 8a7ddc38 bellard
        } else {
2223 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
2224 8a7ddc38 bellard
            if (ret < 0) {
2225 8a7ddc38 bellard
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
2226 8a7ddc38 bellard
                        instance_id, idstr);
2227 8a7ddc38 bellard
            }
2228 34865134 bellard
        }
2229 8a7ddc38 bellard
        /* always seek to exact end of record */
2230 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
2231 8a7ddc38 bellard
    }
2232 8a7ddc38 bellard
    fclose(f);
2233 8a7ddc38 bellard
    ret = 0;
2234 8a7ddc38 bellard
 the_end:
2235 8a7ddc38 bellard
    if (saved_vm_running)
2236 8a7ddc38 bellard
        vm_start();
2237 8a7ddc38 bellard
    return ret;
2238 8a7ddc38 bellard
}
2239 8a7ddc38 bellard
2240 8a7ddc38 bellard
/***********************************************************/
2241 8a7ddc38 bellard
/* cpu save/restore */
2242 8a7ddc38 bellard
2243 8a7ddc38 bellard
#if defined(TARGET_I386)
2244 8a7ddc38 bellard
2245 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
2246 8a7ddc38 bellard
{
2247 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
2248 20f32282 bellard
    qemu_put_betl(f, dt->base);
2249 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
2250 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
2251 8a7ddc38 bellard
}
2252 8a7ddc38 bellard
2253 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
2254 8a7ddc38 bellard
{
2255 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
2256 20f32282 bellard
    dt->base = qemu_get_betl(f);
2257 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
2258 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
2259 8a7ddc38 bellard
}
2260 8a7ddc38 bellard
2261 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
2262 8a7ddc38 bellard
{
2263 8a7ddc38 bellard
    CPUState *env = opaque;
2264 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
2265 8a7ddc38 bellard
    uint32_t hflags;
2266 8a7ddc38 bellard
    int i;
2267 664e0f19 bellard
    
2268 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
2269 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
2270 20f32282 bellard
    qemu_put_betls(f, &env->eip);
2271 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
2272 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
2273 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
2274 8a7ddc38 bellard
    
2275 8a7ddc38 bellard
    /* FPU */
2276 8a7ddc38 bellard
    fpuc = env->fpuc;
2277 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2278 8a7ddc38 bellard
    fptag = 0;
2279 664e0f19 bellard
    for(i = 0; i < 8; i++) {
2280 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
2281 8a7ddc38 bellard
    }
2282 8a7ddc38 bellard
    
2283 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
2284 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
2285 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
2286 8a7ddc38 bellard
2287 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2288 664e0f19 bellard
    fpregs_format = 0;
2289 664e0f19 bellard
#else
2290 664e0f19 bellard
    fpregs_format = 1;
2291 664e0f19 bellard
#endif
2292 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
2293 664e0f19 bellard
    
2294 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2295 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2296 8636b5d8 bellard
        {
2297 8636b5d8 bellard
            uint64_t mant;
2298 8636b5d8 bellard
            uint16_t exp;
2299 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
2300 8636b5d8 bellard
               contains the MMX register */
2301 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
2302 8636b5d8 bellard
            qemu_put_be64(f, mant);
2303 8636b5d8 bellard
            qemu_put_be16(f, exp);
2304 8636b5d8 bellard
        }
2305 664e0f19 bellard
#else
2306 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
2307 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
2308 664e0f19 bellard
           problems if the image is restored on a CPU where long
2309 664e0f19 bellard
           doubles are used instead. */
2310 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
2311 664e0f19 bellard
#endif
2312 8a7ddc38 bellard
    }
2313 8a7ddc38 bellard
2314 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
2315 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
2316 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
2317 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
2318 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
2319 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
2320 8a7ddc38 bellard
    
2321 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
2322 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
2323 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
2324 8a7ddc38 bellard
    
2325 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
2326 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
2327 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
2328 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
2329 8a7ddc38 bellard
    
2330 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
2331 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
2332 8a7ddc38 bellard
2333 8a7ddc38 bellard
    /* MMU */
2334 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
2335 02536f8b bellard
2336 664e0f19 bellard
    /* XMM */
2337 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
2338 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
2339 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2340 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2341 02536f8b bellard
    }
2342 02536f8b bellard
2343 664e0f19 bellard
#ifdef TARGET_X86_64
2344 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
2345 02536f8b bellard
    qemu_put_be64s(f, &env->star);
2346 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
2347 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
2348 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
2349 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
2350 02536f8b bellard
#endif
2351 8a7ddc38 bellard
}
2352 8a7ddc38 bellard
2353 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
2354 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
2355 664e0f19 bellard
union x86_longdouble {
2356 664e0f19 bellard
    uint64_t mant;
2357 664e0f19 bellard
    uint16_t exp;
2358 664e0f19 bellard
};
2359 664e0f19 bellard
2360 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
2361 664e0f19 bellard
#define EXPBIAS1 1023
2362 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
2363 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
2364 664e0f19 bellard
2365 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
2366 664e0f19 bellard
{
2367 664e0f19 bellard
    int e;
2368 664e0f19 bellard
    /* mantissa */
2369 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
2370 664e0f19 bellard
    /* exponent + sign */
2371 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
2372 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
2373 664e0f19 bellard
    p->exp = e;
2374 664e0f19 bellard
}
2375 8636b5d8 bellard
#endif
2376 664e0f19 bellard
2377 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2378 8a7ddc38 bellard
{
2379 8a7ddc38 bellard
    CPUState *env = opaque;
2380 664e0f19 bellard
    int i, guess_mmx;
2381 8a7ddc38 bellard
    uint32_t hflags;
2382 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
2383 8a7ddc38 bellard
2384 664e0f19 bellard
    if (version_id != 3)
2385 8a7ddc38 bellard
        return -EINVAL;
2386 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
2387 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
2388 20f32282 bellard
    qemu_get_betls(f, &env->eip);
2389 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
2390 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
2391 8a7ddc38 bellard
2392 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
2393 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
2394 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
2395 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
2396 664e0f19 bellard
    
2397 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
2398 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
2399 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
2400 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
2401 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2402 8a7ddc38 bellard
        uint64_t mant;
2403 8a7ddc38 bellard
        uint16_t exp;
2404 664e0f19 bellard
        
2405 664e0f19 bellard
        switch(fpregs_format) {
2406 664e0f19 bellard
        case 0:
2407 664e0f19 bellard
            mant = qemu_get_be64(f);
2408 664e0f19 bellard
            exp = qemu_get_be16(f);
2409 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2410 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
2411 664e0f19 bellard
#else
2412 664e0f19 bellard
            /* difficult case */
2413 664e0f19 bellard
            if (guess_mmx)
2414 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
2415 664e0f19 bellard
            else
2416 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
2417 664e0f19 bellard
#endif
2418 664e0f19 bellard
            break;
2419 664e0f19 bellard
        case 1:
2420 664e0f19 bellard
            mant = qemu_get_be64(f);
2421 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2422 8636b5d8 bellard
            {
2423 8636b5d8 bellard
                union x86_longdouble *p;
2424 8636b5d8 bellard
                /* difficult case */
2425 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
2426 8636b5d8 bellard
                if (guess_mmx) {
2427 8636b5d8 bellard
                    p->mant = mant;
2428 8636b5d8 bellard
                    p->exp = 0xffff;
2429 8636b5d8 bellard
                } else {
2430 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
2431 8636b5d8 bellard
                }
2432 664e0f19 bellard
            }
2433 664e0f19 bellard
#else
2434 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
2435 664e0f19 bellard
#endif            
2436 664e0f19 bellard
            break;
2437 664e0f19 bellard
        default:
2438 664e0f19 bellard
            return -EINVAL;
2439 664e0f19 bellard
        }
2440 8a7ddc38 bellard
    }
2441 8a7ddc38 bellard
2442 8a7ddc38 bellard
    env->fpuc = fpuc;
2443 7a0e1f41 bellard
    /* XXX: restore FPU round state */
2444 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
2445 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
2446 664e0f19 bellard
    fptag ^= 0xff;
2447 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2448 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
2449 8a7ddc38 bellard
    }
2450 8a7ddc38 bellard
    
2451 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
2452 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
2453 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
2454 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
2455 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
2456 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
2457 8a7ddc38 bellard
    
2458 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
2459 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
2460 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
2461 8a7ddc38 bellard
    
2462 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
2463 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
2464 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
2465 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
2466 8a7ddc38 bellard
    
2467 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
2468 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
2469 8a7ddc38 bellard
2470 8a7ddc38 bellard
    /* MMU */
2471 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
2472 8a7ddc38 bellard
2473 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
2474 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
2475 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2476 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2477 02536f8b bellard
    }
2478 02536f8b bellard
2479 664e0f19 bellard
#ifdef TARGET_X86_64
2480 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
2481 02536f8b bellard
    qemu_get_be64s(f, &env->star);
2482 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
2483 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
2484 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
2485 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
2486 02536f8b bellard
#endif
2487 02536f8b bellard
2488 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
2489 8a7ddc38 bellard
    env->hflags = hflags;
2490 8a7ddc38 bellard
    tlb_flush(env, 1);
2491 8a7ddc38 bellard
    return 0;
2492 8a7ddc38 bellard
}
2493 8a7ddc38 bellard
2494 a541f297 bellard
#elif defined(TARGET_PPC)
2495 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
2496 a541f297 bellard
{
2497 a541f297 bellard
}
2498 a541f297 bellard
2499 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2500 a541f297 bellard
{
2501 a541f297 bellard
    return 0;
2502 a541f297 bellard
}
2503 6af0bf9c bellard
2504 6af0bf9c bellard
#elif defined(TARGET_MIPS)
2505 6af0bf9c bellard
void cpu_save(QEMUFile *f, void *opaque)
2506 6af0bf9c bellard
{
2507 6af0bf9c bellard
}
2508 6af0bf9c bellard
2509 6af0bf9c bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2510 6af0bf9c bellard
{
2511 6af0bf9c bellard
    return 0;
2512 6af0bf9c bellard
}
2513 6af0bf9c bellard
2514 e95c8d51 bellard
#elif defined(TARGET_SPARC)
2515 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
2516 e95c8d51 bellard
{
2517 e80cfcfc bellard
    CPUState *env = opaque;
2518 e80cfcfc bellard
    int i;
2519 e80cfcfc bellard
    uint32_t tmp;
2520 e80cfcfc bellard
2521 4fa5d772 bellard
    for(i = 0; i < 8; i++)
2522 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
2523 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
2524 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
2525 e80cfcfc bellard
2526 e80cfcfc bellard
    /* FPU */
2527 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
2528 4fa5d772 bellard
        union {
2529 4fa5d772 bellard
            TARGET_FPREG_T f;
2530 4fa5d772 bellard
            target_ulong i;
2531 4fa5d772 bellard
        } u;
2532 4fa5d772 bellard
        u.f = env->fpr[i];
2533 4fa5d772 bellard
        qemu_put_betl(f, u.i);
2534 4fa5d772 bellard
    }
2535 4fa5d772 bellard
2536 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
2537 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
2538 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
2539 e80cfcfc bellard
    tmp = GET_PSR(env);
2540 4fa5d772 bellard
    qemu_put_be32(f, tmp);
2541 3475187d bellard
    qemu_put_betls(f, &env->fsr);
2542 3475187d bellard
    qemu_put_betls(f, &env->tbr);
2543 3475187d bellard
#ifndef TARGET_SPARC64
2544 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
2545 e80cfcfc bellard
    /* MMU */
2546 e80cfcfc bellard
    for(i = 0; i < 16; i++)
2547 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
2548 3475187d bellard
#endif
2549 e95c8d51 bellard
}
2550 e95c8d51 bellard
2551 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2552 e95c8d51 bellard
{
2553 e80cfcfc bellard
    CPUState *env = opaque;
2554 e80cfcfc bellard
    int i;
2555 e80cfcfc bellard
    uint32_t tmp;
2556 e80cfcfc bellard
2557 4fa5d772 bellard
    for(i = 0; i < 8; i++)
2558 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
2559 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
2560 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
2561 e80cfcfc bellard
2562 e80cfcfc bellard
    /* FPU */
2563 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
2564 4fa5d772 bellard
        union {
2565 4fa5d772 bellard
            TARGET_FPREG_T f;
2566 4fa5d772 bellard
            target_ulong i;
2567 4fa5d772 bellard
        } u;
2568 4fa5d772 bellard
        u.i = qemu_get_betl(f);
2569 4fa5d772 bellard
        env->fpr[i] = u.f;
2570 4fa5d772 bellard
    }
2571 4fa5d772 bellard
2572 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
2573 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
2574 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
2575 4fa5d772 bellard
    tmp = qemu_get_be32(f);
2576 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
2577 4fa5d772 bellard
                     correctly updated */
2578 e80cfcfc bellard
    PUT_PSR(env, tmp);
2579 3475187d bellard
    qemu_get_betls(f, &env->fsr);
2580 3475187d bellard
    qemu_get_betls(f, &env->tbr);
2581 3475187d bellard
#ifndef TARGET_SPARC64
2582 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
2583 e80cfcfc bellard
    /* MMU */
2584 e80cfcfc bellard
    for(i = 0; i < 16; i++)
2585 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
2586 3475187d bellard
#endif
2587 e80cfcfc bellard
    tlb_flush(env, 1);
2588 e95c8d51 bellard
    return 0;
2589 e95c8d51 bellard
}
2590 8a7ddc38 bellard
#else
2591 8a7ddc38 bellard
2592 8a7ddc38 bellard
#warning No CPU save/restore functions
2593 8a7ddc38 bellard
2594 8a7ddc38 bellard
#endif
2595 8a7ddc38 bellard
2596 8a7ddc38 bellard
/***********************************************************/
2597 8a7ddc38 bellard
/* ram save/restore */
2598 8a7ddc38 bellard
2599 8a7ddc38 bellard
/* we just avoid storing empty pages */
2600 8a7ddc38 bellard
static void ram_put_page(QEMUFile *f, const uint8_t *buf, int len)
2601 8a7ddc38 bellard
{
2602 8a7ddc38 bellard
    int i, v;
2603 8a7ddc38 bellard
2604 8a7ddc38 bellard
    v = buf[0];
2605 8a7ddc38 bellard
    for(i = 1; i < len; i++) {
2606 8a7ddc38 bellard
        if (buf[i] != v)
2607 8a7ddc38 bellard
            goto normal_save;
2608 8a7ddc38 bellard
    }
2609 8a7ddc38 bellard
    qemu_put_byte(f, 1);
2610 8a7ddc38 bellard
    qemu_put_byte(f, v);
2611 8a7ddc38 bellard
    return;
2612 8a7ddc38 bellard
 normal_save:
2613 8a7ddc38 bellard
    qemu_put_byte(f, 0); 
2614 8a7ddc38 bellard
    qemu_put_buffer(f, buf, len);
2615 8a7ddc38 bellard
}
2616 8a7ddc38 bellard
2617 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
2618 8a7ddc38 bellard
{
2619 8a7ddc38 bellard
    int v;
2620 8a7ddc38 bellard
2621 8a7ddc38 bellard
    v = qemu_get_byte(f);
2622 8a7ddc38 bellard
    switch(v) {
2623 8a7ddc38 bellard
    case 0:
2624 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
2625 8a7ddc38 bellard
            return -EIO;
2626 8a7ddc38 bellard
        break;
2627 8a7ddc38 bellard
    case 1:
2628 8a7ddc38 bellard
        v = qemu_get_byte(f);
2629 8a7ddc38 bellard
        memset(buf, v, len);
2630 8a7ddc38 bellard
        break;
2631 8a7ddc38 bellard
    default:
2632 8a7ddc38 bellard
        return -EINVAL;
2633 8a7ddc38 bellard
    }
2634 8a7ddc38 bellard
    return 0;
2635 8a7ddc38 bellard
}
2636 8a7ddc38 bellard
2637 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
2638 8a7ddc38 bellard
{
2639 8a7ddc38 bellard
    int i;
2640 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
2641 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
2642 8a7ddc38 bellard
        ram_put_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
2643 8a7ddc38 bellard
    }
2644 8a7ddc38 bellard
}
2645 8a7ddc38 bellard
2646 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
2647 8a7ddc38 bellard
{
2648 8a7ddc38 bellard
    int i, ret;
2649 8a7ddc38 bellard
2650 8a7ddc38 bellard
    if (version_id != 1)
2651 8a7ddc38 bellard
        return -EINVAL;
2652 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
2653 8a7ddc38 bellard
        return -EINVAL;
2654 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
2655 8a7ddc38 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
2656 8a7ddc38 bellard
        if (ret)
2657 8a7ddc38 bellard
            return ret;
2658 8a7ddc38 bellard
    }
2659 8a7ddc38 bellard
    return 0;
2660 8a7ddc38 bellard
}
2661 8a7ddc38 bellard
2662 8a7ddc38 bellard
/***********************************************************/
2663 cc1daa40 bellard
/* machine registration */
2664 cc1daa40 bellard
2665 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
2666 cc1daa40 bellard
2667 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
2668 cc1daa40 bellard
{
2669 cc1daa40 bellard
    QEMUMachine **pm;
2670 cc1daa40 bellard
    pm = &first_machine;
2671 cc1daa40 bellard
    while (*pm != NULL)
2672 cc1daa40 bellard
        pm = &(*pm)->next;
2673 cc1daa40 bellard
    m->next = NULL;
2674 cc1daa40 bellard
    *pm = m;
2675 cc1daa40 bellard
    return 0;
2676 cc1daa40 bellard
}
2677 cc1daa40 bellard
2678 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
2679 cc1daa40 bellard
{
2680 cc1daa40 bellard
    QEMUMachine *m;
2681 cc1daa40 bellard
2682 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
2683 cc1daa40 bellard
        if (!strcmp(m->name, name))
2684 cc1daa40 bellard
            return m;
2685 cc1daa40 bellard
    }
2686 cc1daa40 bellard
    return NULL;
2687 cc1daa40 bellard
}
2688 cc1daa40 bellard
2689 cc1daa40 bellard
/***********************************************************/
2690 8a7ddc38 bellard
/* main execution loop */
2691 8a7ddc38 bellard
2692 8a7ddc38 bellard
void gui_update(void *opaque)
2693 8a7ddc38 bellard
{
2694 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
2695 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
2696 8a7ddc38 bellard
}
2697 8a7ddc38 bellard
2698 8a7ddc38 bellard
/* XXX: support several handlers */
2699 8a7ddc38 bellard
VMStopHandler *vm_stop_cb;
2700 8a7ddc38 bellard
VMStopHandler *vm_stop_opaque;
2701 8a7ddc38 bellard
2702 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
2703 8a7ddc38 bellard
{
2704 8a7ddc38 bellard
    vm_stop_cb = cb;
2705 8a7ddc38 bellard
    vm_stop_opaque = opaque;
2706 8a7ddc38 bellard
    return 0;
2707 8a7ddc38 bellard
}
2708 8a7ddc38 bellard
2709 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
2710 8a7ddc38 bellard
{
2711 8a7ddc38 bellard
    vm_stop_cb = NULL;
2712 8a7ddc38 bellard
}
2713 8a7ddc38 bellard
2714 8a7ddc38 bellard
void vm_start(void)
2715 8a7ddc38 bellard
{
2716 8a7ddc38 bellard
    if (!vm_running) {
2717 8a7ddc38 bellard
        cpu_enable_ticks();
2718 8a7ddc38 bellard
        vm_running = 1;
2719 8a7ddc38 bellard
    }
2720 8a7ddc38 bellard
}
2721 8a7ddc38 bellard
2722 8a7ddc38 bellard
void vm_stop(int reason) 
2723 8a7ddc38 bellard
{
2724 8a7ddc38 bellard
    if (vm_running) {
2725 8a7ddc38 bellard
        cpu_disable_ticks();
2726 8a7ddc38 bellard
        vm_running = 0;
2727 8a7ddc38 bellard
        if (reason != 0) {
2728 8a7ddc38 bellard
            if (vm_stop_cb) {
2729 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
2730 8a7ddc38 bellard
            }
2731 34865134 bellard
        }
2732 8a7ddc38 bellard
    }
2733 8a7ddc38 bellard
}
2734 8a7ddc38 bellard
2735 bb0c6722 bellard
/* reset/shutdown handler */
2736 bb0c6722 bellard
2737 bb0c6722 bellard
typedef struct QEMUResetEntry {
2738 bb0c6722 bellard
    QEMUResetHandler *func;
2739 bb0c6722 bellard
    void *opaque;
2740 bb0c6722 bellard
    struct QEMUResetEntry *next;
2741 bb0c6722 bellard
} QEMUResetEntry;
2742 bb0c6722 bellard
2743 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
2744 bb0c6722 bellard
static int reset_requested;
2745 bb0c6722 bellard
static int shutdown_requested;
2746 3475187d bellard
static int powerdown_requested;
2747 bb0c6722 bellard
2748 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
2749 bb0c6722 bellard
{
2750 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
2751 bb0c6722 bellard
2752 bb0c6722 bellard
    pre = &first_reset_entry;
2753 bb0c6722 bellard
    while (*pre != NULL)
2754 bb0c6722 bellard
        pre = &(*pre)->next;
2755 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
2756 bb0c6722 bellard
    re->func = func;
2757 bb0c6722 bellard
    re->opaque = opaque;
2758 bb0c6722 bellard
    re->next = NULL;
2759 bb0c6722 bellard
    *pre = re;
2760 bb0c6722 bellard
}
2761 bb0c6722 bellard
2762 bb0c6722 bellard
void qemu_system_reset(void)
2763 bb0c6722 bellard
{
2764 bb0c6722 bellard
    QEMUResetEntry *re;
2765 bb0c6722 bellard
2766 bb0c6722 bellard
    /* reset all devices */
2767 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
2768 bb0c6722 bellard
        re->func(re->opaque);
2769 bb0c6722 bellard
    }
2770 bb0c6722 bellard
}
2771 bb0c6722 bellard
2772 bb0c6722 bellard
void qemu_system_reset_request(void)
2773 bb0c6722 bellard
{
2774 bb0c6722 bellard
    reset_requested = 1;
2775 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2776 bb0c6722 bellard
}
2777 bb0c6722 bellard
2778 bb0c6722 bellard
void qemu_system_shutdown_request(void)
2779 bb0c6722 bellard
{
2780 bb0c6722 bellard
    shutdown_requested = 1;
2781 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2782 bb0c6722 bellard
}
2783 bb0c6722 bellard
2784 3475187d bellard
void qemu_system_powerdown_request(void)
2785 3475187d bellard
{
2786 3475187d bellard
    powerdown_requested = 1;
2787 3475187d bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2788 3475187d bellard
}
2789 3475187d bellard
2790 bb0c6722 bellard
static void main_cpu_reset(void *opaque)
2791 bb0c6722 bellard
{
2792 e80cfcfc bellard
#if defined(TARGET_I386) || defined(TARGET_SPARC)
2793 bb0c6722 bellard
    CPUState *env = opaque;
2794 bb0c6722 bellard
    cpu_reset(env);
2795 bb0c6722 bellard
#endif
2796 bb0c6722 bellard
}
2797 bb0c6722 bellard
2798 5905b2e5 bellard
void main_loop_wait(int timeout)
2799 8a7ddc38 bellard
{
2800 67b915a5 bellard
#ifndef _WIN32
2801 8a7ddc38 bellard
    struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
2802 8a7ddc38 bellard
    IOHandlerRecord *ioh, *ioh_next;
2803 67b915a5 bellard
    uint8_t buf[4096];
2804 67b915a5 bellard
    int n, max_size;
2805 67b915a5 bellard
#endif
2806 5905b2e5 bellard
    int ret;
2807 c4b1fcc0 bellard
2808 38e205a2 bellard
#ifdef _WIN32
2809 38e205a2 bellard
        if (timeout > 0)
2810 38e205a2 bellard
            Sleep(timeout);
2811 38e205a2 bellard
#else
2812 b4608c04 bellard
        /* poll any events */
2813 8a7ddc38 bellard
        /* XXX: separate device handlers from system ones */
2814 b4608c04 bellard
        pf = ufds;
2815 8a7ddc38 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2816 8a7ddc38 bellard
            if (!ioh->fd_can_read) {
2817 8a7ddc38 bellard
                max_size = 0;
2818 c4b1fcc0 bellard
                pf->fd = ioh->fd;
2819 c4b1fcc0 bellard
                pf->events = POLLIN;
2820 c4b1fcc0 bellard
                ioh->ufd = pf;
2821 c4b1fcc0 bellard
                pf++;
2822 c4b1fcc0 bellard
            } else {
2823 8a7ddc38 bellard
                max_size = ioh->fd_can_read(ioh->opaque);
2824 8a7ddc38 bellard
                if (max_size > 0) {
2825 8a7ddc38 bellard
                    if (max_size > sizeof(buf))
2826 8a7ddc38 bellard
                        max_size = sizeof(buf);
2827 8a7ddc38 bellard
                    pf->fd = ioh->fd;
2828 8a7ddc38 bellard
                    pf->events = POLLIN;
2829 8a7ddc38 bellard
                    ioh->ufd = pf;
2830 8a7ddc38 bellard
                    pf++;
2831 8a7ddc38 bellard
                } else {
2832 8a7ddc38 bellard
                    ioh->ufd = NULL;
2833 8a7ddc38 bellard
                }
2834 c4b1fcc0 bellard
            }
2835 c4b1fcc0 bellard
            ioh->max_size = max_size;
2836 b4608c04 bellard
        }
2837 73332e5c bellard
        
2838 b4608c04 bellard
        ret = poll(ufds, pf - ufds, timeout);
2839 b4608c04 bellard
        if (ret > 0) {
2840 8a7ddc38 bellard
            /* XXX: better handling of removal */
2841 8a7ddc38 bellard
            for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
2842 8a7ddc38 bellard
                ioh_next = ioh->next;
2843 c4b1fcc0 bellard
                pf = ioh->ufd;
2844 c4b1fcc0 bellard
                if (pf) {
2845 8a7ddc38 bellard
                    if (pf->revents & POLLIN) {
2846 8a7ddc38 bellard
                        if (ioh->max_size == 0) {
2847 8a7ddc38 bellard
                            /* just a read event */
2848 8a7ddc38 bellard
                            ioh->fd_read(ioh->opaque, NULL, 0);
2849 8a7ddc38 bellard
                        } else {
2850 8a7ddc38 bellard
                            n = read(ioh->fd, buf, ioh->max_size);
2851 8a7ddc38 bellard
                            if (n >= 0) {
2852 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, buf, n);
2853 158156d1 bellard
                            } else if (errno != EAGAIN) {
2854 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, NULL, -errno);
2855 8a7ddc38 bellard
                            }
2856 8a7ddc38 bellard
                        }
2857 b4608c04 bellard
                    }
2858 b4608c04 bellard
                }
2859 b4608c04 bellard
            }
2860 b4608c04 bellard
        }
2861 5905b2e5 bellard
#endif /* !defined(_WIN32) */
2862 c20709aa bellard
#if defined(CONFIG_SLIRP)
2863 c20709aa bellard
        /* XXX: merge with poll() */
2864 c20709aa bellard
        if (slirp_inited) {
2865 c20709aa bellard
            fd_set rfds, wfds, xfds;
2866 c20709aa bellard
            int nfds;
2867 c20709aa bellard
            struct timeval tv;
2868 c20709aa bellard
2869 c20709aa bellard
            nfds = -1;
2870 c20709aa bellard
            FD_ZERO(&rfds);
2871 c20709aa bellard
            FD_ZERO(&wfds);
2872 c20709aa bellard
            FD_ZERO(&xfds);
2873 c20709aa bellard
            slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2874 c20709aa bellard
            tv.tv_sec = 0;
2875 c20709aa bellard
            tv.tv_usec = 0;
2876 c20709aa bellard
            ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
2877 c20709aa bellard
            if (ret >= 0) {
2878 c20709aa bellard
                slirp_select_poll(&rfds, &wfds, &xfds);
2879 c20709aa bellard
            }
2880 c20709aa bellard
        }
2881 c20709aa bellard
#endif
2882 c20709aa bellard
2883 8a7ddc38 bellard
        if (vm_running) {
2884 8a7ddc38 bellard
            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
2885 8a7ddc38 bellard
                            qemu_get_clock(vm_clock));
2886 8a7ddc38 bellard
            /* run dma transfers, if any */
2887 8a7ddc38 bellard
            DMA_run();
2888 b4608c04 bellard
        }
2889 313aa567 bellard
2890 8a7ddc38 bellard
        /* real time timers */
2891 8a7ddc38 bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
2892 8a7ddc38 bellard
                        qemu_get_clock(rt_clock));
2893 5905b2e5 bellard
}
2894 5905b2e5 bellard
2895 5905b2e5 bellard
int main_loop(void)
2896 5905b2e5 bellard
{
2897 5905b2e5 bellard
    int ret, timeout;
2898 5905b2e5 bellard
    CPUState *env = global_env;
2899 5905b2e5 bellard
2900 5905b2e5 bellard
    for(;;) {
2901 5905b2e5 bellard
        if (vm_running) {
2902 5905b2e5 bellard
            ret = cpu_exec(env);
2903 5905b2e5 bellard
            if (shutdown_requested) {
2904 3475187d bellard
                ret = EXCP_INTERRUPT;
2905 5905b2e5 bellard
                break;
2906 5905b2e5 bellard
            }
2907 5905b2e5 bellard
            if (reset_requested) {
2908 5905b2e5 bellard
                reset_requested = 0;
2909 5905b2e5 bellard
                qemu_system_reset();
2910 3475187d bellard
                ret = EXCP_INTERRUPT;
2911 3475187d bellard
            }
2912 3475187d bellard
            if (powerdown_requested) {
2913 3475187d bellard
                powerdown_requested = 0;
2914 3475187d bellard
                qemu_system_powerdown();
2915 3475187d bellard
                ret = EXCP_INTERRUPT;
2916 5905b2e5 bellard
            }
2917 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
2918 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
2919 5905b2e5 bellard
            }
2920 5905b2e5 bellard
            /* if hlt instruction, we wait until the next IRQ */
2921 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
2922 3475187d bellard
            if (ret == EXCP_HLT)
2923 5905b2e5 bellard
                timeout = 10;
2924 5905b2e5 bellard
            else
2925 5905b2e5 bellard
                timeout = 0;
2926 5905b2e5 bellard
        } else {
2927 5905b2e5 bellard
            timeout = 10;
2928 5905b2e5 bellard
        }
2929 5905b2e5 bellard
        main_loop_wait(timeout);
2930 b4608c04 bellard
    }
2931 34865134 bellard
    cpu_disable_ticks();
2932 34865134 bellard
    return ret;
2933 b4608c04 bellard
}
2934 b4608c04 bellard
2935 0824d6fc bellard
void help(void)
2936 0824d6fc bellard
{
2937 f5a8510c bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2005 Fabrice Bellard\n"
2938 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
2939 0824d6fc bellard
           "\n"
2940 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2941 fc01f7e7 bellard
           "\n"
2942 a20dd508 bellard
           "Standard options:\n"
2943 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
2944 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
2945 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
2946 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
2947 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
2948 9e89a4be bellard
           "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
2949 a20dd508 bellard
           "-snapshot       write to temporary files instead of disk image files\n"
2950 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
2951 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
2952 4ca0074c bellard
#ifndef _WIN32
2953 3d11d0eb bellard
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
2954 4ca0074c bellard
#endif
2955 1d14ffa9 bellard
#ifdef HAS_AUDIO
2956 c0fe3827 bellard
           "-enable-audio   enable audio support, and all the sound cars\n"
2957 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
2958 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
2959 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
2960 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
2961 1d14ffa9 bellard
#endif
2962 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
2963 d63d307f bellard
           "-full-screen    start in full screen\n"
2964 a09db21f bellard
#ifdef TARGET_I386
2965 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
2966 a09db21f bellard
#endif
2967 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
2968 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
2969 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
2970 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
2971 bb0c6722 bellard
#endif
2972 c4b1fcc0 bellard
           "\n"
2973 c4b1fcc0 bellard
           "Network options:\n"
2974 c20709aa bellard
           "-nics n         simulate 'n' network cards [default=1]\n"
2975 702c651c bellard
           "-macaddr addr   set the mac address of the first interface\n"
2976 c20709aa bellard
           "-n script       set tap/tun network init script [default=%s]\n"
2977 c20709aa bellard
           "-tun-fd fd      use this fd as already opened tap/tun interface\n"
2978 c20709aa bellard
#ifdef CONFIG_SLIRP
2979 c20709aa bellard
           "-user-net       use user mode network stack [default if no tap/tun script]\n"
2980 9bf05444 bellard
           "-tftp prefix    allow tftp access to files starting with prefix [-user-net]\n"
2981 c94c8d64 bellard
#ifndef _WIN32
2982 9d728e8c bellard
           "-smb dir        allow SMB access to files in 'dir' [-user-net]\n"
2983 c94c8d64 bellard
#endif
2984 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
2985 9bf05444 bellard
           "                redirect TCP or UDP connections from host to guest [-user-net]\n"
2986 c20709aa bellard
#endif
2987 c20709aa bellard
           "-dummy-net      use dummy network stack\n"
2988 a20dd508 bellard
           "\n"
2989 c4b1fcc0 bellard
           "Linux boot specific:\n"
2990 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
2991 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
2992 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
2993 fc01f7e7 bellard
           "\n"
2994 330d0414 bellard
           "Debug/Expert options:\n"
2995 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
2996 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
2997 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
2998 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
2999 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
3000 a20dd508 bellard
           "-s              wait gdb connection to port %d\n"
3001 a20dd508 bellard
           "-p port         change gdb connection port\n"
3002 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
3003 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
3004 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
3005 a20dd508 bellard
           "-L path         set the directory for the BIOS and VGA BIOS\n"
3006 d993e026 bellard
#ifdef USE_KQEMU
3007 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
3008 d993e026 bellard
#endif
3009 77fef8c1 bellard
#ifdef USE_CODE_COPY
3010 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
3011 77fef8c1 bellard
#endif
3012 bb0c6722 bellard
#ifdef TARGET_I386
3013 bb0c6722 bellard
           "-isa            simulate an ISA-only system (default is PCI system)\n"
3014 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
3015 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
3016 bb0c6722 bellard
#endif
3017 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
3018 0824d6fc bellard
           "\n"
3019 82c643ff bellard
           "During emulation, the following keys are useful:\n"
3020 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
3021 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
3022 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
3023 82c643ff bellard
           "\n"
3024 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
3025 82c643ff bellard
           ,
3026 0db63474 bellard
#ifdef CONFIG_SOFTMMU
3027 0db63474 bellard
           "qemu",
3028 0db63474 bellard
#else
3029 0db63474 bellard
           "qemu-fast",
3030 0db63474 bellard
#endif
3031 a00bad7e bellard
           DEFAULT_RAM_SIZE,
3032 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
3033 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
3034 6e44ba7f bellard
           "/tmp/qemu.log");
3035 0db63474 bellard
#ifndef CONFIG_SOFTMMU
3036 0db63474 bellard
    printf("\n"
3037 0db63474 bellard
           "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
3038 0db63474 bellard
           "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
3039 0db63474 bellard
           "PC emulation.\n");
3040 0db63474 bellard
#endif
3041 0824d6fc bellard
    exit(1);
3042 0824d6fc bellard
}
3043 0824d6fc bellard
3044 cd6f1169 bellard
#define HAS_ARG 0x0001
3045 cd6f1169 bellard
3046 cd6f1169 bellard
enum {
3047 cd6f1169 bellard
    QEMU_OPTION_h,
3048 cd6f1169 bellard
3049 cc1daa40 bellard
    QEMU_OPTION_M,
3050 cd6f1169 bellard
    QEMU_OPTION_fda,
3051 cd6f1169 bellard
    QEMU_OPTION_fdb,
3052 cd6f1169 bellard
    QEMU_OPTION_hda,
3053 cd6f1169 bellard
    QEMU_OPTION_hdb,
3054 cd6f1169 bellard
    QEMU_OPTION_hdc,
3055 cd6f1169 bellard
    QEMU_OPTION_hdd,
3056 cd6f1169 bellard
    QEMU_OPTION_cdrom,
3057 cd6f1169 bellard
    QEMU_OPTION_boot,
3058 cd6f1169 bellard
    QEMU_OPTION_snapshot,
3059 cd6f1169 bellard
    QEMU_OPTION_m,
3060 cd6f1169 bellard
    QEMU_OPTION_nographic,
3061 1d14ffa9 bellard
#ifdef HAS_AUDIO
3062 cd6f1169 bellard
    QEMU_OPTION_enable_audio,
3063 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
3064 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
3065 1d14ffa9 bellard
#endif
3066 cd6f1169 bellard
3067 cd6f1169 bellard
    QEMU_OPTION_nics,
3068 cd6f1169 bellard
    QEMU_OPTION_macaddr,
3069 cd6f1169 bellard
    QEMU_OPTION_n,
3070 cd6f1169 bellard
    QEMU_OPTION_tun_fd,
3071 cd6f1169 bellard
    QEMU_OPTION_user_net,
3072 c7f74643 bellard
    QEMU_OPTION_tftp,
3073 9d728e8c bellard
    QEMU_OPTION_smb,
3074 9bf05444 bellard
    QEMU_OPTION_redir,
3075 cd6f1169 bellard
    QEMU_OPTION_dummy_net,
3076 cd6f1169 bellard
3077 cd6f1169 bellard
    QEMU_OPTION_kernel,
3078 cd6f1169 bellard
    QEMU_OPTION_append,
3079 cd6f1169 bellard
    QEMU_OPTION_initrd,
3080 cd6f1169 bellard
3081 cd6f1169 bellard
    QEMU_OPTION_S,
3082 cd6f1169 bellard
    QEMU_OPTION_s,
3083 cd6f1169 bellard
    QEMU_OPTION_p,
3084 cd6f1169 bellard
    QEMU_OPTION_d,
3085 cd6f1169 bellard
    QEMU_OPTION_hdachs,
3086 cd6f1169 bellard
    QEMU_OPTION_L,
3087 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
3088 3d11d0eb bellard
    QEMU_OPTION_k,
3089 ee22c2f7 bellard
    QEMU_OPTION_localtime,
3090 1f04275e bellard
    QEMU_OPTION_cirrusvga,
3091 e9b137c2 bellard
    QEMU_OPTION_g,
3092 1bfe856e bellard
    QEMU_OPTION_std_vga,
3093 82c643ff bellard
    QEMU_OPTION_monitor,
3094 82c643ff bellard
    QEMU_OPTION_serial,
3095 6508fe59 bellard
    QEMU_OPTION_parallel,
3096 d63d307f bellard
    QEMU_OPTION_loadvm,
3097 d63d307f bellard
    QEMU_OPTION_full_screen,
3098 f7cce898 bellard
    QEMU_OPTION_pidfile,
3099 d993e026 bellard
    QEMU_OPTION_no_kqemu,
3100 a09db21f bellard
    QEMU_OPTION_win2k_hack,
3101 bb36d470 bellard
    QEMU_OPTION_usb,
3102 a594cfbf bellard
    QEMU_OPTION_usbdevice,
3103 cd6f1169 bellard
};
3104 cd6f1169 bellard
3105 cd6f1169 bellard
typedef struct QEMUOption {
3106 cd6f1169 bellard
    const char *name;
3107 cd6f1169 bellard
    int flags;
3108 cd6f1169 bellard
    int index;
3109 cd6f1169 bellard
} QEMUOption;
3110 cd6f1169 bellard
3111 cd6f1169 bellard
const QEMUOption qemu_options[] = {
3112 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
3113 cd6f1169 bellard
3114 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
3115 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
3116 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
3117 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
3118 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
3119 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
3120 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
3121 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
3122 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
3123 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
3124 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
3125 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
3126 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
3127 1d14ffa9 bellard
#ifdef HAS_AUDIO
3128 cd6f1169 bellard
    { "enable-audio", 0, QEMU_OPTION_enable_audio },
3129 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
3130 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
3131 1d14ffa9 bellard
#endif
3132 cd6f1169 bellard
3133 cd6f1169 bellard
    { "nics", HAS_ARG, QEMU_OPTION_nics},
3134 cd6f1169 bellard
    { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
3135 69b91039 bellard
    { "n", HAS_ARG, QEMU_OPTION_n },
3136 cd6f1169 bellard
    { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
3137 158156d1 bellard
#ifdef CONFIG_SLIRP
3138 cd6f1169 bellard
    { "user-net", 0, QEMU_OPTION_user_net },
3139 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
3140 c94c8d64 bellard
#ifndef _WIN32
3141 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
3142 c94c8d64 bellard
#endif
3143 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
3144 158156d1 bellard
#endif
3145 cd6f1169 bellard
    { "dummy-net", 0, QEMU_OPTION_dummy_net },
3146 cd6f1169 bellard
3147 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
3148 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
3149 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
3150 cd6f1169 bellard
3151 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
3152 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
3153 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
3154 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
3155 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
3156 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
3157 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
3158 d993e026 bellard
#ifdef USE_KQEMU
3159 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
3160 d993e026 bellard
#endif
3161 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
3162 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
3163 77d4bc34 bellard
#endif
3164 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
3165 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
3166 82c643ff bellard
    { "monitor", 1, QEMU_OPTION_monitor },
3167 82c643ff bellard
    { "serial", 1, QEMU_OPTION_serial },
3168 6508fe59 bellard
    { "parallel", 1, QEMU_OPTION_parallel },
3169 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
3170 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
3171 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
3172 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
3173 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
3174 a09db21f bellard
    
3175 1f04275e bellard
    /* temporary options */
3176 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
3177 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
3178 cd6f1169 bellard
    { NULL },
3179 fc01f7e7 bellard
};
3180 fc01f7e7 bellard
3181 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
3182 77fef8c1 bellard
3183 77fef8c1 bellard
/* this stack is only used during signal handling */
3184 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
3185 77fef8c1 bellard
3186 77fef8c1 bellard
static uint8_t *signal_stack;
3187 77fef8c1 bellard
3188 77fef8c1 bellard
#endif
3189 77fef8c1 bellard
3190 5905b2e5 bellard
/* password input */
3191 5905b2e5 bellard
3192 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
3193 5905b2e5 bellard
{
3194 5905b2e5 bellard
    BlockDriverState *bs;
3195 5905b2e5 bellard
3196 5905b2e5 bellard
    if (index < 4) {
3197 5905b2e5 bellard
        bs = bs_table[index];
3198 5905b2e5 bellard
    } else if (index < 6) {
3199 5905b2e5 bellard
        bs = fd_table[index - 4];
3200 5905b2e5 bellard
    } else {
3201 5905b2e5 bellard
        bs = NULL;
3202 5905b2e5 bellard
    }
3203 5905b2e5 bellard
    return bs;
3204 5905b2e5 bellard
}
3205 5905b2e5 bellard
3206 5905b2e5 bellard
static void read_passwords(void)
3207 5905b2e5 bellard
{
3208 5905b2e5 bellard
    BlockDriverState *bs;
3209 5905b2e5 bellard
    int i, j;
3210 5905b2e5 bellard
    char password[256];
3211 5905b2e5 bellard
3212 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
3213 5905b2e5 bellard
        bs = get_bdrv(i);
3214 5905b2e5 bellard
        if (bs && bdrv_is_encrypted(bs)) {
3215 5905b2e5 bellard
            term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
3216 5905b2e5 bellard
            for(j = 0; j < 3; j++) {
3217 5905b2e5 bellard
                monitor_readline("Password: ", 
3218 5905b2e5 bellard
                                 1, password, sizeof(password));
3219 5905b2e5 bellard
                if (bdrv_set_key(bs, password) == 0)
3220 5905b2e5 bellard
                    break;
3221 5905b2e5 bellard
                term_printf("invalid password\n");
3222 5905b2e5 bellard
            }
3223 5905b2e5 bellard
        }
3224 5905b2e5 bellard
    }
3225 5905b2e5 bellard
}
3226 5905b2e5 bellard
3227 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
3228 cc1daa40 bellard
void register_machines(void)
3229 cc1daa40 bellard
{
3230 cc1daa40 bellard
#if defined(TARGET_I386)
3231 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
3232 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
3233 cc1daa40 bellard
#elif defined(TARGET_PPC)
3234 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
3235 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
3236 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
3237 6af0bf9c bellard
#elif defined(TARGET_MIPS)
3238 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
3239 cc1daa40 bellard
#elif defined(TARGET_SPARC)
3240 3475187d bellard
#ifdef TARGET_SPARC64
3241 3475187d bellard
    qemu_register_machine(&sun4u_machine);
3242 3475187d bellard
#else
3243 cc1daa40 bellard
    qemu_register_machine(&sun4m_machine);
3244 cc1daa40 bellard
#endif
3245 3475187d bellard
#endif
3246 cc1daa40 bellard
}
3247 cc1daa40 bellard
3248 1d14ffa9 bellard
#ifdef HAS_AUDIO
3249 1d14ffa9 bellard
static void select_soundhw (const char *optarg)
3250 1d14ffa9 bellard
{
3251 1d14ffa9 bellard
    if (*optarg == '?') {
3252 1d14ffa9 bellard
    show_valid_cards:
3253 1d14ffa9 bellard
        printf ("Valid sound card names (comma separated):\n");
3254 1d14ffa9 bellard
        printf ("sb16       Creative Sound Blaster 16\n");
3255 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
3256 1d14ffa9 bellard
#ifdef HAS_YMF262
3257 c0fe3827 bellard
        printf ("adlib      Yamaha YMF262 (OPL3)\n");
3258 1d14ffa9 bellard
#else
3259 c0fe3827 bellard
        printf ("adlib      Yamaha YM3812 (OPL2)\n");
3260 1d14ffa9 bellard
#endif
3261 1d14ffa9 bellard
#endif
3262 1d14ffa9 bellard
#ifdef CONFIG_GUS
3263 1d14ffa9 bellard
        printf ("gus        Gravis Ultrasound GF1\n");
3264 1d14ffa9 bellard
#endif
3265 1d14ffa9 bellard
        printf ("es1370     ENSONIQ AudioPCI ES1370\n");
3266 1d14ffa9 bellard
        exit (*optarg != '?');
3267 1d14ffa9 bellard
    }
3268 1d14ffa9 bellard
    else {
3269 1d14ffa9 bellard
        struct {
3270 1d14ffa9 bellard
            char *name;
3271 1d14ffa9 bellard
            int *enabledp;
3272 1d14ffa9 bellard
        } soundhw_tab[] = {
3273 1d14ffa9 bellard
            { "sb16", &sb16_enabled },
3274 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
3275 1d14ffa9 bellard
            { "adlib", &adlib_enabled },
3276 1d14ffa9 bellard
#endif
3277 1d14ffa9 bellard
#ifdef CONFIG_GUS
3278 1d14ffa9 bellard
            { "gus", &gus_enabled },
3279 1d14ffa9 bellard
#endif
3280 1d14ffa9 bellard
            { "es1370", &es1370_enabled },
3281 1d14ffa9 bellard
        };
3282 1d14ffa9 bellard
        size_t tablen, l, i;
3283 1d14ffa9 bellard
        const char *p;
3284 1d14ffa9 bellard
        char *e;
3285 1d14ffa9 bellard
        int bad_card = 0;
3286 1d14ffa9 bellard
3287 1d14ffa9 bellard
        p = optarg;
3288 1d14ffa9 bellard
        tablen = sizeof (soundhw_tab) / sizeof (soundhw_tab[0]);
3289 1d14ffa9 bellard
3290 1d14ffa9 bellard
        while (*p) {
3291 1d14ffa9 bellard
            e = strchr (p, ',');
3292 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
3293 1d14ffa9 bellard
            for (i = 0; i < tablen; ++i) {
3294 1d14ffa9 bellard
                if (!strncmp (soundhw_tab[i].name, p, l)) {
3295 1d14ffa9 bellard
                    audio_enabled = 1;
3296 1d14ffa9 bellard
                    *soundhw_tab[i].enabledp = 1;
3297 1d14ffa9 bellard
                    break;
3298 1d14ffa9 bellard
                }
3299 1d14ffa9 bellard
            }
3300 1d14ffa9 bellard
            if (i == tablen) {
3301 1d14ffa9 bellard
                if (l > 80) {
3302 1d14ffa9 bellard
                    fprintf (stderr,
3303 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
3304 1d14ffa9 bellard
                }
3305 1d14ffa9 bellard
                else {
3306 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
3307 1d14ffa9 bellard
                             (int) l, p);
3308 1d14ffa9 bellard
                }
3309 1d14ffa9 bellard
                bad_card = 1;
3310 1d14ffa9 bellard
            }
3311 1d14ffa9 bellard
            p += l + (e != NULL);
3312 1d14ffa9 bellard
        }
3313 1d14ffa9 bellard
3314 1d14ffa9 bellard
        if (bad_card)
3315 1d14ffa9 bellard
            goto show_valid_cards;
3316 1d14ffa9 bellard
    }
3317 1d14ffa9 bellard
}
3318 1d14ffa9 bellard
#endif
3319 1d14ffa9 bellard
3320 c20709aa bellard
#define NET_IF_TUN   0
3321 c20709aa bellard
#define NET_IF_USER  1
3322 c20709aa bellard
#define NET_IF_DUMMY 2
3323 c20709aa bellard
3324 0824d6fc bellard
int main(int argc, char **argv)
3325 0824d6fc bellard
{
3326 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3327 67b915a5 bellard
    int use_gdbstub, gdbstub_port;
3328 67b915a5 bellard
#endif
3329 cc1daa40 bellard
    int i, cdrom_index;
3330 1ccde1cb bellard
    int snapshot, linux_boot;
3331 c45886db bellard
    CPUState *env;
3332 7f7f9873 bellard
    const char *initrd_filename;
3333 c45886db bellard
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
3334 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
3335 313aa567 bellard
    DisplayState *ds = &display_state;
3336 46d4767d bellard
    int cyls, heads, secs, translation;
3337 a541f297 bellard
    int start_emulation = 1;
3338 702c651c bellard
    uint8_t macaddr[6];
3339 c20709aa bellard
    int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
3340 cd6f1169 bellard
    int optind;
3341 cd6f1169 bellard
    const char *r, *optarg;
3342 82c643ff bellard
    CharDriverState *monitor_hd;
3343 82c643ff bellard
    char monitor_device[128];
3344 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
3345 8d11df9e bellard
    int serial_device_index;
3346 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
3347 6508fe59 bellard
    int parallel_device_index;
3348 d63d307f bellard
    const char *loadvm = NULL;
3349 cc1daa40 bellard
    QEMUMachine *machine;
3350 a594cfbf bellard
    char usb_devices[MAX_VM_USB_PORTS][128];
3351 a594cfbf bellard
    int usb_devices_index;
3352 a594cfbf bellard
    
3353 67b915a5 bellard
#if !defined(CONFIG_SOFTMMU)
3354 0824d6fc bellard
    /* we never want that malloc() uses mmap() */
3355 0824d6fc bellard
    mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
3356 67b915a5 bellard
#endif
3357 cc1daa40 bellard
    register_machines();
3358 cc1daa40 bellard
    machine = first_machine;
3359 fc01f7e7 bellard
    initrd_filename = NULL;
3360 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
3361 c45886db bellard
        fd_filename[i] = NULL;
3362 fc01f7e7 bellard
    for(i = 0; i < MAX_DISKS; i++)
3363 fc01f7e7 bellard
        hd_filename[i] = NULL;
3364 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
3365 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
3366 0ced6589 bellard
    bios_size = BIOS_SIZE;
3367 f1510b2c bellard
    pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
3368 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3369 b4608c04 bellard
    use_gdbstub = 0;
3370 b4608c04 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
3371 67b915a5 bellard
#endif
3372 33e3963e bellard
    snapshot = 0;
3373 a20dd508 bellard
    nographic = 0;
3374 a20dd508 bellard
    kernel_filename = NULL;
3375 a20dd508 bellard
    kernel_cmdline = "";
3376 cc1daa40 bellard
#ifdef TARGET_PPC
3377 cc1daa40 bellard
    cdrom_index = 1;
3378 cc1daa40 bellard
#else
3379 cc1daa40 bellard
    cdrom_index = 2;
3380 cc1daa40 bellard
#endif
3381 c4b1fcc0 bellard
    cyls = heads = secs = 0;
3382 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
3383 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
3384 c4b1fcc0 bellard
3385 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
3386 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
3387 8d11df9e bellard
        serial_devices[i][0] = '\0';
3388 8d11df9e bellard
    serial_device_index = 0;
3389 8d11df9e bellard
    
3390 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
3391 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3392 6508fe59 bellard
        parallel_devices[i][0] = '\0';
3393 6508fe59 bellard
    parallel_device_index = 0;
3394 6508fe59 bellard
    
3395 a594cfbf bellard
    usb_devices_index = 0;
3396 a594cfbf bellard
    
3397 c20709aa bellard
    nb_tun_fds = 0;
3398 c20709aa bellard
    net_if_type = -1;
3399 c4b1fcc0 bellard
    nb_nics = 1;
3400 702c651c bellard
    /* default mac address of the first network interface */
3401 702c651c bellard
    macaddr[0] = 0x52;
3402 702c651c bellard
    macaddr[1] = 0x54;
3403 702c651c bellard
    macaddr[2] = 0x00;
3404 702c651c bellard
    macaddr[3] = 0x12;
3405 702c651c bellard
    macaddr[4] = 0x34;
3406 702c651c bellard
    macaddr[5] = 0x56;
3407 82c643ff bellard
    
3408 cd6f1169 bellard
    optind = 1;
3409 0824d6fc bellard
    for(;;) {
3410 cd6f1169 bellard
        if (optind >= argc)
3411 0824d6fc bellard
            break;
3412 cd6f1169 bellard
        r = argv[optind];
3413 cd6f1169 bellard
        if (r[0] != '-') {
3414 cd6f1169 bellard
            hd_filename[0] = argv[optind++];
3415 cd6f1169 bellard
        } else {
3416 cd6f1169 bellard
            const QEMUOption *popt;
3417 cd6f1169 bellard
3418 cd6f1169 bellard
            optind++;
3419 cd6f1169 bellard
            popt = qemu_options;
3420 cd6f1169 bellard
            for(;;) {
3421 cd6f1169 bellard
                if (!popt->name) {
3422 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
3423 cd6f1169 bellard
                            argv[0], r);
3424 cd6f1169 bellard
                    exit(1);
3425 cd6f1169 bellard
                }
3426 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
3427 cd6f1169 bellard
                    break;
3428 cd6f1169 bellard
                popt++;
3429 cd6f1169 bellard
            }
3430 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
3431 cd6f1169 bellard
                if (optind >= argc) {
3432 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
3433 cd6f1169 bellard
                            argv[0], r);
3434 cd6f1169 bellard
                    exit(1);
3435 cd6f1169 bellard
                }
3436 cd6f1169 bellard
                optarg = argv[optind++];
3437 cd6f1169 bellard
            } else {
3438 cd6f1169 bellard
                optarg = NULL;
3439 cd6f1169 bellard
            }
3440 cd6f1169 bellard
3441 cd6f1169 bellard
            switch(popt->index) {
3442 cc1daa40 bellard
            case QEMU_OPTION_M:
3443 cc1daa40 bellard
                machine = find_machine(optarg);
3444 cc1daa40 bellard
                if (!machine) {
3445 cc1daa40 bellard
                    QEMUMachine *m;
3446 cc1daa40 bellard
                    printf("Supported machines are:\n");
3447 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
3448 cc1daa40 bellard
                        printf("%-10s %s%s\n",
3449 cc1daa40 bellard
                               m->name, m->desc, 
3450 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
3451 cc1daa40 bellard
                    }
3452 cc1daa40 bellard
                    exit(1);
3453 cc1daa40 bellard
                }
3454 cc1daa40 bellard
                break;
3455 cd6f1169 bellard
            case QEMU_OPTION_initrd:
3456 fc01f7e7 bellard
                initrd_filename = optarg;
3457 fc01f7e7 bellard
                break;
3458 cd6f1169 bellard
            case QEMU_OPTION_hda:
3459 cd6f1169 bellard
            case QEMU_OPTION_hdb:
3460 cc1daa40 bellard
            case QEMU_OPTION_hdc:
3461 cc1daa40 bellard
            case QEMU_OPTION_hdd:
3462 cc1daa40 bellard
                {
3463 cc1daa40 bellard
                    int hd_index;
3464 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
3465 cc1daa40 bellard
                    hd_filename[hd_index] = optarg;
3466 cc1daa40 bellard
                    if (hd_index == cdrom_index)
3467 cc1daa40 bellard
                        cdrom_index = -1;
3468 cc1daa40 bellard
                }
3469 fc01f7e7 bellard
                break;
3470 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
3471 33e3963e bellard
                snapshot = 1;
3472 33e3963e bellard
                break;
3473 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
3474 330d0414 bellard
                {
3475 330d0414 bellard
                    const char *p;
3476 330d0414 bellard
                    p = optarg;
3477 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
3478 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
3479 46d4767d bellard
                        goto chs_fail;
3480 330d0414 bellard
                    if (*p != ',')
3481 330d0414 bellard
                        goto chs_fail;
3482 330d0414 bellard
                    p++;
3483 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
3484 46d4767d bellard
                    if (heads < 1 || heads > 16)
3485 46d4767d bellard
                        goto chs_fail;
3486 330d0414 bellard
                    if (*p != ',')
3487 330d0414 bellard
                        goto chs_fail;
3488 330d0414 bellard
                    p++;
3489 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
3490 46d4767d bellard
                    if (secs < 1 || secs > 63)
3491 46d4767d bellard
                        goto chs_fail;
3492 46d4767d bellard
                    if (*p == ',') {
3493 46d4767d bellard
                        p++;
3494 46d4767d bellard
                        if (!strcmp(p, "none"))
3495 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
3496 46d4767d bellard
                        else if (!strcmp(p, "lba"))
3497 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
3498 46d4767d bellard
                        else if (!strcmp(p, "auto"))
3499 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
3500 46d4767d bellard
                        else
3501 46d4767d bellard
                            goto chs_fail;
3502 46d4767d bellard
                    } else if (*p != '\0') {
3503 c4b1fcc0 bellard
                    chs_fail:
3504 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
3505 46d4767d bellard
                        exit(1);
3506 c4b1fcc0 bellard
                    }
3507 330d0414 bellard
                }
3508 330d0414 bellard
                break;
3509 cd6f1169 bellard
            case QEMU_OPTION_nographic:
3510 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
3511 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
3512 a20dd508 bellard
                nographic = 1;
3513 a20dd508 bellard
                break;
3514 cd6f1169 bellard
            case QEMU_OPTION_kernel:
3515 a20dd508 bellard
                kernel_filename = optarg;
3516 a20dd508 bellard
                break;
3517 cd6f1169 bellard
            case QEMU_OPTION_append:
3518 a20dd508 bellard
                kernel_cmdline = optarg;
3519 313aa567 bellard
                break;
3520 cd6f1169 bellard
            case QEMU_OPTION_tun_fd:
3521 c4b1fcc0 bellard
                {
3522 c4b1fcc0 bellard
                    const char *p;
3523 c4b1fcc0 bellard
                    int fd;
3524 d6b86f4d bellard
                    net_if_type = NET_IF_TUN;
3525 c20709aa bellard
                    if (nb_tun_fds < MAX_NICS) {
3526 c20709aa bellard
                        fd = strtol(optarg, (char **)&p, 0);
3527 c20709aa bellard
                        if (*p != '\0') {
3528 c20709aa bellard
                            fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
3529 c4b1fcc0 bellard
                            exit(1);
3530 c4b1fcc0 bellard
                        }
3531 c20709aa bellard
                        tun_fds[nb_tun_fds++] = fd;
3532 c4b1fcc0 bellard
                    }
3533 c4b1fcc0 bellard
                }
3534 42f1e0e4 bellard
                break;
3535 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
3536 cc1daa40 bellard
                if (cdrom_index >= 0) {
3537 cc1daa40 bellard
                    hd_filename[cdrom_index] = optarg;
3538 cc1daa40 bellard
                }
3539 36b486bb bellard
                break;
3540 cd6f1169 bellard
            case QEMU_OPTION_boot:
3541 36b486bb bellard
                boot_device = optarg[0];
3542 9e89a4be bellard
                if (boot_device != 'a' && 
3543 6f7e9aec bellard
#ifdef TARGET_SPARC
3544 6f7e9aec bellard
                    // Network boot
3545 6f7e9aec bellard
                    boot_device != 'n' &&
3546 6f7e9aec bellard
#endif
3547 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
3548 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
3549 36b486bb bellard
                    exit(1);
3550 36b486bb bellard
                }
3551 36b486bb bellard
                break;
3552 cd6f1169 bellard
            case QEMU_OPTION_fda:
3553 c45886db bellard
                fd_filename[0] = optarg;
3554 c45886db bellard
                break;
3555 cd6f1169 bellard
            case QEMU_OPTION_fdb:
3556 c45886db bellard
                fd_filename[1] = optarg;
3557 c45886db bellard
                break;
3558 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
3559 77fef8c1 bellard
                code_copy_enabled = 0;
3560 77fef8c1 bellard
                break;
3561 cd6f1169 bellard
            case QEMU_OPTION_nics:
3562 c4b1fcc0 bellard
                nb_nics = atoi(optarg);
3563 3a1bc175 bellard
                if (nb_nics < 0 || nb_nics > MAX_NICS) {
3564 c4b1fcc0 bellard
                    fprintf(stderr, "qemu: invalid number of network interfaces\n");
3565 c4b1fcc0 bellard
                    exit(1);
3566 c4b1fcc0 bellard
                }
3567 c4b1fcc0 bellard
                break;
3568 cd6f1169 bellard
            case QEMU_OPTION_macaddr:
3569 702c651c bellard
                {
3570 702c651c bellard
                    const char *p;
3571 702c651c bellard
                    int i;
3572 702c651c bellard
                    p = optarg;
3573 702c651c bellard
                    for(i = 0; i < 6; i++) {
3574 702c651c bellard
                        macaddr[i] = strtol(p, (char **)&p, 16);
3575 702c651c bellard
                        if (i == 5) {
3576 702c651c bellard
                            if (*p != '\0') 
3577 702c651c bellard
                                goto macaddr_error;
3578 702c651c bellard
                        } else {
3579 702c651c bellard
                            if (*p != ':') {
3580 702c651c bellard
                            macaddr_error:
3581 702c651c bellard
                                fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
3582 702c651c bellard
                                exit(1);
3583 702c651c bellard
                            }
3584 702c651c bellard
                            p++;
3585 702c651c bellard
                        }
3586 702c651c bellard
                    }
3587 702c651c bellard
                }
3588 702c651c bellard
                break;
3589 c7f74643 bellard
#ifdef CONFIG_SLIRP
3590 c7f74643 bellard
            case QEMU_OPTION_tftp:
3591 c7f74643 bellard
                tftp_prefix = optarg;
3592 9bf05444 bellard
                break;
3593 c94c8d64 bellard
#ifndef _WIN32
3594 9d728e8c bellard
            case QEMU_OPTION_smb:
3595 9d728e8c bellard
                net_slirp_smb(optarg);
3596 9d728e8c bellard
                break;
3597 c94c8d64 bellard
#endif
3598 cd6f1169 bellard
            case QEMU_OPTION_user_net:
3599 c20709aa bellard
                net_if_type = NET_IF_USER;
3600 c20709aa bellard
                break;
3601 9bf05444 bellard
            case QEMU_OPTION_redir:
3602 9bf05444 bellard
                net_slirp_redir(optarg);                
3603 9bf05444 bellard
                break;
3604 c7f74643 bellard
#endif
3605 cd6f1169 bellard
            case QEMU_OPTION_dummy_net:
3606 c20709aa bellard
                net_if_type = NET_IF_DUMMY;
3607 c20709aa bellard
                break;
3608 1d14ffa9 bellard
#ifdef HAS_AUDIO
3609 cd6f1169 bellard
            case QEMU_OPTION_enable_audio:
3610 aaaa7df6 bellard
                audio_enabled = 1;
3611 1d14ffa9 bellard
                sb16_enabled = 1;
3612 1d14ffa9 bellard
                adlib_enabled = 1;
3613 1d14ffa9 bellard
                gus_enabled = 1;
3614 1d14ffa9 bellard
                es1370_enabled = 1;
3615 aaaa7df6 bellard
                break;
3616 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
3617 1d14ffa9 bellard
                AUD_help ();
3618 1d14ffa9 bellard
                exit (0);
3619 1d14ffa9 bellard
                break;
3620 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
3621 1d14ffa9 bellard
                select_soundhw (optarg);
3622 1d14ffa9 bellard
                break;
3623 1d14ffa9 bellard
#endif
3624 cd6f1169 bellard
            case QEMU_OPTION_h:
3625 0824d6fc bellard
                help();
3626 cd6f1169 bellard
                break;
3627 cd6f1169 bellard
            case QEMU_OPTION_m:
3628 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
3629 cd6f1169 bellard
                if (ram_size <= 0)
3630 cd6f1169 bellard
                    help();
3631 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
3632 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
3633 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
3634 cd6f1169 bellard
                    exit(1);
3635 cd6f1169 bellard
                }
3636 cd6f1169 bellard
                break;
3637 cd6f1169 bellard
            case QEMU_OPTION_d:
3638 cd6f1169 bellard
                {
3639 cd6f1169 bellard
                    int mask;
3640 cd6f1169 bellard
                    CPULogItem *item;
3641 cd6f1169 bellard
                    
3642 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
3643 cd6f1169 bellard
                    if (!mask) {
3644 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
3645 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
3646 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
3647 f193c797 bellard
                    }
3648 f193c797 bellard
                    exit(1);
3649 cd6f1169 bellard
                    }
3650 cd6f1169 bellard
                    cpu_set_log(mask);
3651 f193c797 bellard
                }
3652 cd6f1169 bellard
                break;
3653 cd6f1169 bellard
            case QEMU_OPTION_n:
3654 cd6f1169 bellard
                pstrcpy(network_script, sizeof(network_script), optarg);
3655 cd6f1169 bellard
                break;
3656 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3657 cd6f1169 bellard
            case QEMU_OPTION_s:
3658 cd6f1169 bellard
                use_gdbstub = 1;
3659 cd6f1169 bellard
                break;
3660 cd6f1169 bellard
            case QEMU_OPTION_p:
3661 cd6f1169 bellard
                gdbstub_port = atoi(optarg);
3662 cd6f1169 bellard
                break;
3663 67b915a5 bellard
#endif
3664 cd6f1169 bellard
            case QEMU_OPTION_L:
3665 cd6f1169 bellard
                bios_dir = optarg;
3666 cd6f1169 bellard
                break;
3667 cd6f1169 bellard
            case QEMU_OPTION_S:
3668 cd6f1169 bellard
                start_emulation = 0;
3669 cd6f1169 bellard
                break;
3670 3d11d0eb bellard
            case QEMU_OPTION_k:
3671 3d11d0eb bellard
                keyboard_layout = optarg;
3672 3d11d0eb bellard
                break;
3673 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
3674 ee22c2f7 bellard
                rtc_utc = 0;
3675 ee22c2f7 bellard
                break;
3676 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
3677 1f04275e bellard
                cirrus_vga_enabled = 1;
3678 1f04275e bellard
                break;
3679 1bfe856e bellard
            case QEMU_OPTION_std_vga:
3680 1bfe856e bellard
                cirrus_vga_enabled = 0;
3681 1bfe856e bellard
                break;
3682 e9b137c2 bellard
            case QEMU_OPTION_g:
3683 e9b137c2 bellard
                {
3684 e9b137c2 bellard
                    const char *p;
3685 e9b137c2 bellard
                    int w, h, depth;
3686 e9b137c2 bellard
                    p = optarg;
3687 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
3688 e9b137c2 bellard
                    if (w <= 0) {
3689 e9b137c2 bellard
                    graphic_error:
3690 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
3691 e9b137c2 bellard
                        exit(1);
3692 e9b137c2 bellard
                    }
3693 e9b137c2 bellard
                    if (*p != 'x')
3694 e9b137c2 bellard
                        goto graphic_error;
3695 e9b137c2 bellard
                    p++;
3696 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
3697 e9b137c2 bellard
                    if (h <= 0)
3698 e9b137c2 bellard
                        goto graphic_error;
3699 e9b137c2 bellard
                    if (*p == 'x') {
3700 e9b137c2 bellard
                        p++;
3701 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
3702 e9b137c2 bellard
                        if (depth != 8 && depth != 15 && depth != 16 && 
3703 e9b137c2 bellard
                            depth != 24 && depth != 32)
3704 e9b137c2 bellard
                            goto graphic_error;
3705 e9b137c2 bellard
                    } else if (*p == '\0') {
3706 e9b137c2 bellard
                        depth = graphic_depth;
3707 e9b137c2 bellard
                    } else {
3708 e9b137c2 bellard
                        goto graphic_error;
3709 e9b137c2 bellard
                    }
3710 e9b137c2 bellard
                    
3711 e9b137c2 bellard
                    graphic_width = w;
3712 e9b137c2 bellard
                    graphic_height = h;
3713 e9b137c2 bellard
                    graphic_depth = depth;
3714 e9b137c2 bellard
                }
3715 e9b137c2 bellard
                break;
3716 82c643ff bellard
            case QEMU_OPTION_monitor:
3717 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
3718 82c643ff bellard
                break;
3719 82c643ff bellard
            case QEMU_OPTION_serial:
3720 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
3721 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
3722 8d11df9e bellard
                    exit(1);
3723 8d11df9e bellard
                }
3724 8d11df9e bellard
                pstrcpy(serial_devices[serial_device_index], 
3725 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
3726 8d11df9e bellard
                serial_device_index++;
3727 82c643ff bellard
                break;
3728 6508fe59 bellard
            case QEMU_OPTION_parallel:
3729 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
3730 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
3731 6508fe59 bellard
                    exit(1);
3732 6508fe59 bellard
                }
3733 6508fe59 bellard
                pstrcpy(parallel_devices[parallel_device_index], 
3734 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
3735 6508fe59 bellard
                parallel_device_index++;
3736 6508fe59 bellard
                break;
3737 d63d307f bellard
            case QEMU_OPTION_loadvm:
3738 d63d307f bellard
                loadvm = optarg;
3739 d63d307f bellard
                break;
3740 d63d307f bellard
            case QEMU_OPTION_full_screen:
3741 d63d307f bellard
                full_screen = 1;
3742 d63d307f bellard
                break;
3743 f7cce898 bellard
            case QEMU_OPTION_pidfile:
3744 f7cce898 bellard
                create_pidfile(optarg);
3745 f7cce898 bellard
                break;
3746 a09db21f bellard
#ifdef TARGET_I386
3747 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
3748 a09db21f bellard
                win2k_install_hack = 1;
3749 a09db21f bellard
                break;
3750 a09db21f bellard
#endif
3751 d993e026 bellard
#ifdef USE_KQEMU
3752 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
3753 d993e026 bellard
                kqemu_allowed = 0;
3754 d993e026 bellard
                break;
3755 d993e026 bellard
#endif
3756 bb36d470 bellard
            case QEMU_OPTION_usb:
3757 bb36d470 bellard
                usb_enabled = 1;
3758 bb36d470 bellard
                break;
3759 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
3760 a594cfbf bellard
                usb_enabled = 1;
3761 a594cfbf bellard
                if (usb_devices_index >= MAX_VM_USB_PORTS) {
3762 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
3763 a594cfbf bellard
                    exit(1);
3764 a594cfbf bellard
                }
3765 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
3766 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
3767 a594cfbf bellard
                        optarg);
3768 a594cfbf bellard
                usb_devices_index++;
3769 a594cfbf bellard
                break;
3770 cd6f1169 bellard
            }
3771 0824d6fc bellard
        }
3772 0824d6fc bellard
    }
3773 330d0414 bellard
3774 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
3775 330d0414 bellard
        
3776 cc1daa40 bellard
    if (!linux_boot && 
3777 cc1daa40 bellard
        hd_filename[0] == '\0' && 
3778 cc1daa40 bellard
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
3779 c45886db bellard
        fd_filename[0] == '\0')
3780 0824d6fc bellard
        help();
3781 8f2b1fb0 bellard
    
3782 8f2b1fb0 bellard
    /* boot to cd by default if no hard disk */
3783 d0309311 bellard
    if (hd_filename[0] == '\0' && boot_device == 'c') {
3784 d0309311 bellard
        if (fd_filename[0] != '\0')
3785 d0309311 bellard
            boot_device = 'a';
3786 d0309311 bellard
        else
3787 d0309311 bellard
            boot_device = 'd';
3788 d0309311 bellard
    }
3789 0824d6fc bellard
3790 dc887a4d bellard
#if !defined(CONFIG_SOFTMMU)
3791 dc887a4d bellard
    /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
3792 dc887a4d bellard
    {
3793 dc887a4d bellard
        static uint8_t stdout_buf[4096];
3794 dc887a4d bellard
        setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
3795 dc887a4d bellard
    }
3796 dc887a4d bellard
#else
3797 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
3798 dc887a4d bellard
#endif
3799 0824d6fc bellard
3800 c4b1fcc0 bellard
    /* init host network redirectors */
3801 c20709aa bellard
    if (net_if_type == -1) {
3802 c20709aa bellard
        net_if_type = NET_IF_TUN;
3803 c20709aa bellard
#if defined(CONFIG_SLIRP)
3804 c20709aa bellard
        if (access(network_script, R_OK) < 0) {
3805 c20709aa bellard
            net_if_type = NET_IF_USER;
3806 c20709aa bellard
        }
3807 c20709aa bellard
#endif
3808 c20709aa bellard
    }
3809 c20709aa bellard
3810 c20709aa bellard
    for(i = 0; i < nb_nics; i++) {
3811 702c651c bellard
        NetDriverState *nd = &nd_table[i];
3812 c20709aa bellard
        nd->index = i;
3813 702c651c bellard
        /* init virtual mac address */
3814 702c651c bellard
        nd->macaddr[0] = macaddr[0];
3815 702c651c bellard
        nd->macaddr[1] = macaddr[1];
3816 702c651c bellard
        nd->macaddr[2] = macaddr[2];
3817 702c651c bellard
        nd->macaddr[3] = macaddr[3];
3818 702c651c bellard
        nd->macaddr[4] = macaddr[4];
3819 702c651c bellard
        nd->macaddr[5] = macaddr[5] + i;
3820 c20709aa bellard
        switch(net_if_type) {
3821 c20709aa bellard
#if defined(CONFIG_SLIRP)
3822 c20709aa bellard
        case NET_IF_USER:
3823 c20709aa bellard
            net_slirp_init(nd);
3824 c20709aa bellard
            break;
3825 c20709aa bellard
#endif
3826 c20709aa bellard
#if !defined(_WIN32)
3827 c20709aa bellard
        case NET_IF_TUN:
3828 c20709aa bellard
            if (i < nb_tun_fds) {
3829 c20709aa bellard
                net_fd_init(nd, tun_fds[i]);
3830 c20709aa bellard
            } else {
3831 d927637d bellard
                if (net_tun_init(nd) < 0)
3832 d927637d bellard
                    net_dummy_init(nd);
3833 c20709aa bellard
            }
3834 c20709aa bellard
            break;
3835 c20709aa bellard
#endif
3836 c20709aa bellard
        case NET_IF_DUMMY:
3837 c20709aa bellard
        default:
3838 c20709aa bellard
            net_dummy_init(nd);
3839 c20709aa bellard
            break;
3840 c20709aa bellard
        }
3841 702c651c bellard
    }
3842 f1510b2c bellard
3843 0824d6fc bellard
    /* init the memory */
3844 0ced6589 bellard
    phys_ram_size = ram_size + vga_ram_size + bios_size;
3845 7f7f9873 bellard
3846 7f7f9873 bellard
#ifdef CONFIG_SOFTMMU
3847 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
3848 7f7f9873 bellard
    if (!phys_ram_base) {
3849 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
3850 0824d6fc bellard
        exit(1);
3851 0824d6fc bellard
    }
3852 7f7f9873 bellard
#else
3853 7f7f9873 bellard
    /* as we must map the same page at several addresses, we must use
3854 7f7f9873 bellard
       a fd */
3855 7f7f9873 bellard
    {
3856 7f7f9873 bellard
        const char *tmpdir;
3857 7f7f9873 bellard
3858 7f7f9873 bellard
        tmpdir = getenv("QEMU_TMPDIR");
3859 7f7f9873 bellard
        if (!tmpdir)
3860 7f7f9873 bellard
            tmpdir = "/tmp";
3861 7f7f9873 bellard
        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir);
3862 7f7f9873 bellard
        if (mkstemp(phys_ram_file) < 0) {
3863 7f7f9873 bellard
            fprintf(stderr, "Could not create temporary memory file '%s'\n", 
3864 7f7f9873 bellard
                    phys_ram_file);
3865 7f7f9873 bellard
            exit(1);
3866 7f7f9873 bellard
        }
3867 7f7f9873 bellard
        phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600);
3868 7f7f9873 bellard
        if (phys_ram_fd < 0) {
3869 7f7f9873 bellard
            fprintf(stderr, "Could not open temporary memory file '%s'\n", 
3870 7f7f9873 bellard
                    phys_ram_file);
3871 7f7f9873 bellard
            exit(1);
3872 7f7f9873 bellard
        }
3873 1ccde1cb bellard
        ftruncate(phys_ram_fd, phys_ram_size);
3874 7f7f9873 bellard
        unlink(phys_ram_file);
3875 1ccde1cb bellard
        phys_ram_base = mmap(get_mmap_addr(phys_ram_size), 
3876 1ccde1cb bellard
                             phys_ram_size, 
3877 7f7f9873 bellard
                             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, 
3878 7f7f9873 bellard
                             phys_ram_fd, 0);
3879 7f7f9873 bellard
        if (phys_ram_base == MAP_FAILED) {
3880 7f7f9873 bellard
            fprintf(stderr, "Could not map physical memory\n");
3881 7f7f9873 bellard
            exit(1);
3882 7f7f9873 bellard
        }
3883 7f7f9873 bellard
    }
3884 7f7f9873 bellard
#endif
3885 0824d6fc bellard
3886 c4b1fcc0 bellard
    /* we always create the cdrom drive, even if no disk is there */
3887 5905b2e5 bellard
    bdrv_init();
3888 cc1daa40 bellard
    if (cdrom_index >= 0) {
3889 cc1daa40 bellard
        bs_table[cdrom_index] = bdrv_new("cdrom");
3890 cc1daa40 bellard
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
3891 c4b1fcc0 bellard
    }
3892 c4b1fcc0 bellard
3893 33e3963e bellard
    /* open the virtual block devices */
3894 33e3963e bellard
    for(i = 0; i < MAX_DISKS; i++) {
3895 33e3963e bellard
        if (hd_filename[i]) {
3896 33e3963e bellard
            if (!bs_table[i]) {
3897 c4b1fcc0 bellard
                char buf[64];
3898 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
3899 c4b1fcc0 bellard
                bs_table[i] = bdrv_new(buf);
3900 c4b1fcc0 bellard
            }
3901 c4b1fcc0 bellard
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
3902 5905b2e5 bellard
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
3903 33e3963e bellard
                        hd_filename[i]);
3904 33e3963e bellard
                exit(1);
3905 33e3963e bellard
            }
3906 46d4767d bellard
            if (i == 0 && cyls != 0) {
3907 c4b1fcc0 bellard
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
3908 46d4767d bellard
                bdrv_set_translation_hint(bs_table[i], translation);
3909 46d4767d bellard
            }
3910 c4b1fcc0 bellard
        }
3911 c4b1fcc0 bellard
    }
3912 c4b1fcc0 bellard
3913 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
3914 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
3915 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
3916 c4b1fcc0 bellard
3917 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
3918 c4b1fcc0 bellard
        if (fd_filename[i]) {
3919 c4b1fcc0 bellard
            if (!fd_table[i]) {
3920 c4b1fcc0 bellard
                char buf[64];
3921 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
3922 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
3923 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
3924 c4b1fcc0 bellard
            }
3925 c4b1fcc0 bellard
            if (fd_filename[i] != '\0') {
3926 c4b1fcc0 bellard
                if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
3927 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
3928 c4b1fcc0 bellard
                            fd_filename[i]);
3929 c4b1fcc0 bellard
                    exit(1);
3930 c4b1fcc0 bellard
                }
3931 c4b1fcc0 bellard
            }
3932 33e3963e bellard
        }
3933 33e3963e bellard
    }
3934 33e3963e bellard
3935 a594cfbf bellard
    /* init USB devices */
3936 a594cfbf bellard
    if (usb_enabled) {
3937 a594cfbf bellard
        vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS);
3938 a594cfbf bellard
        for(i = 0; i < usb_devices_index; i++) {
3939 a594cfbf bellard
            if (usb_device_add(usb_devices[i]) < 0) {
3940 a594cfbf bellard
                fprintf(stderr, "Warning: could not add USB device %s\n",
3941 a594cfbf bellard
                        usb_devices[i]);
3942 a594cfbf bellard
            }
3943 a594cfbf bellard
        }
3944 a594cfbf bellard
    }
3945 a594cfbf bellard
3946 330d0414 bellard
    /* init CPU state */
3947 330d0414 bellard
    env = cpu_init();
3948 330d0414 bellard
    global_env = env;
3949 330d0414 bellard
    cpu_single_env = env;
3950 330d0414 bellard
3951 8a7ddc38 bellard
    register_savevm("timer", 0, 1, timer_save, timer_load, env);
3952 664e0f19 bellard
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
3953 8a7ddc38 bellard
    register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
3954 bb0c6722 bellard
    qemu_register_reset(main_cpu_reset, global_env);
3955 8a7ddc38 bellard
3956 330d0414 bellard
    init_ioports();
3957 80cabfad bellard
    cpu_calibrate_ticks();
3958 0824d6fc bellard
3959 313aa567 bellard
    /* terminal init */
3960 a20dd508 bellard
    if (nographic) {
3961 313aa567 bellard
        dumb_display_init(ds);
3962 313aa567 bellard
    } else {
3963 5b0753e0 bellard
#if defined(CONFIG_SDL)
3964 d63d307f bellard
        sdl_display_init(ds, full_screen);
3965 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
3966 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
3967 313aa567 bellard
#else
3968 313aa567 bellard
        dumb_display_init(ds);
3969 313aa567 bellard
#endif
3970 313aa567 bellard
    }
3971 0824d6fc bellard
3972 82c643ff bellard
    vga_console = graphic_console_init(ds);
3973 82c643ff bellard
    
3974 82c643ff bellard
    monitor_hd = qemu_chr_open(monitor_device);
3975 82c643ff bellard
    if (!monitor_hd) {
3976 82c643ff bellard
        fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
3977 82c643ff bellard
        exit(1);
3978 82c643ff bellard
    }
3979 82c643ff bellard
    monitor_init(monitor_hd, !nographic);
3980 82c643ff bellard
3981 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
3982 8d11df9e bellard
        if (serial_devices[i][0] != '\0') {
3983 8d11df9e bellard
            serial_hds[i] = qemu_chr_open(serial_devices[i]);
3984 8d11df9e bellard
            if (!serial_hds[i]) {
3985 8d11df9e bellard
                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
3986 8d11df9e bellard
                        serial_devices[i]);
3987 8d11df9e bellard
                exit(1);
3988 8d11df9e bellard
            }
3989 8d11df9e bellard
            if (!strcmp(serial_devices[i], "vc"))
3990 8d11df9e bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
3991 8d11df9e bellard
        }
3992 82c643ff bellard
    }
3993 82c643ff bellard
3994 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
3995 6508fe59 bellard
        if (parallel_devices[i][0] != '\0') {
3996 6508fe59 bellard
            parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
3997 6508fe59 bellard
            if (!parallel_hds[i]) {
3998 6508fe59 bellard
                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
3999 6508fe59 bellard
                        parallel_devices[i]);
4000 6508fe59 bellard
                exit(1);
4001 6508fe59 bellard
            }
4002 6508fe59 bellard
            if (!strcmp(parallel_devices[i], "vc"))
4003 6508fe59 bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\n", i);
4004 6508fe59 bellard
        }
4005 6508fe59 bellard
    }
4006 6508fe59 bellard
4007 0824d6fc bellard
    /* setup cpu signal handlers for MMU / self modifying code handling */
4008 77fef8c1 bellard
#if !defined(CONFIG_SOFTMMU)
4009 8a7ddc38 bellard
    
4010 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
4011 77fef8c1 bellard
    {
4012 77fef8c1 bellard
        stack_t stk;
4013 73332e5c bellard
        signal_stack = memalign(16, SIGNAL_STACK_SIZE);
4014 77fef8c1 bellard
        stk.ss_sp = signal_stack;
4015 77fef8c1 bellard
        stk.ss_size = SIGNAL_STACK_SIZE;
4016 77fef8c1 bellard
        stk.ss_flags = 0;
4017 77fef8c1 bellard
4018 77fef8c1 bellard
        if (sigaltstack(&stk, NULL) < 0) {
4019 77fef8c1 bellard
            perror("sigaltstack");
4020 77fef8c1 bellard
            exit(1);
4021 77fef8c1 bellard
        }
4022 77fef8c1 bellard
    }
4023 77fef8c1 bellard
#endif
4024 8a7ddc38 bellard
    {
4025 8a7ddc38 bellard
        struct sigaction act;
4026 77fef8c1 bellard
        
4027 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
4028 8a7ddc38 bellard
        act.sa_flags = SA_SIGINFO;
4029 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
4030 8a7ddc38 bellard
        act.sa_flags |= SA_ONSTACK;
4031 77fef8c1 bellard
#endif
4032 8a7ddc38 bellard
        act.sa_sigaction = host_segv_handler;
4033 8a7ddc38 bellard
        sigaction(SIGSEGV, &act, NULL);
4034 8a7ddc38 bellard
        sigaction(SIGBUS, &act, NULL);
4035 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
4036 8a7ddc38 bellard
        sigaction(SIGFPE, &act, NULL);
4037 77fef8c1 bellard
#endif
4038 8a7ddc38 bellard
    }
4039 3a51dee6 bellard
#endif
4040 0824d6fc bellard
4041 67b915a5 bellard
#ifndef _WIN32
4042 8a7ddc38 bellard
    {
4043 8a7ddc38 bellard
        struct sigaction act;
4044 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
4045 8a7ddc38 bellard
        act.sa_flags = 0;
4046 8a7ddc38 bellard
        act.sa_handler = SIG_IGN;
4047 8a7ddc38 bellard
        sigaction(SIGPIPE, &act, NULL);
4048 8a7ddc38 bellard
    }
4049 67b915a5 bellard
#endif
4050 73332e5c bellard
    init_timers();
4051 73332e5c bellard
4052 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
4053 cc1daa40 bellard
                  ds, fd_filename, snapshot,
4054 cc1daa40 bellard
                  kernel_filename, kernel_cmdline, initrd_filename);
4055 73332e5c bellard
4056 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
4057 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
4058 7f7f9873 bellard
4059 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
4060 b4608c04 bellard
    if (use_gdbstub) {
4061 8a7ddc38 bellard
        if (gdbserver_start(gdbstub_port) < 0) {
4062 8a7ddc38 bellard
            fprintf(stderr, "Could not open gdbserver socket on port %d\n", 
4063 8a7ddc38 bellard
                    gdbstub_port);
4064 8a7ddc38 bellard
            exit(1);
4065 8a7ddc38 bellard
        } else {
4066 8a7ddc38 bellard
            printf("Waiting gdb connection on port %d\n", gdbstub_port);
4067 8a7ddc38 bellard
        }
4068 67b915a5 bellard
    } else 
4069 67b915a5 bellard
#endif
4070 d63d307f bellard
    if (loadvm)
4071 d63d307f bellard
        qemu_loadvm(loadvm);
4072 d63d307f bellard
4073 67b915a5 bellard
    {
4074 5905b2e5 bellard
        /* XXX: simplify init */
4075 5905b2e5 bellard
        read_passwords();
4076 5905b2e5 bellard
        if (start_emulation) {
4077 5905b2e5 bellard
            vm_start();
4078 5905b2e5 bellard
        }
4079 0824d6fc bellard
    }
4080 8a7ddc38 bellard
    main_loop();
4081 40c3bac3 bellard
    quit_timers();
4082 0824d6fc bellard
    return 0;
4083 0824d6fc bellard
}