Statistics
| Branch: | Revision:

root / vl.c @ 4fa5d772

History | View | Annotate | Download (96.1 kB)

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