Statistics
| Branch: | Revision:

root / vl.c @ 6f7e9aec

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