Statistics
| Branch: | Revision:

root / vl.c @ 157777ef

History | View | Annotate | Download (96.4 kB)

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