Statistics
| Branch: | Revision:

root / vl.c @ 8636b5d8

History | View | Annotate | Download (94.8 kB)

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