Statistics
| Branch: | Revision:

root / vl.c @ 0443eaf6

History | View | Annotate | Download (96.3 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 9d728e8c bellard
            "pid directory=%s\n"
1542 9d728e8c bellard
            "lock directory=%s\n"
1543 9d728e8c bellard
            "log file=%s/log.smbd\n"
1544 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
1545 03ffbb69 bellard
            "security = share\n"
1546 9d728e8c bellard
            "[qemu]\n"
1547 9d728e8c bellard
            "path=%s\n"
1548 9d728e8c bellard
            "read only=no\n"
1549 9d728e8c bellard
            "guest ok=yes\n",
1550 9d728e8c bellard
            smb_dir,
1551 9d728e8c bellard
            smb_dir,
1552 9d728e8c bellard
            smb_dir,
1553 9d728e8c bellard
            smb_dir,
1554 9d728e8c bellard
            exported_dir
1555 9d728e8c bellard
            );
1556 9d728e8c bellard
    fclose(f);
1557 9d728e8c bellard
    atexit(smb_exit);
1558 9d728e8c bellard
1559 9d728e8c bellard
    snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
1560 9d728e8c bellard
             smb_conf);
1561 9d728e8c bellard
    
1562 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
1563 9d728e8c bellard
}
1564 9bf05444 bellard
1565 c94c8d64 bellard
#endif /* !defined(_WIN32) */
1566 c94c8d64 bellard
1567 c20709aa bellard
#endif /* CONFIG_SLIRP */
1568 c20709aa bellard
1569 c20709aa bellard
#if !defined(_WIN32)
1570 7d3505c5 bellard
#ifdef _BSD
1571 7d3505c5 bellard
static int tun_open(char *ifname, int ifname_size)
1572 7d3505c5 bellard
{
1573 7d3505c5 bellard
    int fd;
1574 7d3505c5 bellard
    char *dev;
1575 7d3505c5 bellard
    struct stat s;
1576 67b915a5 bellard
1577 7d3505c5 bellard
    fd = open("/dev/tap", O_RDWR);
1578 7d3505c5 bellard
    if (fd < 0) {
1579 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
1580 7d3505c5 bellard
        return -1;
1581 7d3505c5 bellard
    }
1582 7d3505c5 bellard
1583 7d3505c5 bellard
    fstat(fd, &s);
1584 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
1585 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
1586 7d3505c5 bellard
1587 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1588 7d3505c5 bellard
    return fd;
1589 7d3505c5 bellard
}
1590 7d3505c5 bellard
#else
1591 c4b1fcc0 bellard
static int tun_open(char *ifname, int ifname_size)
1592 330d0414 bellard
{
1593 80cabfad bellard
    struct ifreq ifr;
1594 c4b1fcc0 bellard
    int fd, ret;
1595 80cabfad bellard
    
1596 80cabfad bellard
    fd = open("/dev/net/tun", O_RDWR);
1597 80cabfad bellard
    if (fd < 0) {
1598 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1599 80cabfad bellard
        return -1;
1600 330d0414 bellard
    }
1601 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
1602 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1603 80cabfad bellard
    pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1604 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1605 80cabfad bellard
    if (ret != 0) {
1606 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1607 80cabfad bellard
        close(fd);
1608 80cabfad bellard
        return -1;
1609 80cabfad bellard
    }
1610 80cabfad bellard
    printf("Connected to host network interface: %s\n", ifr.ifr_name);
1611 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
1612 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1613 c4b1fcc0 bellard
    return fd;
1614 c4b1fcc0 bellard
}
1615 7d3505c5 bellard
#endif
1616 330d0414 bellard
1617 c20709aa bellard
static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1618 c20709aa bellard
{
1619 c20709aa bellard
    write(nd->fd, buf, size);
1620 c20709aa bellard
}
1621 c20709aa bellard
1622 c20709aa bellard
static void tun_add_read_packet(NetDriverState *nd, 
1623 c20709aa bellard
                                IOCanRWHandler *fd_can_read, 
1624 c20709aa bellard
                                IOReadHandler *fd_read, void *opaque)
1625 c4b1fcc0 bellard
{
1626 c20709aa bellard
    qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
1627 c20709aa bellard
}
1628 c20709aa bellard
1629 c20709aa bellard
static int net_tun_init(NetDriverState *nd)
1630 c20709aa bellard
{
1631 c20709aa bellard
    int pid, status;
1632 c20709aa bellard
    char *args[3];
1633 c4b1fcc0 bellard
    char **parg;
1634 c4b1fcc0 bellard
1635 c20709aa bellard
    nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
1636 c20709aa bellard
    if (nd->fd < 0)
1637 c20709aa bellard
        return -1;
1638 c4b1fcc0 bellard
1639 c20709aa bellard
    /* try to launch network init script */
1640 c20709aa bellard
    pid = fork();
1641 c20709aa bellard
    if (pid >= 0) {
1642 c20709aa bellard
        if (pid == 0) {
1643 c20709aa bellard
            parg = args;
1644 c20709aa bellard
            *parg++ = network_script;
1645 c20709aa bellard
            *parg++ = nd->ifname;
1646 c20709aa bellard
            *parg++ = NULL;
1647 c20709aa bellard
            execv(network_script, args);
1648 c20709aa bellard
            exit(1);
1649 c20709aa bellard
        }
1650 c20709aa bellard
        while (waitpid(pid, &status, 0) != pid);
1651 c20709aa bellard
        if (!WIFEXITED(status) ||
1652 c20709aa bellard
            WEXITSTATUS(status) != 0) {
1653 c20709aa bellard
            fprintf(stderr, "%s: could not launch network script\n",
1654 c20709aa bellard
                    network_script);
1655 80cabfad bellard
        }
1656 330d0414 bellard
    }
1657 c20709aa bellard
    nd->send_packet = tun_send_packet;
1658 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1659 80cabfad bellard
    return 0;
1660 330d0414 bellard
}
1661 330d0414 bellard
1662 c20709aa bellard
static int net_fd_init(NetDriverState *nd, int fd)
1663 330d0414 bellard
{
1664 c20709aa bellard
    nd->fd = fd;
1665 c20709aa bellard
    nd->send_packet = tun_send_packet;
1666 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1667 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
1668 c20709aa bellard
    return 0;
1669 80cabfad bellard
}
1670 330d0414 bellard
1671 c20709aa bellard
#endif /* !_WIN32 */
1672 67b915a5 bellard
1673 330d0414 bellard
/***********************************************************/
1674 f7cce898 bellard
/* pid file */
1675 f7cce898 bellard
1676 f7cce898 bellard
static char *pid_filename;
1677 f7cce898 bellard
1678 f7cce898 bellard
/* Remove PID file. Called on normal exit */
1679 f7cce898 bellard
1680 f7cce898 bellard
static void remove_pidfile(void) 
1681 f7cce898 bellard
{
1682 f7cce898 bellard
    unlink (pid_filename);
1683 f7cce898 bellard
}
1684 f7cce898 bellard
1685 f7cce898 bellard
static void create_pidfile(const char *filename)
1686 f7cce898 bellard
{
1687 f7cce898 bellard
    struct stat pidstat;
1688 f7cce898 bellard
    FILE *f;
1689 f7cce898 bellard
1690 f7cce898 bellard
    /* Try to write our PID to the named file */
1691 f7cce898 bellard
    if (stat(filename, &pidstat) < 0) {
1692 f7cce898 bellard
        if (errno == ENOENT) {
1693 f7cce898 bellard
            if ((f = fopen (filename, "w")) == NULL) {
1694 f7cce898 bellard
                perror("Opening pidfile");
1695 f7cce898 bellard
                exit(1);
1696 f7cce898 bellard
            }
1697 f7cce898 bellard
            fprintf(f, "%d\n", getpid());
1698 f7cce898 bellard
            fclose(f);
1699 f7cce898 bellard
            pid_filename = qemu_strdup(filename);
1700 f7cce898 bellard
            if (!pid_filename) {
1701 f7cce898 bellard
                fprintf(stderr, "Could not save PID filename");
1702 f7cce898 bellard
                exit(1);
1703 f7cce898 bellard
            }
1704 f7cce898 bellard
            atexit(remove_pidfile);
1705 f7cce898 bellard
        }
1706 f7cce898 bellard
    } else {
1707 f7cce898 bellard
        fprintf(stderr, "%s already exists. Remove it and try again.\n", 
1708 f7cce898 bellard
                filename);
1709 f7cce898 bellard
        exit(1);
1710 f7cce898 bellard
    }
1711 f7cce898 bellard
}
1712 f7cce898 bellard
1713 f7cce898 bellard
/***********************************************************/
1714 313aa567 bellard
/* dumb display */
1715 313aa567 bellard
1716 313aa567 bellard
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
1717 313aa567 bellard
{
1718 313aa567 bellard
}
1719 313aa567 bellard
1720 313aa567 bellard
static void dumb_resize(DisplayState *ds, int w, int h)
1721 313aa567 bellard
{
1722 313aa567 bellard
}
1723 313aa567 bellard
1724 313aa567 bellard
static void dumb_refresh(DisplayState *ds)
1725 313aa567 bellard
{
1726 313aa567 bellard
    vga_update_display();
1727 313aa567 bellard
}
1728 313aa567 bellard
1729 313aa567 bellard
void dumb_display_init(DisplayState *ds)
1730 313aa567 bellard
{
1731 313aa567 bellard
    ds->data = NULL;
1732 313aa567 bellard
    ds->linesize = 0;
1733 313aa567 bellard
    ds->depth = 0;
1734 313aa567 bellard
    ds->dpy_update = dumb_update;
1735 313aa567 bellard
    ds->dpy_resize = dumb_resize;
1736 313aa567 bellard
    ds->dpy_refresh = dumb_refresh;
1737 313aa567 bellard
}
1738 313aa567 bellard
1739 3a51dee6 bellard
#if !defined(CONFIG_SOFTMMU)
1740 313aa567 bellard
/***********************************************************/
1741 0824d6fc bellard
/* cpu signal handler */
1742 0824d6fc bellard
static void host_segv_handler(int host_signum, siginfo_t *info, 
1743 0824d6fc bellard
                              void *puc)
1744 0824d6fc bellard
{
1745 0824d6fc bellard
    if (cpu_signal_handler(host_signum, info, puc))
1746 0824d6fc bellard
        return;
1747 8d11df9e bellard
    if (stdio_nb_clients > 0)
1748 8d11df9e bellard
        term_exit();
1749 0824d6fc bellard
    abort();
1750 0824d6fc bellard
}
1751 3a51dee6 bellard
#endif
1752 0824d6fc bellard
1753 8a7ddc38 bellard
/***********************************************************/
1754 8a7ddc38 bellard
/* I/O handling */
1755 0824d6fc bellard
1756 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
1757 c4b1fcc0 bellard
1758 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
1759 c4b1fcc0 bellard
    int fd;
1760 c4b1fcc0 bellard
    IOCanRWHandler *fd_can_read;
1761 c4b1fcc0 bellard
    IOReadHandler *fd_read;
1762 c4b1fcc0 bellard
    void *opaque;
1763 c4b1fcc0 bellard
    /* temporary data */
1764 c4b1fcc0 bellard
    struct pollfd *ufd;
1765 c4b1fcc0 bellard
    int max_size;
1766 8a7ddc38 bellard
    struct IOHandlerRecord *next;
1767 c4b1fcc0 bellard
} IOHandlerRecord;
1768 c4b1fcc0 bellard
1769 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
1770 c4b1fcc0 bellard
1771 8a7ddc38 bellard
int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
1772 8a7ddc38 bellard
                             IOReadHandler *fd_read, void *opaque)
1773 c4b1fcc0 bellard
{
1774 c4b1fcc0 bellard
    IOHandlerRecord *ioh;
1775 c4b1fcc0 bellard
1776 8a7ddc38 bellard
    ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1777 8a7ddc38 bellard
    if (!ioh)
1778 c4b1fcc0 bellard
        return -1;
1779 c4b1fcc0 bellard
    ioh->fd = fd;
1780 c4b1fcc0 bellard
    ioh->fd_can_read = fd_can_read;
1781 c4b1fcc0 bellard
    ioh->fd_read = fd_read;
1782 c4b1fcc0 bellard
    ioh->opaque = opaque;
1783 8a7ddc38 bellard
    ioh->next = first_io_handler;
1784 8a7ddc38 bellard
    first_io_handler = ioh;
1785 c4b1fcc0 bellard
    return 0;
1786 c4b1fcc0 bellard
}
1787 c4b1fcc0 bellard
1788 8a7ddc38 bellard
void qemu_del_fd_read_handler(int fd)
1789 8a7ddc38 bellard
{
1790 8a7ddc38 bellard
    IOHandlerRecord **pioh, *ioh;
1791 b4608c04 bellard
1792 8a7ddc38 bellard
    pioh = &first_io_handler;
1793 8a7ddc38 bellard
    for(;;) {
1794 8a7ddc38 bellard
        ioh = *pioh;
1795 8a7ddc38 bellard
        if (ioh == NULL)
1796 8a7ddc38 bellard
            break;
1797 8a7ddc38 bellard
        if (ioh->fd == fd) {
1798 8a7ddc38 bellard
            *pioh = ioh->next;
1799 8a7ddc38 bellard
            break;
1800 8a7ddc38 bellard
        }
1801 8a7ddc38 bellard
        pioh = &ioh->next;
1802 8a7ddc38 bellard
    }
1803 8a7ddc38 bellard
}
1804 8a7ddc38 bellard
1805 8a7ddc38 bellard
/***********************************************************/
1806 8a7ddc38 bellard
/* savevm/loadvm support */
1807 8a7ddc38 bellard
1808 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
1809 b4608c04 bellard
{
1810 8a7ddc38 bellard
    fwrite(buf, 1, size, f);
1811 b4608c04 bellard
}
1812 b4608c04 bellard
1813 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
1814 b4608c04 bellard
{
1815 8a7ddc38 bellard
    fputc(v, f);
1816 8a7ddc38 bellard
}
1817 8a7ddc38 bellard
1818 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
1819 8a7ddc38 bellard
{
1820 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
1821 8a7ddc38 bellard
    qemu_put_byte(f, v);
1822 8a7ddc38 bellard
}
1823 8a7ddc38 bellard
1824 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
1825 8a7ddc38 bellard
{
1826 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
1827 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
1828 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
1829 8a7ddc38 bellard
    qemu_put_byte(f, v);
1830 8a7ddc38 bellard
}
1831 8a7ddc38 bellard
1832 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
1833 8a7ddc38 bellard
{
1834 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
1835 8a7ddc38 bellard
    qemu_put_be32(f, v);
1836 8a7ddc38 bellard
}
1837 8a7ddc38 bellard
1838 8a7ddc38 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
1839 8a7ddc38 bellard
{
1840 8a7ddc38 bellard
    return fread(buf, 1, size, f);
1841 8a7ddc38 bellard
}
1842 8a7ddc38 bellard
1843 8a7ddc38 bellard
int qemu_get_byte(QEMUFile *f)
1844 8a7ddc38 bellard
{
1845 8a7ddc38 bellard
    int v;
1846 8a7ddc38 bellard
    v = fgetc(f);
1847 8a7ddc38 bellard
    if (v == EOF)
1848 8a7ddc38 bellard
        return 0;
1849 8a7ddc38 bellard
    else
1850 8a7ddc38 bellard
        return v;
1851 8a7ddc38 bellard
}
1852 8a7ddc38 bellard
1853 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
1854 8a7ddc38 bellard
{
1855 8a7ddc38 bellard
    unsigned int v;
1856 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
1857 8a7ddc38 bellard
    v |= qemu_get_byte(f);
1858 8a7ddc38 bellard
    return v;
1859 8a7ddc38 bellard
}
1860 8a7ddc38 bellard
1861 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
1862 8a7ddc38 bellard
{
1863 8a7ddc38 bellard
    unsigned int v;
1864 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
1865 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
1866 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
1867 8a7ddc38 bellard
    v |= qemu_get_byte(f);
1868 8a7ddc38 bellard
    return v;
1869 8a7ddc38 bellard
}
1870 8a7ddc38 bellard
1871 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
1872 8a7ddc38 bellard
{
1873 8a7ddc38 bellard
    uint64_t v;
1874 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
1875 8a7ddc38 bellard
    v |= qemu_get_be32(f);
1876 8a7ddc38 bellard
    return v;
1877 8a7ddc38 bellard
}
1878 8a7ddc38 bellard
1879 8a7ddc38 bellard
int64_t qemu_ftell(QEMUFile *f)
1880 8a7ddc38 bellard
{
1881 8a7ddc38 bellard
    return ftell(f);
1882 8a7ddc38 bellard
}
1883 8a7ddc38 bellard
1884 8a7ddc38 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
1885 8a7ddc38 bellard
{
1886 8a7ddc38 bellard
    if (fseek(f, pos, whence) < 0)
1887 8a7ddc38 bellard
        return -1;
1888 8a7ddc38 bellard
    return ftell(f);
1889 8a7ddc38 bellard
}
1890 8a7ddc38 bellard
1891 8a7ddc38 bellard
typedef struct SaveStateEntry {
1892 8a7ddc38 bellard
    char idstr[256];
1893 8a7ddc38 bellard
    int instance_id;
1894 8a7ddc38 bellard
    int version_id;
1895 8a7ddc38 bellard
    SaveStateHandler *save_state;
1896 8a7ddc38 bellard
    LoadStateHandler *load_state;
1897 8a7ddc38 bellard
    void *opaque;
1898 8a7ddc38 bellard
    struct SaveStateEntry *next;
1899 8a7ddc38 bellard
} SaveStateEntry;
1900 b4608c04 bellard
1901 8a7ddc38 bellard
static SaveStateEntry *first_se;
1902 8a7ddc38 bellard
1903 8a7ddc38 bellard
int register_savevm(const char *idstr, 
1904 8a7ddc38 bellard
                    int instance_id, 
1905 8a7ddc38 bellard
                    int version_id,
1906 8a7ddc38 bellard
                    SaveStateHandler *save_state,
1907 8a7ddc38 bellard
                    LoadStateHandler *load_state,
1908 8a7ddc38 bellard
                    void *opaque)
1909 8a7ddc38 bellard
{
1910 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
1911 8a7ddc38 bellard
1912 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
1913 8a7ddc38 bellard
    if (!se)
1914 8a7ddc38 bellard
        return -1;
1915 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1916 8a7ddc38 bellard
    se->instance_id = instance_id;
1917 8a7ddc38 bellard
    se->version_id = version_id;
1918 8a7ddc38 bellard
    se->save_state = save_state;
1919 8a7ddc38 bellard
    se->load_state = load_state;
1920 8a7ddc38 bellard
    se->opaque = opaque;
1921 8a7ddc38 bellard
    se->next = NULL;
1922 8a7ddc38 bellard
1923 8a7ddc38 bellard
    /* add at the end of list */
1924 8a7ddc38 bellard
    pse = &first_se;
1925 8a7ddc38 bellard
    while (*pse != NULL)
1926 8a7ddc38 bellard
        pse = &(*pse)->next;
1927 8a7ddc38 bellard
    *pse = se;
1928 8a7ddc38 bellard
    return 0;
1929 8a7ddc38 bellard
}
1930 8a7ddc38 bellard
1931 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
1932 8a7ddc38 bellard
#define QEMU_VM_FILE_VERSION 0x00000001
1933 8a7ddc38 bellard
1934 8a7ddc38 bellard
int qemu_savevm(const char *filename)
1935 8a7ddc38 bellard
{
1936 8a7ddc38 bellard
    SaveStateEntry *se;
1937 8a7ddc38 bellard
    QEMUFile *f;
1938 8a7ddc38 bellard
    int len, len_pos, cur_pos, saved_vm_running, ret;
1939 8a7ddc38 bellard
1940 8a7ddc38 bellard
    saved_vm_running = vm_running;
1941 8a7ddc38 bellard
    vm_stop(0);
1942 8a7ddc38 bellard
1943 8a7ddc38 bellard
    f = fopen(filename, "wb");
1944 8a7ddc38 bellard
    if (!f) {
1945 8a7ddc38 bellard
        ret = -1;
1946 8a7ddc38 bellard
        goto the_end;
1947 313aa567 bellard
    }
1948 313aa567 bellard
1949 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1950 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1951 8a7ddc38 bellard
1952 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
1953 8a7ddc38 bellard
        /* ID string */
1954 8a7ddc38 bellard
        len = strlen(se->idstr);
1955 8a7ddc38 bellard
        qemu_put_byte(f, len);
1956 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
1957 8a7ddc38 bellard
1958 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
1959 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
1960 8a7ddc38 bellard
1961 8a7ddc38 bellard
        /* record size: filled later */
1962 8a7ddc38 bellard
        len_pos = ftell(f);
1963 8a7ddc38 bellard
        qemu_put_be32(f, 0);
1964 8a7ddc38 bellard
        
1965 8a7ddc38 bellard
        se->save_state(f, se->opaque);
1966 8a7ddc38 bellard
1967 8a7ddc38 bellard
        /* fill record size */
1968 8a7ddc38 bellard
        cur_pos = ftell(f);
1969 8a7ddc38 bellard
        len = ftell(f) - len_pos - 4;
1970 8a7ddc38 bellard
        fseek(f, len_pos, SEEK_SET);
1971 8a7ddc38 bellard
        qemu_put_be32(f, len);
1972 8a7ddc38 bellard
        fseek(f, cur_pos, SEEK_SET);
1973 8a7ddc38 bellard
    }
1974 8a7ddc38 bellard
1975 8a7ddc38 bellard
    fclose(f);
1976 8a7ddc38 bellard
    ret = 0;
1977 8a7ddc38 bellard
 the_end:
1978 8a7ddc38 bellard
    if (saved_vm_running)
1979 8a7ddc38 bellard
        vm_start();
1980 8a7ddc38 bellard
    return ret;
1981 8a7ddc38 bellard
}
1982 8a7ddc38 bellard
1983 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
1984 8a7ddc38 bellard
{
1985 8a7ddc38 bellard
    SaveStateEntry *se;
1986 8a7ddc38 bellard
1987 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
1988 8a7ddc38 bellard
        if (!strcmp(se->idstr, idstr) && 
1989 8a7ddc38 bellard
            instance_id == se->instance_id)
1990 8a7ddc38 bellard
            return se;
1991 8a7ddc38 bellard
    }
1992 8a7ddc38 bellard
    return NULL;
1993 8a7ddc38 bellard
}
1994 8a7ddc38 bellard
1995 8a7ddc38 bellard
int qemu_loadvm(const char *filename)
1996 8a7ddc38 bellard
{
1997 8a7ddc38 bellard
    SaveStateEntry *se;
1998 8a7ddc38 bellard
    QEMUFile *f;
1999 8a7ddc38 bellard
    int len, cur_pos, ret, instance_id, record_len, version_id;
2000 8a7ddc38 bellard
    int saved_vm_running;
2001 8a7ddc38 bellard
    unsigned int v;
2002 8a7ddc38 bellard
    char idstr[256];
2003 8a7ddc38 bellard
    
2004 8a7ddc38 bellard
    saved_vm_running = vm_running;
2005 8a7ddc38 bellard
    vm_stop(0);
2006 8a7ddc38 bellard
2007 8a7ddc38 bellard
    f = fopen(filename, "rb");
2008 8a7ddc38 bellard
    if (!f) {
2009 8a7ddc38 bellard
        ret = -1;
2010 8a7ddc38 bellard
        goto the_end;
2011 8a7ddc38 bellard
    }
2012 8a7ddc38 bellard
2013 8a7ddc38 bellard
    v = qemu_get_be32(f);
2014 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
2015 8a7ddc38 bellard
        goto fail;
2016 8a7ddc38 bellard
    v = qemu_get_be32(f);
2017 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
2018 8a7ddc38 bellard
    fail:
2019 8a7ddc38 bellard
        fclose(f);
2020 8a7ddc38 bellard
        ret = -1;
2021 8a7ddc38 bellard
        goto the_end;
2022 8a7ddc38 bellard
    }
2023 b4608c04 bellard
    for(;;) {
2024 a541f297 bellard
#if defined (DO_TB_FLUSH)
2025 d927637d bellard
        tb_flush(global_env);
2026 a541f297 bellard
#endif
2027 8a7ddc38 bellard
        len = qemu_get_byte(f);
2028 8a7ddc38 bellard
        if (feof(f))
2029 cd4c3e88 bellard
            break;
2030 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
2031 8a7ddc38 bellard
        idstr[len] = '\0';
2032 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
2033 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
2034 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
2035 8a7ddc38 bellard
#if 0
2036 8a7ddc38 bellard
        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
2037 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
2038 8a7ddc38 bellard
#endif
2039 8a7ddc38 bellard
        cur_pos = ftell(f);
2040 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
2041 8a7ddc38 bellard
        if (!se) {
2042 8a7ddc38 bellard
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
2043 8a7ddc38 bellard
                    instance_id, idstr);
2044 8a7ddc38 bellard
        } else {
2045 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
2046 8a7ddc38 bellard
            if (ret < 0) {
2047 8a7ddc38 bellard
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
2048 8a7ddc38 bellard
                        instance_id, idstr);
2049 8a7ddc38 bellard
            }
2050 34865134 bellard
        }
2051 8a7ddc38 bellard
        /* always seek to exact end of record */
2052 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
2053 8a7ddc38 bellard
    }
2054 8a7ddc38 bellard
    fclose(f);
2055 8a7ddc38 bellard
    ret = 0;
2056 8a7ddc38 bellard
 the_end:
2057 8a7ddc38 bellard
    if (saved_vm_running)
2058 8a7ddc38 bellard
        vm_start();
2059 8a7ddc38 bellard
    return ret;
2060 8a7ddc38 bellard
}
2061 8a7ddc38 bellard
2062 8a7ddc38 bellard
/***********************************************************/
2063 8a7ddc38 bellard
/* cpu save/restore */
2064 8a7ddc38 bellard
2065 8a7ddc38 bellard
#if defined(TARGET_I386)
2066 8a7ddc38 bellard
2067 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
2068 8a7ddc38 bellard
{
2069 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
2070 20f32282 bellard
    qemu_put_betl(f, dt->base);
2071 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
2072 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
2073 8a7ddc38 bellard
}
2074 8a7ddc38 bellard
2075 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
2076 8a7ddc38 bellard
{
2077 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
2078 20f32282 bellard
    dt->base = qemu_get_betl(f);
2079 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
2080 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
2081 8a7ddc38 bellard
}
2082 8a7ddc38 bellard
2083 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
2084 8a7ddc38 bellard
{
2085 8a7ddc38 bellard
    CPUState *env = opaque;
2086 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
2087 8a7ddc38 bellard
    uint32_t hflags;
2088 8a7ddc38 bellard
    int i;
2089 664e0f19 bellard
    
2090 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
2091 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
2092 20f32282 bellard
    qemu_put_betls(f, &env->eip);
2093 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
2094 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
2095 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
2096 8a7ddc38 bellard
    
2097 8a7ddc38 bellard
    /* FPU */
2098 8a7ddc38 bellard
    fpuc = env->fpuc;
2099 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2100 8a7ddc38 bellard
    fptag = 0;
2101 664e0f19 bellard
    for(i = 0; i < 8; i++) {
2102 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
2103 8a7ddc38 bellard
    }
2104 8a7ddc38 bellard
    
2105 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
2106 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
2107 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
2108 8a7ddc38 bellard
2109 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2110 664e0f19 bellard
    fpregs_format = 0;
2111 664e0f19 bellard
#else
2112 664e0f19 bellard
    fpregs_format = 1;
2113 664e0f19 bellard
#endif
2114 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
2115 664e0f19 bellard
    
2116 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2117 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2118 8636b5d8 bellard
        {
2119 8636b5d8 bellard
            uint64_t mant;
2120 8636b5d8 bellard
            uint16_t exp;
2121 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
2122 8636b5d8 bellard
               contains the MMX register */
2123 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
2124 8636b5d8 bellard
            qemu_put_be64(f, mant);
2125 8636b5d8 bellard
            qemu_put_be16(f, exp);
2126 8636b5d8 bellard
        }
2127 664e0f19 bellard
#else
2128 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
2129 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
2130 664e0f19 bellard
           problems if the image is restored on a CPU where long
2131 664e0f19 bellard
           doubles are used instead. */
2132 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
2133 664e0f19 bellard
#endif
2134 8a7ddc38 bellard
    }
2135 8a7ddc38 bellard
2136 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
2137 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
2138 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
2139 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
2140 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
2141 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
2142 8a7ddc38 bellard
    
2143 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
2144 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
2145 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
2146 8a7ddc38 bellard
    
2147 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
2148 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
2149 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
2150 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
2151 8a7ddc38 bellard
    
2152 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
2153 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
2154 8a7ddc38 bellard
2155 8a7ddc38 bellard
    /* MMU */
2156 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
2157 02536f8b bellard
2158 664e0f19 bellard
    /* XMM */
2159 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
2160 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
2161 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2162 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2163 02536f8b bellard
    }
2164 02536f8b bellard
2165 664e0f19 bellard
#ifdef TARGET_X86_64
2166 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
2167 02536f8b bellard
    qemu_put_be64s(f, &env->star);
2168 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
2169 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
2170 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
2171 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
2172 02536f8b bellard
#endif
2173 8a7ddc38 bellard
}
2174 8a7ddc38 bellard
2175 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
2176 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
2177 664e0f19 bellard
union x86_longdouble {
2178 664e0f19 bellard
    uint64_t mant;
2179 664e0f19 bellard
    uint16_t exp;
2180 664e0f19 bellard
};
2181 664e0f19 bellard
2182 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
2183 664e0f19 bellard
#define EXPBIAS1 1023
2184 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
2185 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
2186 664e0f19 bellard
2187 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
2188 664e0f19 bellard
{
2189 664e0f19 bellard
    int e;
2190 664e0f19 bellard
    /* mantissa */
2191 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
2192 664e0f19 bellard
    /* exponent + sign */
2193 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
2194 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
2195 664e0f19 bellard
    p->exp = e;
2196 664e0f19 bellard
}
2197 8636b5d8 bellard
#endif
2198 664e0f19 bellard
2199 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2200 8a7ddc38 bellard
{
2201 8a7ddc38 bellard
    CPUState *env = opaque;
2202 664e0f19 bellard
    int i, guess_mmx;
2203 8a7ddc38 bellard
    uint32_t hflags;
2204 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
2205 8a7ddc38 bellard
2206 664e0f19 bellard
    if (version_id != 3)
2207 8a7ddc38 bellard
        return -EINVAL;
2208 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
2209 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
2210 20f32282 bellard
    qemu_get_betls(f, &env->eip);
2211 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
2212 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
2213 8a7ddc38 bellard
2214 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
2215 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
2216 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
2217 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
2218 664e0f19 bellard
    
2219 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
2220 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
2221 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
2222 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
2223 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2224 8a7ddc38 bellard
        uint64_t mant;
2225 8a7ddc38 bellard
        uint16_t exp;
2226 664e0f19 bellard
        
2227 664e0f19 bellard
        switch(fpregs_format) {
2228 664e0f19 bellard
        case 0:
2229 664e0f19 bellard
            mant = qemu_get_be64(f);
2230 664e0f19 bellard
            exp = qemu_get_be16(f);
2231 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2232 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
2233 664e0f19 bellard
#else
2234 664e0f19 bellard
            /* difficult case */
2235 664e0f19 bellard
            if (guess_mmx)
2236 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
2237 664e0f19 bellard
            else
2238 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
2239 664e0f19 bellard
#endif
2240 664e0f19 bellard
            break;
2241 664e0f19 bellard
        case 1:
2242 664e0f19 bellard
            mant = qemu_get_be64(f);
2243 664e0f19 bellard
#ifdef USE_X86LDOUBLE
2244 8636b5d8 bellard
            {
2245 8636b5d8 bellard
                union x86_longdouble *p;
2246 8636b5d8 bellard
                /* difficult case */
2247 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
2248 8636b5d8 bellard
                if (guess_mmx) {
2249 8636b5d8 bellard
                    p->mant = mant;
2250 8636b5d8 bellard
                    p->exp = 0xffff;
2251 8636b5d8 bellard
                } else {
2252 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
2253 8636b5d8 bellard
                }
2254 664e0f19 bellard
            }
2255 664e0f19 bellard
#else
2256 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
2257 664e0f19 bellard
#endif            
2258 664e0f19 bellard
            break;
2259 664e0f19 bellard
        default:
2260 664e0f19 bellard
            return -EINVAL;
2261 664e0f19 bellard
        }
2262 8a7ddc38 bellard
    }
2263 8a7ddc38 bellard
2264 8a7ddc38 bellard
    env->fpuc = fpuc;
2265 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
2266 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
2267 664e0f19 bellard
    fptag ^= 0xff;
2268 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
2269 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
2270 8a7ddc38 bellard
    }
2271 8a7ddc38 bellard
    
2272 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
2273 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
2274 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
2275 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
2276 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
2277 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
2278 8a7ddc38 bellard
    
2279 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
2280 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
2281 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
2282 8a7ddc38 bellard
    
2283 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
2284 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
2285 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
2286 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
2287 8a7ddc38 bellard
    
2288 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
2289 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
2290 8a7ddc38 bellard
2291 8a7ddc38 bellard
    /* MMU */
2292 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
2293 8a7ddc38 bellard
2294 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
2295 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
2296 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2297 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2298 02536f8b bellard
    }
2299 02536f8b bellard
2300 664e0f19 bellard
#ifdef TARGET_X86_64
2301 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
2302 02536f8b bellard
    qemu_get_be64s(f, &env->star);
2303 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
2304 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
2305 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
2306 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
2307 02536f8b bellard
#endif
2308 02536f8b bellard
2309 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
2310 8a7ddc38 bellard
    env->hflags = hflags;
2311 8a7ddc38 bellard
    tlb_flush(env, 1);
2312 8a7ddc38 bellard
    return 0;
2313 8a7ddc38 bellard
}
2314 8a7ddc38 bellard
2315 a541f297 bellard
#elif defined(TARGET_PPC)
2316 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
2317 a541f297 bellard
{
2318 a541f297 bellard
}
2319 a541f297 bellard
2320 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2321 a541f297 bellard
{
2322 a541f297 bellard
    return 0;
2323 a541f297 bellard
}
2324 e95c8d51 bellard
#elif defined(TARGET_SPARC)
2325 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
2326 e95c8d51 bellard
{
2327 e80cfcfc bellard
    CPUState *env = opaque;
2328 e80cfcfc bellard
    int i;
2329 e80cfcfc bellard
    uint32_t tmp;
2330 e80cfcfc bellard
2331 4fa5d772 bellard
    for(i = 0; i < 8; i++)
2332 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
2333 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
2334 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
2335 e80cfcfc bellard
2336 e80cfcfc bellard
    /* FPU */
2337 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
2338 4fa5d772 bellard
        union {
2339 4fa5d772 bellard
            TARGET_FPREG_T f;
2340 4fa5d772 bellard
            target_ulong i;
2341 4fa5d772 bellard
        } u;
2342 4fa5d772 bellard
        u.f = env->fpr[i];
2343 4fa5d772 bellard
        qemu_put_betl(f, u.i);
2344 4fa5d772 bellard
    }
2345 4fa5d772 bellard
2346 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
2347 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
2348 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
2349 e80cfcfc bellard
    tmp = GET_PSR(env);
2350 4fa5d772 bellard
    qemu_put_be32(f, tmp);
2351 e80cfcfc bellard
    qemu_put_be32s(f, &env->fsr);
2352 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
2353 e80cfcfc bellard
    qemu_put_be32s(f, &env->tbr);
2354 e80cfcfc bellard
    /* MMU */
2355 e80cfcfc bellard
    for(i = 0; i < 16; i++)
2356 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
2357 e95c8d51 bellard
}
2358 e95c8d51 bellard
2359 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
2360 e95c8d51 bellard
{
2361 e80cfcfc bellard
    CPUState *env = opaque;
2362 e80cfcfc bellard
    int i;
2363 e80cfcfc bellard
    uint32_t tmp;
2364 e80cfcfc bellard
2365 4fa5d772 bellard
    for(i = 0; i < 8; i++)
2366 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
2367 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
2368 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
2369 e80cfcfc bellard
2370 e80cfcfc bellard
    /* FPU */
2371 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
2372 4fa5d772 bellard
        union {
2373 4fa5d772 bellard
            TARGET_FPREG_T f;
2374 4fa5d772 bellard
            target_ulong i;
2375 4fa5d772 bellard
        } u;
2376 4fa5d772 bellard
        u.i = qemu_get_betl(f);
2377 4fa5d772 bellard
        env->fpr[i] = u.f;
2378 4fa5d772 bellard
    }
2379 4fa5d772 bellard
2380 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
2381 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
2382 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
2383 4fa5d772 bellard
    tmp = qemu_get_be32(f);
2384 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
2385 4fa5d772 bellard
                     correctly updated */
2386 e80cfcfc bellard
    PUT_PSR(env, tmp);
2387 e80cfcfc bellard
    qemu_get_be32s(f, &env->fsr);
2388 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
2389 e80cfcfc bellard
    qemu_get_be32s(f, &env->tbr);
2390 e80cfcfc bellard
    /* MMU */
2391 e80cfcfc bellard
    for(i = 0; i < 16; i++)
2392 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
2393 4fa5d772 bellard
2394 e80cfcfc bellard
    tlb_flush(env, 1);
2395 e95c8d51 bellard
    return 0;
2396 e95c8d51 bellard
}
2397 8a7ddc38 bellard
#else
2398 8a7ddc38 bellard
2399 8a7ddc38 bellard
#warning No CPU save/restore functions
2400 8a7ddc38 bellard
2401 8a7ddc38 bellard
#endif
2402 8a7ddc38 bellard
2403 8a7ddc38 bellard
/***********************************************************/
2404 8a7ddc38 bellard
/* ram save/restore */
2405 8a7ddc38 bellard
2406 8a7ddc38 bellard
/* we just avoid storing empty pages */
2407 8a7ddc38 bellard
static void ram_put_page(QEMUFile *f, const uint8_t *buf, int len)
2408 8a7ddc38 bellard
{
2409 8a7ddc38 bellard
    int i, v;
2410 8a7ddc38 bellard
2411 8a7ddc38 bellard
    v = buf[0];
2412 8a7ddc38 bellard
    for(i = 1; i < len; i++) {
2413 8a7ddc38 bellard
        if (buf[i] != v)
2414 8a7ddc38 bellard
            goto normal_save;
2415 8a7ddc38 bellard
    }
2416 8a7ddc38 bellard
    qemu_put_byte(f, 1);
2417 8a7ddc38 bellard
    qemu_put_byte(f, v);
2418 8a7ddc38 bellard
    return;
2419 8a7ddc38 bellard
 normal_save:
2420 8a7ddc38 bellard
    qemu_put_byte(f, 0); 
2421 8a7ddc38 bellard
    qemu_put_buffer(f, buf, len);
2422 8a7ddc38 bellard
}
2423 8a7ddc38 bellard
2424 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
2425 8a7ddc38 bellard
{
2426 8a7ddc38 bellard
    int v;
2427 8a7ddc38 bellard
2428 8a7ddc38 bellard
    v = qemu_get_byte(f);
2429 8a7ddc38 bellard
    switch(v) {
2430 8a7ddc38 bellard
    case 0:
2431 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
2432 8a7ddc38 bellard
            return -EIO;
2433 8a7ddc38 bellard
        break;
2434 8a7ddc38 bellard
    case 1:
2435 8a7ddc38 bellard
        v = qemu_get_byte(f);
2436 8a7ddc38 bellard
        memset(buf, v, len);
2437 8a7ddc38 bellard
        break;
2438 8a7ddc38 bellard
    default:
2439 8a7ddc38 bellard
        return -EINVAL;
2440 8a7ddc38 bellard
    }
2441 8a7ddc38 bellard
    return 0;
2442 8a7ddc38 bellard
}
2443 8a7ddc38 bellard
2444 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
2445 8a7ddc38 bellard
{
2446 8a7ddc38 bellard
    int i;
2447 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
2448 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
2449 8a7ddc38 bellard
        ram_put_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
2450 8a7ddc38 bellard
    }
2451 8a7ddc38 bellard
}
2452 8a7ddc38 bellard
2453 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
2454 8a7ddc38 bellard
{
2455 8a7ddc38 bellard
    int i, ret;
2456 8a7ddc38 bellard
2457 8a7ddc38 bellard
    if (version_id != 1)
2458 8a7ddc38 bellard
        return -EINVAL;
2459 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
2460 8a7ddc38 bellard
        return -EINVAL;
2461 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
2462 8a7ddc38 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
2463 8a7ddc38 bellard
        if (ret)
2464 8a7ddc38 bellard
            return ret;
2465 8a7ddc38 bellard
    }
2466 8a7ddc38 bellard
    return 0;
2467 8a7ddc38 bellard
}
2468 8a7ddc38 bellard
2469 8a7ddc38 bellard
/***********************************************************/
2470 8a7ddc38 bellard
/* main execution loop */
2471 8a7ddc38 bellard
2472 8a7ddc38 bellard
void gui_update(void *opaque)
2473 8a7ddc38 bellard
{
2474 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
2475 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
2476 8a7ddc38 bellard
}
2477 8a7ddc38 bellard
2478 8a7ddc38 bellard
/* XXX: support several handlers */
2479 8a7ddc38 bellard
VMStopHandler *vm_stop_cb;
2480 8a7ddc38 bellard
VMStopHandler *vm_stop_opaque;
2481 8a7ddc38 bellard
2482 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
2483 8a7ddc38 bellard
{
2484 8a7ddc38 bellard
    vm_stop_cb = cb;
2485 8a7ddc38 bellard
    vm_stop_opaque = opaque;
2486 8a7ddc38 bellard
    return 0;
2487 8a7ddc38 bellard
}
2488 8a7ddc38 bellard
2489 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
2490 8a7ddc38 bellard
{
2491 8a7ddc38 bellard
    vm_stop_cb = NULL;
2492 8a7ddc38 bellard
}
2493 8a7ddc38 bellard
2494 8a7ddc38 bellard
void vm_start(void)
2495 8a7ddc38 bellard
{
2496 8a7ddc38 bellard
    if (!vm_running) {
2497 8a7ddc38 bellard
        cpu_enable_ticks();
2498 8a7ddc38 bellard
        vm_running = 1;
2499 8a7ddc38 bellard
    }
2500 8a7ddc38 bellard
}
2501 8a7ddc38 bellard
2502 8a7ddc38 bellard
void vm_stop(int reason) 
2503 8a7ddc38 bellard
{
2504 8a7ddc38 bellard
    if (vm_running) {
2505 8a7ddc38 bellard
        cpu_disable_ticks();
2506 8a7ddc38 bellard
        vm_running = 0;
2507 8a7ddc38 bellard
        if (reason != 0) {
2508 8a7ddc38 bellard
            if (vm_stop_cb) {
2509 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
2510 8a7ddc38 bellard
            }
2511 34865134 bellard
        }
2512 8a7ddc38 bellard
    }
2513 8a7ddc38 bellard
}
2514 8a7ddc38 bellard
2515 bb0c6722 bellard
/* reset/shutdown handler */
2516 bb0c6722 bellard
2517 bb0c6722 bellard
typedef struct QEMUResetEntry {
2518 bb0c6722 bellard
    QEMUResetHandler *func;
2519 bb0c6722 bellard
    void *opaque;
2520 bb0c6722 bellard
    struct QEMUResetEntry *next;
2521 bb0c6722 bellard
} QEMUResetEntry;
2522 bb0c6722 bellard
2523 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
2524 bb0c6722 bellard
static int reset_requested;
2525 bb0c6722 bellard
static int shutdown_requested;
2526 bb0c6722 bellard
2527 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
2528 bb0c6722 bellard
{
2529 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
2530 bb0c6722 bellard
2531 bb0c6722 bellard
    pre = &first_reset_entry;
2532 bb0c6722 bellard
    while (*pre != NULL)
2533 bb0c6722 bellard
        pre = &(*pre)->next;
2534 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
2535 bb0c6722 bellard
    re->func = func;
2536 bb0c6722 bellard
    re->opaque = opaque;
2537 bb0c6722 bellard
    re->next = NULL;
2538 bb0c6722 bellard
    *pre = re;
2539 bb0c6722 bellard
}
2540 bb0c6722 bellard
2541 bb0c6722 bellard
void qemu_system_reset(void)
2542 bb0c6722 bellard
{
2543 bb0c6722 bellard
    QEMUResetEntry *re;
2544 bb0c6722 bellard
2545 bb0c6722 bellard
    /* reset all devices */
2546 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
2547 bb0c6722 bellard
        re->func(re->opaque);
2548 bb0c6722 bellard
    }
2549 bb0c6722 bellard
}
2550 bb0c6722 bellard
2551 bb0c6722 bellard
void qemu_system_reset_request(void)
2552 bb0c6722 bellard
{
2553 bb0c6722 bellard
    reset_requested = 1;
2554 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2555 bb0c6722 bellard
}
2556 bb0c6722 bellard
2557 bb0c6722 bellard
void qemu_system_shutdown_request(void)
2558 bb0c6722 bellard
{
2559 bb0c6722 bellard
    shutdown_requested = 1;
2560 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2561 bb0c6722 bellard
}
2562 bb0c6722 bellard
2563 bb0c6722 bellard
static void main_cpu_reset(void *opaque)
2564 bb0c6722 bellard
{
2565 e80cfcfc bellard
#if defined(TARGET_I386) || defined(TARGET_SPARC)
2566 bb0c6722 bellard
    CPUState *env = opaque;
2567 bb0c6722 bellard
    cpu_reset(env);
2568 bb0c6722 bellard
#endif
2569 bb0c6722 bellard
}
2570 bb0c6722 bellard
2571 5905b2e5 bellard
void main_loop_wait(int timeout)
2572 8a7ddc38 bellard
{
2573 67b915a5 bellard
#ifndef _WIN32
2574 8a7ddc38 bellard
    struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
2575 8a7ddc38 bellard
    IOHandlerRecord *ioh, *ioh_next;
2576 67b915a5 bellard
    uint8_t buf[4096];
2577 67b915a5 bellard
    int n, max_size;
2578 67b915a5 bellard
#endif
2579 5905b2e5 bellard
    int ret;
2580 c4b1fcc0 bellard
2581 38e205a2 bellard
#ifdef _WIN32
2582 38e205a2 bellard
        if (timeout > 0)
2583 38e205a2 bellard
            Sleep(timeout);
2584 38e205a2 bellard
#else
2585 b4608c04 bellard
        /* poll any events */
2586 8a7ddc38 bellard
        /* XXX: separate device handlers from system ones */
2587 b4608c04 bellard
        pf = ufds;
2588 8a7ddc38 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2589 8a7ddc38 bellard
            if (!ioh->fd_can_read) {
2590 8a7ddc38 bellard
                max_size = 0;
2591 c4b1fcc0 bellard
                pf->fd = ioh->fd;
2592 c4b1fcc0 bellard
                pf->events = POLLIN;
2593 c4b1fcc0 bellard
                ioh->ufd = pf;
2594 c4b1fcc0 bellard
                pf++;
2595 c4b1fcc0 bellard
            } else {
2596 8a7ddc38 bellard
                max_size = ioh->fd_can_read(ioh->opaque);
2597 8a7ddc38 bellard
                if (max_size > 0) {
2598 8a7ddc38 bellard
                    if (max_size > sizeof(buf))
2599 8a7ddc38 bellard
                        max_size = sizeof(buf);
2600 8a7ddc38 bellard
                    pf->fd = ioh->fd;
2601 8a7ddc38 bellard
                    pf->events = POLLIN;
2602 8a7ddc38 bellard
                    ioh->ufd = pf;
2603 8a7ddc38 bellard
                    pf++;
2604 8a7ddc38 bellard
                } else {
2605 8a7ddc38 bellard
                    ioh->ufd = NULL;
2606 8a7ddc38 bellard
                }
2607 c4b1fcc0 bellard
            }
2608 c4b1fcc0 bellard
            ioh->max_size = max_size;
2609 b4608c04 bellard
        }
2610 73332e5c bellard
        
2611 b4608c04 bellard
        ret = poll(ufds, pf - ufds, timeout);
2612 b4608c04 bellard
        if (ret > 0) {
2613 8a7ddc38 bellard
            /* XXX: better handling of removal */
2614 8a7ddc38 bellard
            for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
2615 8a7ddc38 bellard
                ioh_next = ioh->next;
2616 c4b1fcc0 bellard
                pf = ioh->ufd;
2617 c4b1fcc0 bellard
                if (pf) {
2618 8a7ddc38 bellard
                    if (pf->revents & POLLIN) {
2619 8a7ddc38 bellard
                        if (ioh->max_size == 0) {
2620 8a7ddc38 bellard
                            /* just a read event */
2621 8a7ddc38 bellard
                            ioh->fd_read(ioh->opaque, NULL, 0);
2622 8a7ddc38 bellard
                        } else {
2623 8a7ddc38 bellard
                            n = read(ioh->fd, buf, ioh->max_size);
2624 8a7ddc38 bellard
                            if (n >= 0) {
2625 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, buf, n);
2626 158156d1 bellard
                            } else if (errno != EAGAIN) {
2627 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, NULL, -errno);
2628 8a7ddc38 bellard
                            }
2629 8a7ddc38 bellard
                        }
2630 b4608c04 bellard
                    }
2631 b4608c04 bellard
                }
2632 b4608c04 bellard
            }
2633 b4608c04 bellard
        }
2634 5905b2e5 bellard
#endif /* !defined(_WIN32) */
2635 c20709aa bellard
#if defined(CONFIG_SLIRP)
2636 c20709aa bellard
        /* XXX: merge with poll() */
2637 c20709aa bellard
        if (slirp_inited) {
2638 c20709aa bellard
            fd_set rfds, wfds, xfds;
2639 c20709aa bellard
            int nfds;
2640 c20709aa bellard
            struct timeval tv;
2641 c20709aa bellard
2642 c20709aa bellard
            nfds = -1;
2643 c20709aa bellard
            FD_ZERO(&rfds);
2644 c20709aa bellard
            FD_ZERO(&wfds);
2645 c20709aa bellard
            FD_ZERO(&xfds);
2646 c20709aa bellard
            slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2647 c20709aa bellard
            tv.tv_sec = 0;
2648 c20709aa bellard
            tv.tv_usec = 0;
2649 c20709aa bellard
            ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
2650 c20709aa bellard
            if (ret >= 0) {
2651 c20709aa bellard
                slirp_select_poll(&rfds, &wfds, &xfds);
2652 c20709aa bellard
            }
2653 c20709aa bellard
        }
2654 c20709aa bellard
#endif
2655 c20709aa bellard
2656 8a7ddc38 bellard
        if (vm_running) {
2657 8a7ddc38 bellard
            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
2658 8a7ddc38 bellard
                            qemu_get_clock(vm_clock));
2659 8a7ddc38 bellard
            /* run dma transfers, if any */
2660 8a7ddc38 bellard
            DMA_run();
2661 b4608c04 bellard
        }
2662 313aa567 bellard
2663 8a7ddc38 bellard
        /* real time timers */
2664 8a7ddc38 bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
2665 8a7ddc38 bellard
                        qemu_get_clock(rt_clock));
2666 5905b2e5 bellard
}
2667 5905b2e5 bellard
2668 5905b2e5 bellard
int main_loop(void)
2669 5905b2e5 bellard
{
2670 5905b2e5 bellard
    int ret, timeout;
2671 5905b2e5 bellard
    CPUState *env = global_env;
2672 5905b2e5 bellard
2673 5905b2e5 bellard
    for(;;) {
2674 5905b2e5 bellard
        if (vm_running) {
2675 5905b2e5 bellard
            ret = cpu_exec(env);
2676 5905b2e5 bellard
            if (shutdown_requested) {
2677 5905b2e5 bellard
                ret = EXCP_INTERRUPT; 
2678 5905b2e5 bellard
                break;
2679 5905b2e5 bellard
            }
2680 5905b2e5 bellard
            if (reset_requested) {
2681 5905b2e5 bellard
                reset_requested = 0;
2682 5905b2e5 bellard
                qemu_system_reset();
2683 5905b2e5 bellard
                ret = EXCP_INTERRUPT; 
2684 5905b2e5 bellard
            }
2685 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
2686 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
2687 5905b2e5 bellard
            }
2688 5905b2e5 bellard
            /* if hlt instruction, we wait until the next IRQ */
2689 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
2690 5905b2e5 bellard
            if (ret == EXCP_HLT) 
2691 5905b2e5 bellard
                timeout = 10;
2692 5905b2e5 bellard
            else
2693 5905b2e5 bellard
                timeout = 0;
2694 5905b2e5 bellard
        } else {
2695 5905b2e5 bellard
            timeout = 10;
2696 5905b2e5 bellard
        }
2697 5905b2e5 bellard
        main_loop_wait(timeout);
2698 b4608c04 bellard
    }
2699 34865134 bellard
    cpu_disable_ticks();
2700 34865134 bellard
    return ret;
2701 b4608c04 bellard
}
2702 b4608c04 bellard
2703 0824d6fc bellard
void help(void)
2704 0824d6fc bellard
{
2705 aaaa7df6 bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
2706 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
2707 0824d6fc bellard
           "\n"
2708 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2709 fc01f7e7 bellard
           "\n"
2710 a20dd508 bellard
           "Standard options:\n"
2711 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
2712 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
2713 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
2714 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
2715 9e89a4be bellard
           "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
2716 a20dd508 bellard
           "-snapshot       write to temporary files instead of disk image files\n"
2717 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
2718 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
2719 4ca0074c bellard
#ifndef _WIN32
2720 3d11d0eb bellard
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
2721 4ca0074c bellard
#endif
2722 aaaa7df6 bellard
           "-enable-audio   enable audio support\n"
2723 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
2724 d63d307f bellard
           "-full-screen    start in full screen\n"
2725 bb0c6722 bellard
#ifdef TARGET_PPC
2726 bb0c6722 bellard
           "-prep           Simulate a PREP system (default is PowerMAC)\n"
2727 e9b137c2 bellard
           "-g WxH[xDEPTH]  Set the initial VGA graphic mode\n"
2728 bb0c6722 bellard
#endif
2729 c4b1fcc0 bellard
           "\n"
2730 c4b1fcc0 bellard
           "Network options:\n"
2731 c20709aa bellard
           "-nics n         simulate 'n' network cards [default=1]\n"
2732 702c651c bellard
           "-macaddr addr   set the mac address of the first interface\n"
2733 c20709aa bellard
           "-n script       set tap/tun network init script [default=%s]\n"
2734 c20709aa bellard
           "-tun-fd fd      use this fd as already opened tap/tun interface\n"
2735 c20709aa bellard
#ifdef CONFIG_SLIRP
2736 c20709aa bellard
           "-user-net       use user mode network stack [default if no tap/tun script]\n"
2737 9bf05444 bellard
           "-tftp prefix    allow tftp access to files starting with prefix [-user-net]\n"
2738 c94c8d64 bellard
#ifndef _WIN32
2739 9d728e8c bellard
           "-smb dir        allow SMB access to files in 'dir' [-user-net]\n"
2740 c94c8d64 bellard
#endif
2741 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
2742 9bf05444 bellard
           "                redirect TCP or UDP connections from host to guest [-user-net]\n"
2743 c20709aa bellard
#endif
2744 c20709aa bellard
           "-dummy-net      use dummy network stack\n"
2745 a20dd508 bellard
           "\n"
2746 c4b1fcc0 bellard
           "Linux boot specific:\n"
2747 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
2748 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
2749 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
2750 fc01f7e7 bellard
           "\n"
2751 330d0414 bellard
           "Debug/Expert options:\n"
2752 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
2753 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
2754 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
2755 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
2756 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
2757 a20dd508 bellard
           "-s              wait gdb connection to port %d\n"
2758 a20dd508 bellard
           "-p port         change gdb connection port\n"
2759 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
2760 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
2761 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
2762 a20dd508 bellard
           "-L path         set the directory for the BIOS and VGA BIOS\n"
2763 d993e026 bellard
#ifdef USE_KQEMU
2764 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
2765 d993e026 bellard
#endif
2766 77fef8c1 bellard
#ifdef USE_CODE_COPY
2767 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
2768 77fef8c1 bellard
#endif
2769 bb0c6722 bellard
#ifdef TARGET_I386
2770 bb0c6722 bellard
           "-isa            simulate an ISA-only system (default is PCI system)\n"
2771 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
2772 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
2773 bb0c6722 bellard
#endif
2774 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
2775 0824d6fc bellard
           "\n"
2776 82c643ff bellard
           "During emulation, the following keys are useful:\n"
2777 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
2778 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
2779 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
2780 82c643ff bellard
           "\n"
2781 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
2782 82c643ff bellard
           ,
2783 0db63474 bellard
#ifdef CONFIG_SOFTMMU
2784 0db63474 bellard
           "qemu",
2785 0db63474 bellard
#else
2786 0db63474 bellard
           "qemu-fast",
2787 0db63474 bellard
#endif
2788 a00bad7e bellard
           DEFAULT_RAM_SIZE,
2789 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
2790 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
2791 6e44ba7f bellard
           "/tmp/qemu.log");
2792 0db63474 bellard
#ifndef CONFIG_SOFTMMU
2793 0db63474 bellard
    printf("\n"
2794 0db63474 bellard
           "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
2795 0db63474 bellard
           "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
2796 0db63474 bellard
           "PC emulation.\n");
2797 0db63474 bellard
#endif
2798 0824d6fc bellard
    exit(1);
2799 0824d6fc bellard
}
2800 0824d6fc bellard
2801 cd6f1169 bellard
#define HAS_ARG 0x0001
2802 cd6f1169 bellard
2803 cd6f1169 bellard
enum {
2804 cd6f1169 bellard
    QEMU_OPTION_h,
2805 cd6f1169 bellard
2806 cd6f1169 bellard
    QEMU_OPTION_fda,
2807 cd6f1169 bellard
    QEMU_OPTION_fdb,
2808 cd6f1169 bellard
    QEMU_OPTION_hda,
2809 cd6f1169 bellard
    QEMU_OPTION_hdb,
2810 cd6f1169 bellard
    QEMU_OPTION_hdc,
2811 cd6f1169 bellard
    QEMU_OPTION_hdd,
2812 cd6f1169 bellard
    QEMU_OPTION_cdrom,
2813 cd6f1169 bellard
    QEMU_OPTION_boot,
2814 cd6f1169 bellard
    QEMU_OPTION_snapshot,
2815 cd6f1169 bellard
    QEMU_OPTION_m,
2816 cd6f1169 bellard
    QEMU_OPTION_nographic,
2817 cd6f1169 bellard
    QEMU_OPTION_enable_audio,
2818 cd6f1169 bellard
2819 cd6f1169 bellard
    QEMU_OPTION_nics,
2820 cd6f1169 bellard
    QEMU_OPTION_macaddr,
2821 cd6f1169 bellard
    QEMU_OPTION_n,
2822 cd6f1169 bellard
    QEMU_OPTION_tun_fd,
2823 cd6f1169 bellard
    QEMU_OPTION_user_net,
2824 c7f74643 bellard
    QEMU_OPTION_tftp,
2825 9d728e8c bellard
    QEMU_OPTION_smb,
2826 9bf05444 bellard
    QEMU_OPTION_redir,
2827 cd6f1169 bellard
    QEMU_OPTION_dummy_net,
2828 cd6f1169 bellard
2829 cd6f1169 bellard
    QEMU_OPTION_kernel,
2830 cd6f1169 bellard
    QEMU_OPTION_append,
2831 cd6f1169 bellard
    QEMU_OPTION_initrd,
2832 cd6f1169 bellard
2833 cd6f1169 bellard
    QEMU_OPTION_S,
2834 cd6f1169 bellard
    QEMU_OPTION_s,
2835 cd6f1169 bellard
    QEMU_OPTION_p,
2836 cd6f1169 bellard
    QEMU_OPTION_d,
2837 cd6f1169 bellard
    QEMU_OPTION_hdachs,
2838 cd6f1169 bellard
    QEMU_OPTION_L,
2839 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
2840 69b91039 bellard
    QEMU_OPTION_pci,
2841 bb0c6722 bellard
    QEMU_OPTION_isa,
2842 77d4bc34 bellard
    QEMU_OPTION_prep,
2843 3d11d0eb bellard
    QEMU_OPTION_k,
2844 ee22c2f7 bellard
    QEMU_OPTION_localtime,
2845 1f04275e bellard
    QEMU_OPTION_cirrusvga,
2846 e9b137c2 bellard
    QEMU_OPTION_g,
2847 1bfe856e bellard
    QEMU_OPTION_std_vga,
2848 82c643ff bellard
    QEMU_OPTION_monitor,
2849 82c643ff bellard
    QEMU_OPTION_serial,
2850 6508fe59 bellard
    QEMU_OPTION_parallel,
2851 d63d307f bellard
    QEMU_OPTION_loadvm,
2852 d63d307f bellard
    QEMU_OPTION_full_screen,
2853 f7cce898 bellard
    QEMU_OPTION_pidfile,
2854 d993e026 bellard
    QEMU_OPTION_no_kqemu,
2855 cd6f1169 bellard
};
2856 cd6f1169 bellard
2857 cd6f1169 bellard
typedef struct QEMUOption {
2858 cd6f1169 bellard
    const char *name;
2859 cd6f1169 bellard
    int flags;
2860 cd6f1169 bellard
    int index;
2861 cd6f1169 bellard
} QEMUOption;
2862 cd6f1169 bellard
2863 cd6f1169 bellard
const QEMUOption qemu_options[] = {
2864 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
2865 cd6f1169 bellard
2866 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
2867 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
2868 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
2869 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
2870 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
2871 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
2872 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
2873 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
2874 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
2875 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
2876 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
2877 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
2878 cd6f1169 bellard
    { "enable-audio", 0, QEMU_OPTION_enable_audio },
2879 cd6f1169 bellard
2880 cd6f1169 bellard
    { "nics", HAS_ARG, QEMU_OPTION_nics},
2881 cd6f1169 bellard
    { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
2882 69b91039 bellard
    { "n", HAS_ARG, QEMU_OPTION_n },
2883 cd6f1169 bellard
    { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
2884 158156d1 bellard
#ifdef CONFIG_SLIRP
2885 cd6f1169 bellard
    { "user-net", 0, QEMU_OPTION_user_net },
2886 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
2887 c94c8d64 bellard
#ifndef _WIN32
2888 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
2889 c94c8d64 bellard
#endif
2890 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
2891 158156d1 bellard
#endif
2892 cd6f1169 bellard
    { "dummy-net", 0, QEMU_OPTION_dummy_net },
2893 cd6f1169 bellard
2894 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
2895 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
2896 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
2897 cd6f1169 bellard
2898 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
2899 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
2900 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
2901 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
2902 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
2903 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
2904 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
2905 d993e026 bellard
#ifdef USE_KQEMU
2906 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
2907 d993e026 bellard
#endif
2908 77d4bc34 bellard
#ifdef TARGET_PPC
2909 77d4bc34 bellard
    { "prep", 0, QEMU_OPTION_prep },
2910 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
2911 77d4bc34 bellard
#endif
2912 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
2913 bb0c6722 bellard
    { "isa", 0, QEMU_OPTION_isa },
2914 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
2915 82c643ff bellard
    { "monitor", 1, QEMU_OPTION_monitor },
2916 82c643ff bellard
    { "serial", 1, QEMU_OPTION_serial },
2917 6508fe59 bellard
    { "parallel", 1, QEMU_OPTION_parallel },
2918 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
2919 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
2920 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
2921 f7cce898 bellard
2922 1f04275e bellard
    /* temporary options */
2923 1f04275e bellard
    { "pci", 0, QEMU_OPTION_pci },
2924 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
2925 cd6f1169 bellard
    { NULL },
2926 fc01f7e7 bellard
};
2927 fc01f7e7 bellard
2928 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
2929 77fef8c1 bellard
2930 77fef8c1 bellard
/* this stack is only used during signal handling */
2931 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
2932 77fef8c1 bellard
2933 77fef8c1 bellard
static uint8_t *signal_stack;
2934 77fef8c1 bellard
2935 77fef8c1 bellard
#endif
2936 77fef8c1 bellard
2937 5905b2e5 bellard
/* password input */
2938 5905b2e5 bellard
2939 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
2940 5905b2e5 bellard
{
2941 5905b2e5 bellard
    BlockDriverState *bs;
2942 5905b2e5 bellard
2943 5905b2e5 bellard
    if (index < 4) {
2944 5905b2e5 bellard
        bs = bs_table[index];
2945 5905b2e5 bellard
    } else if (index < 6) {
2946 5905b2e5 bellard
        bs = fd_table[index - 4];
2947 5905b2e5 bellard
    } else {
2948 5905b2e5 bellard
        bs = NULL;
2949 5905b2e5 bellard
    }
2950 5905b2e5 bellard
    return bs;
2951 5905b2e5 bellard
}
2952 5905b2e5 bellard
2953 5905b2e5 bellard
static void read_passwords(void)
2954 5905b2e5 bellard
{
2955 5905b2e5 bellard
    BlockDriverState *bs;
2956 5905b2e5 bellard
    int i, j;
2957 5905b2e5 bellard
    char password[256];
2958 5905b2e5 bellard
2959 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
2960 5905b2e5 bellard
        bs = get_bdrv(i);
2961 5905b2e5 bellard
        if (bs && bdrv_is_encrypted(bs)) {
2962 5905b2e5 bellard
            term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
2963 5905b2e5 bellard
            for(j = 0; j < 3; j++) {
2964 5905b2e5 bellard
                monitor_readline("Password: ", 
2965 5905b2e5 bellard
                                 1, password, sizeof(password));
2966 5905b2e5 bellard
                if (bdrv_set_key(bs, password) == 0)
2967 5905b2e5 bellard
                    break;
2968 5905b2e5 bellard
                term_printf("invalid password\n");
2969 5905b2e5 bellard
            }
2970 5905b2e5 bellard
        }
2971 5905b2e5 bellard
    }
2972 5905b2e5 bellard
}
2973 5905b2e5 bellard
2974 c20709aa bellard
#define NET_IF_TUN   0
2975 c20709aa bellard
#define NET_IF_USER  1
2976 c20709aa bellard
#define NET_IF_DUMMY 2
2977 c20709aa bellard
2978 0824d6fc bellard
int main(int argc, char **argv)
2979 0824d6fc bellard
{
2980 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
2981 67b915a5 bellard
    int use_gdbstub, gdbstub_port;
2982 67b915a5 bellard
#endif
2983 cd6f1169 bellard
    int i, has_cdrom;
2984 1ccde1cb bellard
    int snapshot, linux_boot;
2985 c45886db bellard
    CPUState *env;
2986 7f7f9873 bellard
    const char *initrd_filename;
2987 c45886db bellard
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
2988 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
2989 313aa567 bellard
    DisplayState *ds = &display_state;
2990 46d4767d bellard
    int cyls, heads, secs, translation;
2991 a541f297 bellard
    int start_emulation = 1;
2992 702c651c bellard
    uint8_t macaddr[6];
2993 c20709aa bellard
    int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
2994 cd6f1169 bellard
    int optind;
2995 cd6f1169 bellard
    const char *r, *optarg;
2996 82c643ff bellard
    CharDriverState *monitor_hd;
2997 82c643ff bellard
    char monitor_device[128];
2998 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
2999 8d11df9e bellard
    int serial_device_index;
3000 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
3001 6508fe59 bellard
    int parallel_device_index;
3002 d63d307f bellard
    const char *loadvm = NULL;
3003 8d11df9e bellard
    
3004 67b915a5 bellard
#if !defined(CONFIG_SOFTMMU)
3005 0824d6fc bellard
    /* we never want that malloc() uses mmap() */
3006 0824d6fc bellard
    mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
3007 67b915a5 bellard
#endif
3008 fc01f7e7 bellard
    initrd_filename = NULL;
3009 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
3010 c45886db bellard
        fd_filename[i] = NULL;
3011 fc01f7e7 bellard
    for(i = 0; i < MAX_DISKS; i++)
3012 fc01f7e7 bellard
        hd_filename[i] = NULL;
3013 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
3014 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
3015 0ced6589 bellard
    bios_size = BIOS_SIZE;
3016 f1510b2c bellard
    pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
3017 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3018 b4608c04 bellard
    use_gdbstub = 0;
3019 b4608c04 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
3020 67b915a5 bellard
#endif
3021 33e3963e bellard
    snapshot = 0;
3022 a20dd508 bellard
    nographic = 0;
3023 a20dd508 bellard
    kernel_filename = NULL;
3024 a20dd508 bellard
    kernel_cmdline = "";
3025 c4b1fcc0 bellard
    has_cdrom = 1;
3026 c4b1fcc0 bellard
    cyls = heads = secs = 0;
3027 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
3028 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
3029 c4b1fcc0 bellard
3030 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
3031 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
3032 8d11df9e bellard
        serial_devices[i][0] = '\0';
3033 8d11df9e bellard
    serial_device_index = 0;
3034 8d11df9e bellard
    
3035 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
3036 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3037 6508fe59 bellard
        parallel_devices[i][0] = '\0';
3038 6508fe59 bellard
    parallel_device_index = 0;
3039 6508fe59 bellard
    
3040 c20709aa bellard
    nb_tun_fds = 0;
3041 c20709aa bellard
    net_if_type = -1;
3042 c4b1fcc0 bellard
    nb_nics = 1;
3043 702c651c bellard
    /* default mac address of the first network interface */
3044 702c651c bellard
    macaddr[0] = 0x52;
3045 702c651c bellard
    macaddr[1] = 0x54;
3046 702c651c bellard
    macaddr[2] = 0x00;
3047 702c651c bellard
    macaddr[3] = 0x12;
3048 702c651c bellard
    macaddr[4] = 0x34;
3049 702c651c bellard
    macaddr[5] = 0x56;
3050 82c643ff bellard
    
3051 cd6f1169 bellard
    optind = 1;
3052 0824d6fc bellard
    for(;;) {
3053 cd6f1169 bellard
        if (optind >= argc)
3054 0824d6fc bellard
            break;
3055 cd6f1169 bellard
        r = argv[optind];
3056 cd6f1169 bellard
        if (r[0] != '-') {
3057 cd6f1169 bellard
            hd_filename[0] = argv[optind++];
3058 cd6f1169 bellard
        } else {
3059 cd6f1169 bellard
            const QEMUOption *popt;
3060 cd6f1169 bellard
3061 cd6f1169 bellard
            optind++;
3062 cd6f1169 bellard
            popt = qemu_options;
3063 cd6f1169 bellard
            for(;;) {
3064 cd6f1169 bellard
                if (!popt->name) {
3065 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
3066 cd6f1169 bellard
                            argv[0], r);
3067 cd6f1169 bellard
                    exit(1);
3068 cd6f1169 bellard
                }
3069 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
3070 cd6f1169 bellard
                    break;
3071 cd6f1169 bellard
                popt++;
3072 cd6f1169 bellard
            }
3073 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
3074 cd6f1169 bellard
                if (optind >= argc) {
3075 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
3076 cd6f1169 bellard
                            argv[0], r);
3077 cd6f1169 bellard
                    exit(1);
3078 cd6f1169 bellard
                }
3079 cd6f1169 bellard
                optarg = argv[optind++];
3080 cd6f1169 bellard
            } else {
3081 cd6f1169 bellard
                optarg = NULL;
3082 cd6f1169 bellard
            }
3083 cd6f1169 bellard
3084 cd6f1169 bellard
            switch(popt->index) {
3085 cd6f1169 bellard
            case QEMU_OPTION_initrd:
3086 fc01f7e7 bellard
                initrd_filename = optarg;
3087 fc01f7e7 bellard
                break;
3088 cd6f1169 bellard
            case QEMU_OPTION_hda:
3089 fc01f7e7 bellard
                hd_filename[0] = optarg;
3090 fc01f7e7 bellard
                break;
3091 cd6f1169 bellard
            case QEMU_OPTION_hdb:
3092 fc01f7e7 bellard
                hd_filename[1] = optarg;
3093 fc01f7e7 bellard
                break;
3094 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
3095 33e3963e bellard
                snapshot = 1;
3096 33e3963e bellard
                break;
3097 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
3098 330d0414 bellard
                {
3099 330d0414 bellard
                    const char *p;
3100 330d0414 bellard
                    p = optarg;
3101 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
3102 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
3103 46d4767d bellard
                        goto chs_fail;
3104 330d0414 bellard
                    if (*p != ',')
3105 330d0414 bellard
                        goto chs_fail;
3106 330d0414 bellard
                    p++;
3107 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
3108 46d4767d bellard
                    if (heads < 1 || heads > 16)
3109 46d4767d bellard
                        goto chs_fail;
3110 330d0414 bellard
                    if (*p != ',')
3111 330d0414 bellard
                        goto chs_fail;
3112 330d0414 bellard
                    p++;
3113 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
3114 46d4767d bellard
                    if (secs < 1 || secs > 63)
3115 46d4767d bellard
                        goto chs_fail;
3116 46d4767d bellard
                    if (*p == ',') {
3117 46d4767d bellard
                        p++;
3118 46d4767d bellard
                        if (!strcmp(p, "none"))
3119 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
3120 46d4767d bellard
                        else if (!strcmp(p, "lba"))
3121 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
3122 46d4767d bellard
                        else if (!strcmp(p, "auto"))
3123 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
3124 46d4767d bellard
                        else
3125 46d4767d bellard
                            goto chs_fail;
3126 46d4767d bellard
                    } else if (*p != '\0') {
3127 c4b1fcc0 bellard
                    chs_fail:
3128 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
3129 46d4767d bellard
                        exit(1);
3130 c4b1fcc0 bellard
                    }
3131 330d0414 bellard
                }
3132 330d0414 bellard
                break;
3133 cd6f1169 bellard
            case QEMU_OPTION_nographic:
3134 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
3135 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
3136 a20dd508 bellard
                nographic = 1;
3137 a20dd508 bellard
                break;
3138 cd6f1169 bellard
            case QEMU_OPTION_kernel:
3139 a20dd508 bellard
                kernel_filename = optarg;
3140 a20dd508 bellard
                break;
3141 cd6f1169 bellard
            case QEMU_OPTION_append:
3142 a20dd508 bellard
                kernel_cmdline = optarg;
3143 313aa567 bellard
                break;
3144 cd6f1169 bellard
            case QEMU_OPTION_tun_fd:
3145 c4b1fcc0 bellard
                {
3146 c4b1fcc0 bellard
                    const char *p;
3147 c4b1fcc0 bellard
                    int fd;
3148 d6b86f4d bellard
                    net_if_type = NET_IF_TUN;
3149 c20709aa bellard
                    if (nb_tun_fds < MAX_NICS) {
3150 c20709aa bellard
                        fd = strtol(optarg, (char **)&p, 0);
3151 c20709aa bellard
                        if (*p != '\0') {
3152 c20709aa bellard
                            fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
3153 c4b1fcc0 bellard
                            exit(1);
3154 c4b1fcc0 bellard
                        }
3155 c20709aa bellard
                        tun_fds[nb_tun_fds++] = fd;
3156 c4b1fcc0 bellard
                    }
3157 c4b1fcc0 bellard
                }
3158 42f1e0e4 bellard
                break;
3159 cd6f1169 bellard
            case QEMU_OPTION_hdc:
3160 36b486bb bellard
                hd_filename[2] = optarg;
3161 c4b1fcc0 bellard
                has_cdrom = 0;
3162 36b486bb bellard
                break;
3163 cd6f1169 bellard
            case QEMU_OPTION_hdd:
3164 36b486bb bellard
                hd_filename[3] = optarg;
3165 36b486bb bellard
                break;
3166 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
3167 36b486bb bellard
                hd_filename[2] = optarg;
3168 c4b1fcc0 bellard
                has_cdrom = 1;
3169 36b486bb bellard
                break;
3170 cd6f1169 bellard
            case QEMU_OPTION_boot:
3171 36b486bb bellard
                boot_device = optarg[0];
3172 9e89a4be bellard
                if (boot_device != 'a' && 
3173 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
3174 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
3175 36b486bb bellard
                    exit(1);
3176 36b486bb bellard
                }
3177 36b486bb bellard
                break;
3178 cd6f1169 bellard
            case QEMU_OPTION_fda:
3179 c45886db bellard
                fd_filename[0] = optarg;
3180 c45886db bellard
                break;
3181 cd6f1169 bellard
            case QEMU_OPTION_fdb:
3182 c45886db bellard
                fd_filename[1] = optarg;
3183 c45886db bellard
                break;
3184 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
3185 77fef8c1 bellard
                code_copy_enabled = 0;
3186 77fef8c1 bellard
                break;
3187 cd6f1169 bellard
            case QEMU_OPTION_nics:
3188 c4b1fcc0 bellard
                nb_nics = atoi(optarg);
3189 3a1bc175 bellard
                if (nb_nics < 0 || nb_nics > MAX_NICS) {
3190 c4b1fcc0 bellard
                    fprintf(stderr, "qemu: invalid number of network interfaces\n");
3191 c4b1fcc0 bellard
                    exit(1);
3192 c4b1fcc0 bellard
                }
3193 c4b1fcc0 bellard
                break;
3194 cd6f1169 bellard
            case QEMU_OPTION_macaddr:
3195 702c651c bellard
                {
3196 702c651c bellard
                    const char *p;
3197 702c651c bellard
                    int i;
3198 702c651c bellard
                    p = optarg;
3199 702c651c bellard
                    for(i = 0; i < 6; i++) {
3200 702c651c bellard
                        macaddr[i] = strtol(p, (char **)&p, 16);
3201 702c651c bellard
                        if (i == 5) {
3202 702c651c bellard
                            if (*p != '\0') 
3203 702c651c bellard
                                goto macaddr_error;
3204 702c651c bellard
                        } else {
3205 702c651c bellard
                            if (*p != ':') {
3206 702c651c bellard
                            macaddr_error:
3207 702c651c bellard
                                fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
3208 702c651c bellard
                                exit(1);
3209 702c651c bellard
                            }
3210 702c651c bellard
                            p++;
3211 702c651c bellard
                        }
3212 702c651c bellard
                    }
3213 702c651c bellard
                }
3214 702c651c bellard
                break;
3215 c7f74643 bellard
#ifdef CONFIG_SLIRP
3216 c7f74643 bellard
            case QEMU_OPTION_tftp:
3217 c7f74643 bellard
                tftp_prefix = optarg;
3218 9bf05444 bellard
                break;
3219 c94c8d64 bellard
#ifndef _WIN32
3220 9d728e8c bellard
            case QEMU_OPTION_smb:
3221 9d728e8c bellard
                net_slirp_smb(optarg);
3222 9d728e8c bellard
                break;
3223 c94c8d64 bellard
#endif
3224 cd6f1169 bellard
            case QEMU_OPTION_user_net:
3225 c20709aa bellard
                net_if_type = NET_IF_USER;
3226 c20709aa bellard
                break;
3227 9bf05444 bellard
            case QEMU_OPTION_redir:
3228 9bf05444 bellard
                net_slirp_redir(optarg);                
3229 9bf05444 bellard
                break;
3230 c7f74643 bellard
#endif
3231 cd6f1169 bellard
            case QEMU_OPTION_dummy_net:
3232 c20709aa bellard
                net_if_type = NET_IF_DUMMY;
3233 c20709aa bellard
                break;
3234 cd6f1169 bellard
            case QEMU_OPTION_enable_audio:
3235 aaaa7df6 bellard
                audio_enabled = 1;
3236 aaaa7df6 bellard
                break;
3237 cd6f1169 bellard
            case QEMU_OPTION_h:
3238 0824d6fc bellard
                help();
3239 cd6f1169 bellard
                break;
3240 cd6f1169 bellard
            case QEMU_OPTION_m:
3241 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
3242 cd6f1169 bellard
                if (ram_size <= 0)
3243 cd6f1169 bellard
                    help();
3244 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
3245 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
3246 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
3247 cd6f1169 bellard
                    exit(1);
3248 cd6f1169 bellard
                }
3249 cd6f1169 bellard
                break;
3250 cd6f1169 bellard
            case QEMU_OPTION_d:
3251 cd6f1169 bellard
                {
3252 cd6f1169 bellard
                    int mask;
3253 cd6f1169 bellard
                    CPULogItem *item;
3254 cd6f1169 bellard
                    
3255 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
3256 cd6f1169 bellard
                    if (!mask) {
3257 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
3258 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
3259 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
3260 f193c797 bellard
                    }
3261 f193c797 bellard
                    exit(1);
3262 cd6f1169 bellard
                    }
3263 cd6f1169 bellard
                    cpu_set_log(mask);
3264 f193c797 bellard
                }
3265 cd6f1169 bellard
                break;
3266 cd6f1169 bellard
            case QEMU_OPTION_n:
3267 cd6f1169 bellard
                pstrcpy(network_script, sizeof(network_script), optarg);
3268 cd6f1169 bellard
                break;
3269 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3270 cd6f1169 bellard
            case QEMU_OPTION_s:
3271 cd6f1169 bellard
                use_gdbstub = 1;
3272 cd6f1169 bellard
                break;
3273 cd6f1169 bellard
            case QEMU_OPTION_p:
3274 cd6f1169 bellard
                gdbstub_port = atoi(optarg);
3275 cd6f1169 bellard
                break;
3276 67b915a5 bellard
#endif
3277 cd6f1169 bellard
            case QEMU_OPTION_L:
3278 cd6f1169 bellard
                bios_dir = optarg;
3279 cd6f1169 bellard
                break;
3280 cd6f1169 bellard
            case QEMU_OPTION_S:
3281 cd6f1169 bellard
                start_emulation = 0;
3282 cd6f1169 bellard
                break;
3283 69b91039 bellard
            case QEMU_OPTION_pci:
3284 69b91039 bellard
                pci_enabled = 1;
3285 69b91039 bellard
                break;
3286 bb0c6722 bellard
            case QEMU_OPTION_isa:
3287 bb0c6722 bellard
                pci_enabled = 0;
3288 bb0c6722 bellard
                break;
3289 77d4bc34 bellard
            case QEMU_OPTION_prep:
3290 77d4bc34 bellard
                prep_enabled = 1;
3291 77d4bc34 bellard
                break;
3292 3d11d0eb bellard
            case QEMU_OPTION_k:
3293 3d11d0eb bellard
                keyboard_layout = optarg;
3294 3d11d0eb bellard
                break;
3295 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
3296 ee22c2f7 bellard
                rtc_utc = 0;
3297 ee22c2f7 bellard
                break;
3298 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
3299 1f04275e bellard
                cirrus_vga_enabled = 1;
3300 1f04275e bellard
                break;
3301 1bfe856e bellard
            case QEMU_OPTION_std_vga:
3302 1bfe856e bellard
                cirrus_vga_enabled = 0;
3303 1bfe856e bellard
                break;
3304 e9b137c2 bellard
            case QEMU_OPTION_g:
3305 e9b137c2 bellard
                {
3306 e9b137c2 bellard
                    const char *p;
3307 e9b137c2 bellard
                    int w, h, depth;
3308 e9b137c2 bellard
                    p = optarg;
3309 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
3310 e9b137c2 bellard
                    if (w <= 0) {
3311 e9b137c2 bellard
                    graphic_error:
3312 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
3313 e9b137c2 bellard
                        exit(1);
3314 e9b137c2 bellard
                    }
3315 e9b137c2 bellard
                    if (*p != 'x')
3316 e9b137c2 bellard
                        goto graphic_error;
3317 e9b137c2 bellard
                    p++;
3318 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
3319 e9b137c2 bellard
                    if (h <= 0)
3320 e9b137c2 bellard
                        goto graphic_error;
3321 e9b137c2 bellard
                    if (*p == 'x') {
3322 e9b137c2 bellard
                        p++;
3323 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
3324 e9b137c2 bellard
                        if (depth != 8 && depth != 15 && depth != 16 && 
3325 e9b137c2 bellard
                            depth != 24 && depth != 32)
3326 e9b137c2 bellard
                            goto graphic_error;
3327 e9b137c2 bellard
                    } else if (*p == '\0') {
3328 e9b137c2 bellard
                        depth = graphic_depth;
3329 e9b137c2 bellard
                    } else {
3330 e9b137c2 bellard
                        goto graphic_error;
3331 e9b137c2 bellard
                    }
3332 e9b137c2 bellard
                    
3333 e9b137c2 bellard
                    graphic_width = w;
3334 e9b137c2 bellard
                    graphic_height = h;
3335 e9b137c2 bellard
                    graphic_depth = depth;
3336 e9b137c2 bellard
                }
3337 e9b137c2 bellard
                break;
3338 82c643ff bellard
            case QEMU_OPTION_monitor:
3339 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
3340 82c643ff bellard
                break;
3341 82c643ff bellard
            case QEMU_OPTION_serial:
3342 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
3343 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
3344 8d11df9e bellard
                    exit(1);
3345 8d11df9e bellard
                }
3346 8d11df9e bellard
                pstrcpy(serial_devices[serial_device_index], 
3347 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
3348 8d11df9e bellard
                serial_device_index++;
3349 82c643ff bellard
                break;
3350 6508fe59 bellard
            case QEMU_OPTION_parallel:
3351 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
3352 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
3353 6508fe59 bellard
                    exit(1);
3354 6508fe59 bellard
                }
3355 6508fe59 bellard
                pstrcpy(parallel_devices[parallel_device_index], 
3356 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
3357 6508fe59 bellard
                parallel_device_index++;
3358 6508fe59 bellard
                break;
3359 d63d307f bellard
            case QEMU_OPTION_loadvm:
3360 d63d307f bellard
                loadvm = optarg;
3361 d63d307f bellard
                break;
3362 d63d307f bellard
            case QEMU_OPTION_full_screen:
3363 d63d307f bellard
                full_screen = 1;
3364 d63d307f bellard
                break;
3365 f7cce898 bellard
            case QEMU_OPTION_pidfile:
3366 f7cce898 bellard
                create_pidfile(optarg);
3367 f7cce898 bellard
                break;
3368 d993e026 bellard
#ifdef USE_KQEMU
3369 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
3370 d993e026 bellard
                kqemu_allowed = 0;
3371 d993e026 bellard
                break;
3372 d993e026 bellard
#endif
3373 cd6f1169 bellard
            }
3374 0824d6fc bellard
        }
3375 0824d6fc bellard
    }
3376 330d0414 bellard
3377 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
3378 330d0414 bellard
        
3379 c45886db bellard
    if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
3380 c45886db bellard
        fd_filename[0] == '\0')
3381 0824d6fc bellard
        help();
3382 8f2b1fb0 bellard
    
3383 8f2b1fb0 bellard
    /* boot to cd by default if no hard disk */
3384 d0309311 bellard
    if (hd_filename[0] == '\0' && boot_device == 'c') {
3385 d0309311 bellard
        if (fd_filename[0] != '\0')
3386 d0309311 bellard
            boot_device = 'a';
3387 d0309311 bellard
        else
3388 d0309311 bellard
            boot_device = 'd';
3389 d0309311 bellard
    }
3390 0824d6fc bellard
3391 dc887a4d bellard
#if !defined(CONFIG_SOFTMMU)
3392 dc887a4d bellard
    /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
3393 dc887a4d bellard
    {
3394 dc887a4d bellard
        static uint8_t stdout_buf[4096];
3395 dc887a4d bellard
        setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
3396 dc887a4d bellard
    }
3397 dc887a4d bellard
#else
3398 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
3399 dc887a4d bellard
#endif
3400 0824d6fc bellard
3401 c4b1fcc0 bellard
    /* init host network redirectors */
3402 c20709aa bellard
    if (net_if_type == -1) {
3403 c20709aa bellard
        net_if_type = NET_IF_TUN;
3404 c20709aa bellard
#if defined(CONFIG_SLIRP)
3405 c20709aa bellard
        if (access(network_script, R_OK) < 0) {
3406 c20709aa bellard
            net_if_type = NET_IF_USER;
3407 c20709aa bellard
        }
3408 c20709aa bellard
#endif
3409 c20709aa bellard
    }
3410 c20709aa bellard
3411 c20709aa bellard
    for(i = 0; i < nb_nics; i++) {
3412 702c651c bellard
        NetDriverState *nd = &nd_table[i];
3413 c20709aa bellard
        nd->index = i;
3414 702c651c bellard
        /* init virtual mac address */
3415 702c651c bellard
        nd->macaddr[0] = macaddr[0];
3416 702c651c bellard
        nd->macaddr[1] = macaddr[1];
3417 702c651c bellard
        nd->macaddr[2] = macaddr[2];
3418 702c651c bellard
        nd->macaddr[3] = macaddr[3];
3419 702c651c bellard
        nd->macaddr[4] = macaddr[4];
3420 702c651c bellard
        nd->macaddr[5] = macaddr[5] + i;
3421 c20709aa bellard
        switch(net_if_type) {
3422 c20709aa bellard
#if defined(CONFIG_SLIRP)
3423 c20709aa bellard
        case NET_IF_USER:
3424 c20709aa bellard
            net_slirp_init(nd);
3425 c20709aa bellard
            break;
3426 c20709aa bellard
#endif
3427 c20709aa bellard
#if !defined(_WIN32)
3428 c20709aa bellard
        case NET_IF_TUN:
3429 c20709aa bellard
            if (i < nb_tun_fds) {
3430 c20709aa bellard
                net_fd_init(nd, tun_fds[i]);
3431 c20709aa bellard
            } else {
3432 d927637d bellard
                if (net_tun_init(nd) < 0)
3433 d927637d bellard
                    net_dummy_init(nd);
3434 c20709aa bellard
            }
3435 c20709aa bellard
            break;
3436 c20709aa bellard
#endif
3437 c20709aa bellard
        case NET_IF_DUMMY:
3438 c20709aa bellard
        default:
3439 c20709aa bellard
            net_dummy_init(nd);
3440 c20709aa bellard
            break;
3441 c20709aa bellard
        }
3442 702c651c bellard
    }
3443 f1510b2c bellard
3444 0824d6fc bellard
    /* init the memory */
3445 0ced6589 bellard
    phys_ram_size = ram_size + vga_ram_size + bios_size;
3446 7f7f9873 bellard
3447 7f7f9873 bellard
#ifdef CONFIG_SOFTMMU
3448 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
3449 7f7f9873 bellard
    if (!phys_ram_base) {
3450 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
3451 0824d6fc bellard
        exit(1);
3452 0824d6fc bellard
    }
3453 7f7f9873 bellard
#else
3454 7f7f9873 bellard
    /* as we must map the same page at several addresses, we must use
3455 7f7f9873 bellard
       a fd */
3456 7f7f9873 bellard
    {
3457 7f7f9873 bellard
        const char *tmpdir;
3458 7f7f9873 bellard
3459 7f7f9873 bellard
        tmpdir = getenv("QEMU_TMPDIR");
3460 7f7f9873 bellard
        if (!tmpdir)
3461 7f7f9873 bellard
            tmpdir = "/tmp";
3462 7f7f9873 bellard
        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir);
3463 7f7f9873 bellard
        if (mkstemp(phys_ram_file) < 0) {
3464 7f7f9873 bellard
            fprintf(stderr, "Could not create temporary memory file '%s'\n", 
3465 7f7f9873 bellard
                    phys_ram_file);
3466 7f7f9873 bellard
            exit(1);
3467 7f7f9873 bellard
        }
3468 7f7f9873 bellard
        phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600);
3469 7f7f9873 bellard
        if (phys_ram_fd < 0) {
3470 7f7f9873 bellard
            fprintf(stderr, "Could not open temporary memory file '%s'\n", 
3471 7f7f9873 bellard
                    phys_ram_file);
3472 7f7f9873 bellard
            exit(1);
3473 7f7f9873 bellard
        }
3474 1ccde1cb bellard
        ftruncate(phys_ram_fd, phys_ram_size);
3475 7f7f9873 bellard
        unlink(phys_ram_file);
3476 1ccde1cb bellard
        phys_ram_base = mmap(get_mmap_addr(phys_ram_size), 
3477 1ccde1cb bellard
                             phys_ram_size, 
3478 7f7f9873 bellard
                             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, 
3479 7f7f9873 bellard
                             phys_ram_fd, 0);
3480 7f7f9873 bellard
        if (phys_ram_base == MAP_FAILED) {
3481 7f7f9873 bellard
            fprintf(stderr, "Could not map physical memory\n");
3482 7f7f9873 bellard
            exit(1);
3483 7f7f9873 bellard
        }
3484 7f7f9873 bellard
    }
3485 7f7f9873 bellard
#endif
3486 0824d6fc bellard
3487 c4b1fcc0 bellard
    /* we always create the cdrom drive, even if no disk is there */
3488 5905b2e5 bellard
    bdrv_init();
3489 c4b1fcc0 bellard
    if (has_cdrom) {
3490 c4b1fcc0 bellard
        bs_table[2] = bdrv_new("cdrom");
3491 c4b1fcc0 bellard
        bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
3492 c4b1fcc0 bellard
    }
3493 c4b1fcc0 bellard
3494 33e3963e bellard
    /* open the virtual block devices */
3495 33e3963e bellard
    for(i = 0; i < MAX_DISKS; i++) {
3496 33e3963e bellard
        if (hd_filename[i]) {
3497 33e3963e bellard
            if (!bs_table[i]) {
3498 c4b1fcc0 bellard
                char buf[64];
3499 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
3500 c4b1fcc0 bellard
                bs_table[i] = bdrv_new(buf);
3501 c4b1fcc0 bellard
            }
3502 c4b1fcc0 bellard
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
3503 5905b2e5 bellard
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
3504 33e3963e bellard
                        hd_filename[i]);
3505 33e3963e bellard
                exit(1);
3506 33e3963e bellard
            }
3507 46d4767d bellard
            if (i == 0 && cyls != 0) {
3508 c4b1fcc0 bellard
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
3509 46d4767d bellard
                bdrv_set_translation_hint(bs_table[i], translation);
3510 46d4767d bellard
            }
3511 c4b1fcc0 bellard
        }
3512 c4b1fcc0 bellard
    }
3513 c4b1fcc0 bellard
3514 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
3515 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
3516 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
3517 c4b1fcc0 bellard
3518 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
3519 c4b1fcc0 bellard
        if (fd_filename[i]) {
3520 c4b1fcc0 bellard
            if (!fd_table[i]) {
3521 c4b1fcc0 bellard
                char buf[64];
3522 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
3523 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
3524 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
3525 c4b1fcc0 bellard
            }
3526 c4b1fcc0 bellard
            if (fd_filename[i] != '\0') {
3527 c4b1fcc0 bellard
                if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
3528 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
3529 c4b1fcc0 bellard
                            fd_filename[i]);
3530 c4b1fcc0 bellard
                    exit(1);
3531 c4b1fcc0 bellard
                }
3532 c4b1fcc0 bellard
            }
3533 33e3963e bellard
        }
3534 33e3963e bellard
    }
3535 33e3963e bellard
3536 330d0414 bellard
    /* init CPU state */
3537 330d0414 bellard
    env = cpu_init();
3538 330d0414 bellard
    global_env = env;
3539 330d0414 bellard
    cpu_single_env = env;
3540 330d0414 bellard
3541 8a7ddc38 bellard
    register_savevm("timer", 0, 1, timer_save, timer_load, env);
3542 664e0f19 bellard
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
3543 8a7ddc38 bellard
    register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
3544 bb0c6722 bellard
    qemu_register_reset(main_cpu_reset, global_env);
3545 8a7ddc38 bellard
3546 330d0414 bellard
    init_ioports();
3547 80cabfad bellard
    cpu_calibrate_ticks();
3548 0824d6fc bellard
3549 313aa567 bellard
    /* terminal init */
3550 a20dd508 bellard
    if (nographic) {
3551 313aa567 bellard
        dumb_display_init(ds);
3552 313aa567 bellard
    } else {
3553 313aa567 bellard
#ifdef CONFIG_SDL
3554 d63d307f bellard
        sdl_display_init(ds, full_screen);
3555 313aa567 bellard
#else
3556 313aa567 bellard
        dumb_display_init(ds);
3557 313aa567 bellard
#endif
3558 313aa567 bellard
    }
3559 0824d6fc bellard
3560 82c643ff bellard
    vga_console = graphic_console_init(ds);
3561 82c643ff bellard
    
3562 82c643ff bellard
    monitor_hd = qemu_chr_open(monitor_device);
3563 82c643ff bellard
    if (!monitor_hd) {
3564 82c643ff bellard
        fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
3565 82c643ff bellard
        exit(1);
3566 82c643ff bellard
    }
3567 82c643ff bellard
    monitor_init(monitor_hd, !nographic);
3568 82c643ff bellard
3569 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
3570 8d11df9e bellard
        if (serial_devices[i][0] != '\0') {
3571 8d11df9e bellard
            serial_hds[i] = qemu_chr_open(serial_devices[i]);
3572 8d11df9e bellard
            if (!serial_hds[i]) {
3573 8d11df9e bellard
                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
3574 8d11df9e bellard
                        serial_devices[i]);
3575 8d11df9e bellard
                exit(1);
3576 8d11df9e bellard
            }
3577 8d11df9e bellard
            if (!strcmp(serial_devices[i], "vc"))
3578 8d11df9e bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
3579 8d11df9e bellard
        }
3580 82c643ff bellard
    }
3581 82c643ff bellard
3582 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
3583 6508fe59 bellard
        if (parallel_devices[i][0] != '\0') {
3584 6508fe59 bellard
            parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
3585 6508fe59 bellard
            if (!parallel_hds[i]) {
3586 6508fe59 bellard
                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
3587 6508fe59 bellard
                        parallel_devices[i]);
3588 6508fe59 bellard
                exit(1);
3589 6508fe59 bellard
            }
3590 6508fe59 bellard
            if (!strcmp(parallel_devices[i], "vc"))
3591 6508fe59 bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\n", i);
3592 6508fe59 bellard
        }
3593 6508fe59 bellard
    }
3594 6508fe59 bellard
3595 0824d6fc bellard
    /* setup cpu signal handlers for MMU / self modifying code handling */
3596 77fef8c1 bellard
#if !defined(CONFIG_SOFTMMU)
3597 8a7ddc38 bellard
    
3598 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
3599 77fef8c1 bellard
    {
3600 77fef8c1 bellard
        stack_t stk;
3601 73332e5c bellard
        signal_stack = memalign(16, SIGNAL_STACK_SIZE);
3602 77fef8c1 bellard
        stk.ss_sp = signal_stack;
3603 77fef8c1 bellard
        stk.ss_size = SIGNAL_STACK_SIZE;
3604 77fef8c1 bellard
        stk.ss_flags = 0;
3605 77fef8c1 bellard
3606 77fef8c1 bellard
        if (sigaltstack(&stk, NULL) < 0) {
3607 77fef8c1 bellard
            perror("sigaltstack");
3608 77fef8c1 bellard
            exit(1);
3609 77fef8c1 bellard
        }
3610 77fef8c1 bellard
    }
3611 77fef8c1 bellard
#endif
3612 8a7ddc38 bellard
    {
3613 8a7ddc38 bellard
        struct sigaction act;
3614 77fef8c1 bellard
        
3615 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
3616 8a7ddc38 bellard
        act.sa_flags = SA_SIGINFO;
3617 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
3618 8a7ddc38 bellard
        act.sa_flags |= SA_ONSTACK;
3619 77fef8c1 bellard
#endif
3620 8a7ddc38 bellard
        act.sa_sigaction = host_segv_handler;
3621 8a7ddc38 bellard
        sigaction(SIGSEGV, &act, NULL);
3622 8a7ddc38 bellard
        sigaction(SIGBUS, &act, NULL);
3623 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
3624 8a7ddc38 bellard
        sigaction(SIGFPE, &act, NULL);
3625 77fef8c1 bellard
#endif
3626 8a7ddc38 bellard
    }
3627 3a51dee6 bellard
#endif
3628 0824d6fc bellard
3629 67b915a5 bellard
#ifndef _WIN32
3630 8a7ddc38 bellard
    {
3631 8a7ddc38 bellard
        struct sigaction act;
3632 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
3633 8a7ddc38 bellard
        act.sa_flags = 0;
3634 8a7ddc38 bellard
        act.sa_handler = SIG_IGN;
3635 8a7ddc38 bellard
        sigaction(SIGPIPE, &act, NULL);
3636 8a7ddc38 bellard
    }
3637 67b915a5 bellard
#endif
3638 73332e5c bellard
    init_timers();
3639 73332e5c bellard
3640 73332e5c bellard
#if defined(TARGET_I386)
3641 73332e5c bellard
    pc_init(ram_size, vga_ram_size, boot_device,
3642 73332e5c bellard
            ds, fd_filename, snapshot,
3643 73332e5c bellard
            kernel_filename, kernel_cmdline, initrd_filename);
3644 73332e5c bellard
#elif defined(TARGET_PPC)
3645 a541f297 bellard
    ppc_init(ram_size, vga_ram_size, boot_device,
3646 a541f297 bellard
             ds, fd_filename, snapshot,
3647 a541f297 bellard
             kernel_filename, kernel_cmdline, initrd_filename);
3648 e95c8d51 bellard
#elif defined(TARGET_SPARC)
3649 e95c8d51 bellard
    sun4m_init(ram_size, vga_ram_size, boot_device,
3650 e95c8d51 bellard
            ds, fd_filename, snapshot,
3651 e95c8d51 bellard
            kernel_filename, kernel_cmdline, initrd_filename);
3652 73332e5c bellard
#endif
3653 73332e5c bellard
3654 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
3655 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
3656 7f7f9873 bellard
3657 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
3658 b4608c04 bellard
    if (use_gdbstub) {
3659 8a7ddc38 bellard
        if (gdbserver_start(gdbstub_port) < 0) {
3660 8a7ddc38 bellard
            fprintf(stderr, "Could not open gdbserver socket on port %d\n", 
3661 8a7ddc38 bellard
                    gdbstub_port);
3662 8a7ddc38 bellard
            exit(1);
3663 8a7ddc38 bellard
        } else {
3664 8a7ddc38 bellard
            printf("Waiting gdb connection on port %d\n", gdbstub_port);
3665 8a7ddc38 bellard
        }
3666 67b915a5 bellard
    } else 
3667 67b915a5 bellard
#endif
3668 d63d307f bellard
    if (loadvm)
3669 d63d307f bellard
        qemu_loadvm(loadvm);
3670 d63d307f bellard
3671 67b915a5 bellard
    {
3672 5905b2e5 bellard
        /* XXX: simplify init */
3673 5905b2e5 bellard
        read_passwords();
3674 5905b2e5 bellard
        if (start_emulation) {
3675 5905b2e5 bellard
            vm_start();
3676 5905b2e5 bellard
        }
3677 0824d6fc bellard
    }
3678 8a7ddc38 bellard
    main_loop();
3679 40c3bac3 bellard
    quit_timers();
3680 0824d6fc bellard
    return 0;
3681 0824d6fc bellard
}