Statistics
| Branch: | Revision:

root / vl.c @ 678f2df6

History | View | Annotate | Download (69.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 7d3505c5 bellard
#ifdef _BSD
42 7d3505c5 bellard
#include <sys/stat.h>
43 7d3505c5 bellard
#include <libutil.h>
44 7d3505c5 bellard
#else
45 f1510b2c bellard
#include <linux/if.h>
46 f1510b2c bellard
#include <linux/if_tun.h>
47 7d3505c5 bellard
#include <pty.h>
48 7d3505c5 bellard
#include <malloc.h>
49 fd872598 bellard
#include <linux/rtc.h>
50 67b915a5 bellard
#endif
51 7d3505c5 bellard
#endif
52 67b915a5 bellard
53 c20709aa bellard
#if defined(CONFIG_SLIRP)
54 c20709aa bellard
#include "libslirp.h"
55 c20709aa bellard
#endif
56 c20709aa bellard
57 67b915a5 bellard
#ifdef _WIN32
58 7d3505c5 bellard
#include <malloc.h>
59 67b915a5 bellard
#include <sys/timeb.h>
60 67b915a5 bellard
#include <windows.h>
61 67b915a5 bellard
#define getopt_long_only getopt_long
62 67b915a5 bellard
#define memalign(align, size) malloc(size)
63 67b915a5 bellard
#endif
64 67b915a5 bellard
65 73332e5c bellard
#ifdef CONFIG_SDL
66 7d3505c5 bellard
#if defined(__linux__)
67 73332e5c bellard
/* SDL use the pthreads and they modify sigaction. We don't
68 73332e5c bellard
   want that. */
69 7d3505c5 bellard
#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2))
70 73332e5c bellard
extern void __libc_sigaction();
71 73332e5c bellard
#define sigaction(sig, act, oact) __libc_sigaction(sig, act, oact)
72 73332e5c bellard
#else
73 73332e5c bellard
extern void __sigaction();
74 73332e5c bellard
#define sigaction(sig, act, oact) __sigaction(sig, act, oact)
75 73332e5c bellard
#endif
76 7d3505c5 bellard
#endif /* __linux__ */
77 73332e5c bellard
#endif /* CONFIG_SDL */
78 0824d6fc bellard
79 0824d6fc bellard
#include "disas.h"
80 fc01f7e7 bellard
81 8a7ddc38 bellard
#include "exec-all.h"
82 0824d6fc bellard
83 a541f297 bellard
//#define DO_TB_FLUSH
84 a541f297 bellard
85 5a67135a bellard
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
86 f1510b2c bellard
87 0824d6fc bellard
//#define DEBUG_UNUSED_IOPORT
88 fd872598 bellard
//#define DEBUG_IOPORT
89 330d0414 bellard
90 bb551faa bellard
#if !defined(CONFIG_SOFTMMU)
91 7916e224 bellard
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
92 bb551faa bellard
#else
93 bb551faa bellard
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
94 bb551faa bellard
#endif
95 7916e224 bellard
96 77d4bc34 bellard
#ifdef TARGET_PPC
97 77d4bc34 bellard
#define DEFAULT_RAM_SIZE 144
98 77d4bc34 bellard
#else
99 a00bad7e bellard
#define DEFAULT_RAM_SIZE 32
100 77d4bc34 bellard
#endif
101 8a7ddc38 bellard
/* in ms */
102 8a7ddc38 bellard
#define GUI_REFRESH_INTERVAL 30
103 313aa567 bellard
104 7dea1da4 bellard
/* XXX: use a two level table to limit memory usage */
105 7dea1da4 bellard
#define MAX_IOPORTS 65536
106 0824d6fc bellard
107 80cabfad bellard
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
108 0824d6fc bellard
char phys_ram_file[1024];
109 c45886db bellard
CPUState *global_env;
110 c45886db bellard
CPUState *cpu_single_env;
111 c4b1fcc0 bellard
void *ioport_opaque[MAX_IOPORTS];
112 fc01f7e7 bellard
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
113 fc01f7e7 bellard
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
114 c45886db bellard
BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
115 313aa567 bellard
int vga_ram_size;
116 0ced6589 bellard
int bios_size;
117 313aa567 bellard
static DisplayState display_state;
118 a20dd508 bellard
int nographic;
119 313aa567 bellard
int64_t ticks_per_sec;
120 36b486bb bellard
int boot_device = 'c';
121 0ced6589 bellard
int ram_size;
122 80cabfad bellard
static char network_script[1024];
123 80cabfad bellard
int pit_min_timer_count = 0;
124 c4b1fcc0 bellard
int nb_nics;
125 c4b1fcc0 bellard
NetDriverState nd_table[MAX_NICS];
126 c4b1fcc0 bellard
SerialState *serial_console;
127 8a7ddc38 bellard
QEMUTimer *gui_timer;
128 8a7ddc38 bellard
int vm_running;
129 aaaa7df6 bellard
int audio_enabled = 0;
130 bb0c6722 bellard
int pci_enabled = 1;
131 77d4bc34 bellard
int prep_enabled = 0;
132 ee22c2f7 bellard
int rtc_utc = 1;
133 1f04275e bellard
int cirrus_vga_enabled = 0;
134 0824d6fc bellard
135 0824d6fc bellard
/***********************************************************/
136 26aa7d72 bellard
/* x86 ISA bus support */
137 26aa7d72 bellard
138 26aa7d72 bellard
target_phys_addr_t isa_mem_base = 0;
139 0824d6fc bellard
140 c4b1fcc0 bellard
uint32_t default_ioport_readb(void *opaque, uint32_t address)
141 0824d6fc bellard
{
142 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
143 0824d6fc bellard
    fprintf(stderr, "inb: port=0x%04x\n", address);
144 0824d6fc bellard
#endif
145 fc01f7e7 bellard
    return 0xff;
146 0824d6fc bellard
}
147 0824d6fc bellard
148 c4b1fcc0 bellard
void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
149 0824d6fc bellard
{
150 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
151 0824d6fc bellard
    fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
152 0824d6fc bellard
#endif
153 0824d6fc bellard
}
154 0824d6fc bellard
155 0824d6fc bellard
/* default is to make two byte accesses */
156 c4b1fcc0 bellard
uint32_t default_ioport_readw(void *opaque, uint32_t address)
157 0824d6fc bellard
{
158 0824d6fc bellard
    uint32_t data;
159 db45c29a bellard
    data = ioport_read_table[0][address](ioport_opaque[address], address);
160 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
161 db45c29a bellard
    data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
162 0824d6fc bellard
    return data;
163 0824d6fc bellard
}
164 0824d6fc bellard
165 c4b1fcc0 bellard
void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
166 0824d6fc bellard
{
167 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
168 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
169 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
170 0824d6fc bellard
}
171 0824d6fc bellard
172 c4b1fcc0 bellard
uint32_t default_ioport_readl(void *opaque, uint32_t address)
173 0824d6fc bellard
{
174 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
175 fc01f7e7 bellard
    fprintf(stderr, "inl: port=0x%04x\n", address);
176 fc01f7e7 bellard
#endif
177 fc01f7e7 bellard
    return 0xffffffff;
178 0824d6fc bellard
}
179 0824d6fc bellard
180 c4b1fcc0 bellard
void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
181 0824d6fc bellard
{
182 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
183 fc01f7e7 bellard
    fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
184 fc01f7e7 bellard
#endif
185 0824d6fc bellard
}
186 0824d6fc bellard
187 fc01f7e7 bellard
void init_ioports(void)
188 0824d6fc bellard
{
189 0824d6fc bellard
    int i;
190 0824d6fc bellard
191 fc01f7e7 bellard
    for(i = 0; i < MAX_IOPORTS; i++) {
192 fc01f7e7 bellard
        ioport_read_table[0][i] = default_ioport_readb;
193 fc01f7e7 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
194 fc01f7e7 bellard
        ioport_read_table[1][i] = default_ioport_readw;
195 fc01f7e7 bellard
        ioport_write_table[1][i] = default_ioport_writew;
196 fc01f7e7 bellard
        ioport_read_table[2][i] = default_ioport_readl;
197 fc01f7e7 bellard
        ioport_write_table[2][i] = default_ioport_writel;
198 fc01f7e7 bellard
    }
199 0824d6fc bellard
}
200 0824d6fc bellard
201 fc01f7e7 bellard
/* size is the word size in byte */
202 c4b1fcc0 bellard
int register_ioport_read(int start, int length, int size, 
203 c4b1fcc0 bellard
                         IOPortReadFunc *func, void *opaque)
204 f1510b2c bellard
{
205 fc01f7e7 bellard
    int i, bsize;
206 f1510b2c bellard
207 c4b1fcc0 bellard
    if (size == 1) {
208 fc01f7e7 bellard
        bsize = 0;
209 c4b1fcc0 bellard
    } else if (size == 2) {
210 fc01f7e7 bellard
        bsize = 1;
211 c4b1fcc0 bellard
    } else if (size == 4) {
212 fc01f7e7 bellard
        bsize = 2;
213 c4b1fcc0 bellard
    } else {
214 c4b1fcc0 bellard
        hw_error("register_ioport_read: invalid size");
215 fc01f7e7 bellard
        return -1;
216 c4b1fcc0 bellard
    }
217 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
218 fc01f7e7 bellard
        ioport_read_table[bsize][i] = func;
219 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
220 c4b1fcc0 bellard
            hw_error("register_ioport_read: invalid opaque");
221 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
222 c4b1fcc0 bellard
    }
223 f1510b2c bellard
    return 0;
224 f1510b2c bellard
}
225 f1510b2c bellard
226 fc01f7e7 bellard
/* size is the word size in byte */
227 c4b1fcc0 bellard
int register_ioport_write(int start, int length, int size, 
228 c4b1fcc0 bellard
                          IOPortWriteFunc *func, void *opaque)
229 f1510b2c bellard
{
230 fc01f7e7 bellard
    int i, bsize;
231 f1510b2c bellard
232 c4b1fcc0 bellard
    if (size == 1) {
233 fc01f7e7 bellard
        bsize = 0;
234 c4b1fcc0 bellard
    } else if (size == 2) {
235 fc01f7e7 bellard
        bsize = 1;
236 c4b1fcc0 bellard
    } else if (size == 4) {
237 fc01f7e7 bellard
        bsize = 2;
238 c4b1fcc0 bellard
    } else {
239 c4b1fcc0 bellard
        hw_error("register_ioport_write: invalid size");
240 fc01f7e7 bellard
        return -1;
241 c4b1fcc0 bellard
    }
242 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
243 fc01f7e7 bellard
        ioport_write_table[bsize][i] = func;
244 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
245 c4b1fcc0 bellard
            hw_error("register_ioport_read: invalid opaque");
246 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
247 c4b1fcc0 bellard
    }
248 f1510b2c bellard
    return 0;
249 f1510b2c bellard
}
250 f1510b2c bellard
251 69b91039 bellard
void isa_unassign_ioport(int start, int length)
252 69b91039 bellard
{
253 69b91039 bellard
    int i;
254 69b91039 bellard
255 69b91039 bellard
    for(i = start; i < start + length; i++) {
256 69b91039 bellard
        ioport_read_table[0][i] = default_ioport_readb;
257 69b91039 bellard
        ioport_read_table[1][i] = default_ioport_readw;
258 69b91039 bellard
        ioport_read_table[2][i] = default_ioport_readl;
259 69b91039 bellard
260 69b91039 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
261 69b91039 bellard
        ioport_write_table[1][i] = default_ioport_writew;
262 69b91039 bellard
        ioport_write_table[2][i] = default_ioport_writel;
263 69b91039 bellard
    }
264 69b91039 bellard
}
265 69b91039 bellard
266 0824d6fc bellard
void pstrcpy(char *buf, int buf_size, const char *str)
267 0824d6fc bellard
{
268 0824d6fc bellard
    int c;
269 0824d6fc bellard
    char *q = buf;
270 0824d6fc bellard
271 0824d6fc bellard
    if (buf_size <= 0)
272 0824d6fc bellard
        return;
273 0824d6fc bellard
274 0824d6fc bellard
    for(;;) {
275 0824d6fc bellard
        c = *str++;
276 0824d6fc bellard
        if (c == 0 || q >= buf + buf_size - 1)
277 0824d6fc bellard
            break;
278 0824d6fc bellard
        *q++ = c;
279 0824d6fc bellard
    }
280 0824d6fc bellard
    *q = '\0';
281 0824d6fc bellard
}
282 0824d6fc bellard
283 0824d6fc bellard
/* strcat and truncate. */
284 0824d6fc bellard
char *pstrcat(char *buf, int buf_size, const char *s)
285 0824d6fc bellard
{
286 0824d6fc bellard
    int len;
287 0824d6fc bellard
    len = strlen(buf);
288 0824d6fc bellard
    if (len < buf_size) 
289 0824d6fc bellard
        pstrcpy(buf + len, buf_size - len, s);
290 0824d6fc bellard
    return buf;
291 0824d6fc bellard
}
292 0824d6fc bellard
293 0824d6fc bellard
/* return the size or -1 if error */
294 0824d6fc bellard
int load_image(const char *filename, uint8_t *addr)
295 0824d6fc bellard
{
296 0824d6fc bellard
    int fd, size;
297 40c3bac3 bellard
    fd = open(filename, O_RDONLY | O_BINARY);
298 0824d6fc bellard
    if (fd < 0)
299 0824d6fc bellard
        return -1;
300 0824d6fc bellard
    size = lseek(fd, 0, SEEK_END);
301 0824d6fc bellard
    lseek(fd, 0, SEEK_SET);
302 0824d6fc bellard
    if (read(fd, addr, size) != size) {
303 0824d6fc bellard
        close(fd);
304 0824d6fc bellard
        return -1;
305 0824d6fc bellard
    }
306 0824d6fc bellard
    close(fd);
307 0824d6fc bellard
    return size;
308 0824d6fc bellard
}
309 0824d6fc bellard
310 c45886db bellard
void cpu_outb(CPUState *env, int addr, int val)
311 0824d6fc bellard
{
312 fd872598 bellard
#ifdef DEBUG_IOPORT
313 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
314 fd872598 bellard
        fprintf(logfile, "outb: %04x %02x\n", addr, val);
315 fd872598 bellard
#endif    
316 c4b1fcc0 bellard
    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
317 0824d6fc bellard
}
318 0824d6fc bellard
319 c45886db bellard
void cpu_outw(CPUState *env, int addr, int val)
320 0824d6fc bellard
{
321 fd872598 bellard
#ifdef DEBUG_IOPORT
322 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
323 fd872598 bellard
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
324 fd872598 bellard
#endif    
325 c4b1fcc0 bellard
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
326 0824d6fc bellard
}
327 0824d6fc bellard
328 c45886db bellard
void cpu_outl(CPUState *env, int addr, int val)
329 0824d6fc bellard
{
330 fd872598 bellard
#ifdef DEBUG_IOPORT
331 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
332 fd872598 bellard
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
333 fd872598 bellard
#endif
334 c4b1fcc0 bellard
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
335 0824d6fc bellard
}
336 0824d6fc bellard
337 c45886db bellard
int cpu_inb(CPUState *env, int addr)
338 0824d6fc bellard
{
339 fd872598 bellard
    int val;
340 fd872598 bellard
    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
341 fd872598 bellard
#ifdef DEBUG_IOPORT
342 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
343 fd872598 bellard
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
344 fd872598 bellard
#endif
345 fd872598 bellard
    return val;
346 0824d6fc bellard
}
347 0824d6fc bellard
348 c45886db bellard
int cpu_inw(CPUState *env, int addr)
349 0824d6fc bellard
{
350 fd872598 bellard
    int val;
351 fd872598 bellard
    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
352 fd872598 bellard
#ifdef DEBUG_IOPORT
353 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
354 fd872598 bellard
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
355 fd872598 bellard
#endif
356 fd872598 bellard
    return val;
357 0824d6fc bellard
}
358 0824d6fc bellard
359 c45886db bellard
int cpu_inl(CPUState *env, int addr)
360 0824d6fc bellard
{
361 fd872598 bellard
    int val;
362 fd872598 bellard
    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
363 fd872598 bellard
#ifdef DEBUG_IOPORT
364 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
365 fd872598 bellard
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
366 fd872598 bellard
#endif
367 fd872598 bellard
    return val;
368 0824d6fc bellard
}
369 0824d6fc bellard
370 0824d6fc bellard
/***********************************************************/
371 0824d6fc bellard
void hw_error(const char *fmt, ...)
372 0824d6fc bellard
{
373 0824d6fc bellard
    va_list ap;
374 0824d6fc bellard
375 0824d6fc bellard
    va_start(ap, fmt);
376 0824d6fc bellard
    fprintf(stderr, "qemu: hardware error: ");
377 0824d6fc bellard
    vfprintf(stderr, fmt, ap);
378 0824d6fc bellard
    fprintf(stderr, "\n");
379 0824d6fc bellard
#ifdef TARGET_I386
380 0824d6fc bellard
    cpu_x86_dump_state(global_env, stderr, X86_DUMP_FPU | X86_DUMP_CCOP);
381 c45886db bellard
#else
382 c45886db bellard
    cpu_dump_state(global_env, stderr, 0);
383 0824d6fc bellard
#endif
384 0824d6fc bellard
    va_end(ap);
385 0824d6fc bellard
    abort();
386 0824d6fc bellard
}
387 0824d6fc bellard
388 8a7ddc38 bellard
/***********************************************************/
389 63066f4f bellard
/* keyboard/mouse */
390 63066f4f bellard
391 63066f4f bellard
static QEMUPutKBDEvent *qemu_put_kbd_event;
392 63066f4f bellard
static void *qemu_put_kbd_event_opaque;
393 63066f4f bellard
static QEMUPutMouseEvent *qemu_put_mouse_event;
394 63066f4f bellard
static void *qemu_put_mouse_event_opaque;
395 63066f4f bellard
396 63066f4f bellard
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
397 63066f4f bellard
{
398 63066f4f bellard
    qemu_put_kbd_event_opaque = opaque;
399 63066f4f bellard
    qemu_put_kbd_event = func;
400 63066f4f bellard
}
401 63066f4f bellard
402 63066f4f bellard
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
403 63066f4f bellard
{
404 63066f4f bellard
    qemu_put_mouse_event_opaque = opaque;
405 63066f4f bellard
    qemu_put_mouse_event = func;
406 63066f4f bellard
}
407 63066f4f bellard
408 63066f4f bellard
void kbd_put_keycode(int keycode)
409 63066f4f bellard
{
410 63066f4f bellard
    if (qemu_put_kbd_event) {
411 63066f4f bellard
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
412 63066f4f bellard
    }
413 63066f4f bellard
}
414 63066f4f bellard
415 63066f4f bellard
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
416 63066f4f bellard
{
417 63066f4f bellard
    if (qemu_put_mouse_event) {
418 63066f4f bellard
        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
419 63066f4f bellard
                             dx, dy, dz, buttons_state);
420 63066f4f bellard
    }
421 63066f4f bellard
}
422 63066f4f bellard
423 63066f4f bellard
/***********************************************************/
424 8a7ddc38 bellard
/* timers */
425 8a7ddc38 bellard
426 34865134 bellard
#if defined(__powerpc__)
427 34865134 bellard
428 34865134 bellard
static inline uint32_t get_tbl(void) 
429 0824d6fc bellard
{
430 34865134 bellard
    uint32_t tbl;
431 34865134 bellard
    asm volatile("mftb %0" : "=r" (tbl));
432 34865134 bellard
    return tbl;
433 0824d6fc bellard
}
434 0824d6fc bellard
435 34865134 bellard
static inline uint32_t get_tbu(void) 
436 34865134 bellard
{
437 34865134 bellard
        uint32_t tbl;
438 34865134 bellard
        asm volatile("mftbu %0" : "=r" (tbl));
439 34865134 bellard
        return tbl;
440 34865134 bellard
}
441 34865134 bellard
442 34865134 bellard
int64_t cpu_get_real_ticks(void)
443 34865134 bellard
{
444 34865134 bellard
    uint32_t l, h, h1;
445 34865134 bellard
    /* NOTE: we test if wrapping has occurred */
446 34865134 bellard
    do {
447 34865134 bellard
        h = get_tbu();
448 34865134 bellard
        l = get_tbl();
449 34865134 bellard
        h1 = get_tbu();
450 34865134 bellard
    } while (h != h1);
451 34865134 bellard
    return ((int64_t)h << 32) | l;
452 34865134 bellard
}
453 34865134 bellard
454 34865134 bellard
#elif defined(__i386__)
455 34865134 bellard
456 34865134 bellard
int64_t cpu_get_real_ticks(void)
457 0824d6fc bellard
{
458 0824d6fc bellard
    int64_t val;
459 e463b581 bellard
    asm volatile ("rdtsc" : "=A" (val));
460 0824d6fc bellard
    return val;
461 0824d6fc bellard
}
462 0824d6fc bellard
463 1115dde7 bellard
#elif defined(__x86_64__)
464 1115dde7 bellard
465 1115dde7 bellard
int64_t cpu_get_real_ticks(void)
466 1115dde7 bellard
{
467 1115dde7 bellard
    uint32_t low,high;
468 1115dde7 bellard
    int64_t val;
469 1115dde7 bellard
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
470 1115dde7 bellard
    val = high;
471 1115dde7 bellard
    val <<= 32;
472 1115dde7 bellard
    val |= low;
473 1115dde7 bellard
    return val;
474 1115dde7 bellard
}
475 1115dde7 bellard
476 34865134 bellard
#else
477 34865134 bellard
#error unsupported CPU
478 34865134 bellard
#endif
479 34865134 bellard
480 34865134 bellard
static int64_t cpu_ticks_offset;
481 8a7ddc38 bellard
static int cpu_ticks_enabled;
482 34865134 bellard
483 8a7ddc38 bellard
static inline int64_t cpu_get_ticks(void)
484 34865134 bellard
{
485 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
486 8a7ddc38 bellard
        return cpu_ticks_offset;
487 8a7ddc38 bellard
    } else {
488 8a7ddc38 bellard
        return cpu_get_real_ticks() + cpu_ticks_offset;
489 8a7ddc38 bellard
    }
490 34865134 bellard
}
491 34865134 bellard
492 34865134 bellard
/* enable cpu_get_ticks() */
493 34865134 bellard
void cpu_enable_ticks(void)
494 34865134 bellard
{
495 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
496 8a7ddc38 bellard
        cpu_ticks_offset -= cpu_get_real_ticks();
497 8a7ddc38 bellard
        cpu_ticks_enabled = 1;
498 8a7ddc38 bellard
    }
499 34865134 bellard
}
500 34865134 bellard
501 34865134 bellard
/* disable cpu_get_ticks() : the clock is stopped. You must not call
502 34865134 bellard
   cpu_get_ticks() after that.  */
503 34865134 bellard
void cpu_disable_ticks(void)
504 34865134 bellard
{
505 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
506 8a7ddc38 bellard
        cpu_ticks_offset = cpu_get_ticks();
507 8a7ddc38 bellard
        cpu_ticks_enabled = 0;
508 8a7ddc38 bellard
    }
509 34865134 bellard
}
510 34865134 bellard
511 67b915a5 bellard
static int64_t get_clock(void)
512 34865134 bellard
{
513 67b915a5 bellard
#ifdef _WIN32
514 67b915a5 bellard
    struct _timeb tb;
515 67b915a5 bellard
    _ftime(&tb);
516 67b915a5 bellard
    return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
517 67b915a5 bellard
#else
518 34865134 bellard
    struct timeval tv;
519 34865134 bellard
    gettimeofday(&tv, NULL);
520 34865134 bellard
    return tv.tv_sec * 1000000LL + tv.tv_usec;
521 67b915a5 bellard
#endif
522 34865134 bellard
}
523 34865134 bellard
524 0824d6fc bellard
void cpu_calibrate_ticks(void)
525 0824d6fc bellard
{
526 0824d6fc bellard
    int64_t usec, ticks;
527 0824d6fc bellard
528 0824d6fc bellard
    usec = get_clock();
529 8a7ddc38 bellard
    ticks = cpu_get_real_ticks();
530 67b915a5 bellard
#ifdef _WIN32
531 67b915a5 bellard
    Sleep(50);
532 67b915a5 bellard
#else
533 0824d6fc bellard
    usleep(50 * 1000);
534 67b915a5 bellard
#endif
535 0824d6fc bellard
    usec = get_clock() - usec;
536 8a7ddc38 bellard
    ticks = cpu_get_real_ticks() - ticks;
537 0824d6fc bellard
    ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
538 0824d6fc bellard
}
539 0824d6fc bellard
540 87858c89 bellard
/* compute with 96 bit intermediate result: (a*b)/c */
541 80cabfad bellard
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
542 87858c89 bellard
{
543 87858c89 bellard
    union {
544 87858c89 bellard
        uint64_t ll;
545 87858c89 bellard
        struct {
546 87858c89 bellard
#ifdef WORDS_BIGENDIAN
547 87858c89 bellard
            uint32_t high, low;
548 87858c89 bellard
#else
549 87858c89 bellard
            uint32_t low, high;
550 87858c89 bellard
#endif            
551 87858c89 bellard
        } l;
552 87858c89 bellard
    } u, res;
553 87858c89 bellard
    uint64_t rl, rh;
554 87858c89 bellard
555 87858c89 bellard
    u.ll = a;
556 87858c89 bellard
    rl = (uint64_t)u.l.low * (uint64_t)b;
557 87858c89 bellard
    rh = (uint64_t)u.l.high * (uint64_t)b;
558 87858c89 bellard
    rh += (rl >> 32);
559 87858c89 bellard
    res.l.high = rh / c;
560 87858c89 bellard
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
561 87858c89 bellard
    return res.ll;
562 87858c89 bellard
}
563 87858c89 bellard
564 8a7ddc38 bellard
#define QEMU_TIMER_REALTIME 0
565 8a7ddc38 bellard
#define QEMU_TIMER_VIRTUAL  1
566 8a7ddc38 bellard
567 8a7ddc38 bellard
struct QEMUClock {
568 8a7ddc38 bellard
    int type;
569 8a7ddc38 bellard
    /* XXX: add frequency */
570 8a7ddc38 bellard
};
571 8a7ddc38 bellard
572 8a7ddc38 bellard
struct QEMUTimer {
573 8a7ddc38 bellard
    QEMUClock *clock;
574 8a7ddc38 bellard
    int64_t expire_time;
575 8a7ddc38 bellard
    QEMUTimerCB *cb;
576 8a7ddc38 bellard
    void *opaque;
577 8a7ddc38 bellard
    struct QEMUTimer *next;
578 8a7ddc38 bellard
};
579 8a7ddc38 bellard
580 8a7ddc38 bellard
QEMUClock *rt_clock;
581 8a7ddc38 bellard
QEMUClock *vm_clock;
582 8a7ddc38 bellard
583 8a7ddc38 bellard
static QEMUTimer *active_timers[2];
584 40c3bac3 bellard
#ifdef _WIN32
585 40c3bac3 bellard
static MMRESULT timerID;
586 40c3bac3 bellard
#else
587 8a7ddc38 bellard
/* frequency of the times() clock tick */
588 8a7ddc38 bellard
static int timer_freq;
589 67b915a5 bellard
#endif
590 8a7ddc38 bellard
591 8a7ddc38 bellard
QEMUClock *qemu_new_clock(int type)
592 8a7ddc38 bellard
{
593 8a7ddc38 bellard
    QEMUClock *clock;
594 8a7ddc38 bellard
    clock = qemu_mallocz(sizeof(QEMUClock));
595 8a7ddc38 bellard
    if (!clock)
596 8a7ddc38 bellard
        return NULL;
597 8a7ddc38 bellard
    clock->type = type;
598 8a7ddc38 bellard
    return clock;
599 8a7ddc38 bellard
}
600 8a7ddc38 bellard
601 8a7ddc38 bellard
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
602 8a7ddc38 bellard
{
603 8a7ddc38 bellard
    QEMUTimer *ts;
604 8a7ddc38 bellard
605 8a7ddc38 bellard
    ts = qemu_mallocz(sizeof(QEMUTimer));
606 8a7ddc38 bellard
    ts->clock = clock;
607 8a7ddc38 bellard
    ts->cb = cb;
608 8a7ddc38 bellard
    ts->opaque = opaque;
609 8a7ddc38 bellard
    return ts;
610 8a7ddc38 bellard
}
611 8a7ddc38 bellard
612 8a7ddc38 bellard
void qemu_free_timer(QEMUTimer *ts)
613 8a7ddc38 bellard
{
614 8a7ddc38 bellard
    qemu_free(ts);
615 8a7ddc38 bellard
}
616 8a7ddc38 bellard
617 8a7ddc38 bellard
/* stop a timer, but do not dealloc it */
618 8a7ddc38 bellard
void qemu_del_timer(QEMUTimer *ts)
619 8a7ddc38 bellard
{
620 8a7ddc38 bellard
    QEMUTimer **pt, *t;
621 8a7ddc38 bellard
622 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
623 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
624 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
625 8a7ddc38 bellard
    for(;;) {
626 8a7ddc38 bellard
        t = *pt;
627 8a7ddc38 bellard
        if (!t)
628 8a7ddc38 bellard
            break;
629 8a7ddc38 bellard
        if (t == ts) {
630 8a7ddc38 bellard
            *pt = t->next;
631 8a7ddc38 bellard
            break;
632 8a7ddc38 bellard
        }
633 8a7ddc38 bellard
        pt = &t->next;
634 8a7ddc38 bellard
    }
635 8a7ddc38 bellard
}
636 8a7ddc38 bellard
637 8a7ddc38 bellard
/* modify the current timer so that it will be fired when current_time
638 8a7ddc38 bellard
   >= expire_time. The corresponding callback will be called. */
639 8a7ddc38 bellard
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
640 8a7ddc38 bellard
{
641 8a7ddc38 bellard
    QEMUTimer **pt, *t;
642 8a7ddc38 bellard
643 8a7ddc38 bellard
    qemu_del_timer(ts);
644 8a7ddc38 bellard
645 8a7ddc38 bellard
    /* add the timer in the sorted list */
646 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
647 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
648 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
649 8a7ddc38 bellard
    for(;;) {
650 8a7ddc38 bellard
        t = *pt;
651 8a7ddc38 bellard
        if (!t)
652 8a7ddc38 bellard
            break;
653 8a7ddc38 bellard
        if (t->expire_time > expire_time) 
654 8a7ddc38 bellard
            break;
655 8a7ddc38 bellard
        pt = &t->next;
656 8a7ddc38 bellard
    }
657 8a7ddc38 bellard
    ts->expire_time = expire_time;
658 8a7ddc38 bellard
    ts->next = *pt;
659 8a7ddc38 bellard
    *pt = ts;
660 8a7ddc38 bellard
}
661 8a7ddc38 bellard
662 8a7ddc38 bellard
int qemu_timer_pending(QEMUTimer *ts)
663 8a7ddc38 bellard
{
664 8a7ddc38 bellard
    QEMUTimer *t;
665 8a7ddc38 bellard
    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
666 8a7ddc38 bellard
        if (t == ts)
667 8a7ddc38 bellard
            return 1;
668 8a7ddc38 bellard
    }
669 8a7ddc38 bellard
    return 0;
670 8a7ddc38 bellard
}
671 8a7ddc38 bellard
672 8a7ddc38 bellard
static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
673 8a7ddc38 bellard
{
674 8a7ddc38 bellard
    if (!timer_head)
675 8a7ddc38 bellard
        return 0;
676 8a7ddc38 bellard
    return (timer_head->expire_time <= current_time);
677 8a7ddc38 bellard
}
678 8a7ddc38 bellard
679 8a7ddc38 bellard
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
680 8a7ddc38 bellard
{
681 8a7ddc38 bellard
    QEMUTimer *ts;
682 8a7ddc38 bellard
    
683 8a7ddc38 bellard
    for(;;) {
684 8a7ddc38 bellard
        ts = *ptimer_head;
685 8a7ddc38 bellard
        if (ts->expire_time > current_time)
686 8a7ddc38 bellard
            break;
687 8a7ddc38 bellard
        /* remove timer from the list before calling the callback */
688 8a7ddc38 bellard
        *ptimer_head = ts->next;
689 8a7ddc38 bellard
        ts->next = NULL;
690 8a7ddc38 bellard
        
691 8a7ddc38 bellard
        /* run the callback (the timer list can be modified) */
692 8a7ddc38 bellard
        ts->cb(ts->opaque);
693 8a7ddc38 bellard
    }
694 8a7ddc38 bellard
}
695 8a7ddc38 bellard
696 8a7ddc38 bellard
int64_t qemu_get_clock(QEMUClock *clock)
697 8a7ddc38 bellard
{
698 8a7ddc38 bellard
    switch(clock->type) {
699 8a7ddc38 bellard
    case QEMU_TIMER_REALTIME:
700 67b915a5 bellard
#ifdef _WIN32
701 67b915a5 bellard
        return GetTickCount();
702 67b915a5 bellard
#else
703 7d3505c5 bellard
        {
704 7d3505c5 bellard
            struct tms tp;
705 7d3505c5 bellard
706 7d3505c5 bellard
            /* Note that using gettimeofday() is not a good solution
707 7d3505c5 bellard
               for timers because its value change when the date is
708 7d3505c5 bellard
               modified. */
709 7d3505c5 bellard
            if (timer_freq == 100) {
710 7d3505c5 bellard
                return times(&tp) * 10;
711 7d3505c5 bellard
            } else {
712 7d3505c5 bellard
                return ((int64_t)times(&tp) * 1000) / timer_freq;
713 7d3505c5 bellard
            }
714 8a7ddc38 bellard
        }
715 67b915a5 bellard
#endif
716 8a7ddc38 bellard
    default:
717 8a7ddc38 bellard
    case QEMU_TIMER_VIRTUAL:
718 8a7ddc38 bellard
        return cpu_get_ticks();
719 8a7ddc38 bellard
    }
720 8a7ddc38 bellard
}
721 8a7ddc38 bellard
722 8a7ddc38 bellard
/* save a timer */
723 8a7ddc38 bellard
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
724 8a7ddc38 bellard
{
725 8a7ddc38 bellard
    uint64_t expire_time;
726 8a7ddc38 bellard
727 8a7ddc38 bellard
    if (qemu_timer_pending(ts)) {
728 8a7ddc38 bellard
        expire_time = ts->expire_time;
729 8a7ddc38 bellard
    } else {
730 8a7ddc38 bellard
        expire_time = -1;
731 8a7ddc38 bellard
    }
732 8a7ddc38 bellard
    qemu_put_be64(f, expire_time);
733 8a7ddc38 bellard
}
734 8a7ddc38 bellard
735 8a7ddc38 bellard
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
736 8a7ddc38 bellard
{
737 8a7ddc38 bellard
    uint64_t expire_time;
738 8a7ddc38 bellard
739 8a7ddc38 bellard
    expire_time = qemu_get_be64(f);
740 8a7ddc38 bellard
    if (expire_time != -1) {
741 8a7ddc38 bellard
        qemu_mod_timer(ts, expire_time);
742 8a7ddc38 bellard
    } else {
743 8a7ddc38 bellard
        qemu_del_timer(ts);
744 8a7ddc38 bellard
    }
745 8a7ddc38 bellard
}
746 8a7ddc38 bellard
747 8a7ddc38 bellard
static void timer_save(QEMUFile *f, void *opaque)
748 8a7ddc38 bellard
{
749 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
750 8a7ddc38 bellard
        hw_error("cannot save state if virtual timers are running");
751 8a7ddc38 bellard
    }
752 8a7ddc38 bellard
    qemu_put_be64s(f, &cpu_ticks_offset);
753 8a7ddc38 bellard
    qemu_put_be64s(f, &ticks_per_sec);
754 8a7ddc38 bellard
}
755 8a7ddc38 bellard
756 8a7ddc38 bellard
static int timer_load(QEMUFile *f, void *opaque, int version_id)
757 8a7ddc38 bellard
{
758 8a7ddc38 bellard
    if (version_id != 1)
759 8a7ddc38 bellard
        return -EINVAL;
760 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
761 8a7ddc38 bellard
        return -EINVAL;
762 8a7ddc38 bellard
    }
763 8a7ddc38 bellard
    qemu_get_be64s(f, &cpu_ticks_offset);
764 8a7ddc38 bellard
    qemu_get_be64s(f, &ticks_per_sec);
765 8a7ddc38 bellard
    return 0;
766 8a7ddc38 bellard
}
767 8a7ddc38 bellard
768 67b915a5 bellard
#ifdef _WIN32
769 67b915a5 bellard
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, 
770 67b915a5 bellard
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
771 67b915a5 bellard
#else
772 8a7ddc38 bellard
static void host_alarm_handler(int host_signum)
773 67b915a5 bellard
#endif
774 8a7ddc38 bellard
{
775 8a7ddc38 bellard
    if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
776 8a7ddc38 bellard
                           qemu_get_clock(vm_clock)) ||
777 8a7ddc38 bellard
        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
778 8a7ddc38 bellard
                           qemu_get_clock(rt_clock))) {
779 8a7ddc38 bellard
        /* stop the cpu because a timer occured */
780 8a7ddc38 bellard
        cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
781 8a7ddc38 bellard
    }
782 8a7ddc38 bellard
}
783 8a7ddc38 bellard
784 fd872598 bellard
#ifndef _WIN32
785 fd872598 bellard
786 829309c7 bellard
#if defined(__linux__)
787 829309c7 bellard
788 fd872598 bellard
#define RTC_FREQ 1024
789 fd872598 bellard
790 fd872598 bellard
static int rtc_fd;
791 829309c7 bellard
792 fd872598 bellard
static int start_rtc_timer(void)
793 fd872598 bellard
{
794 fd872598 bellard
    rtc_fd = open("/dev/rtc", O_RDONLY);
795 fd872598 bellard
    if (rtc_fd < 0)
796 fd872598 bellard
        return -1;
797 fd872598 bellard
    if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
798 fd872598 bellard
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
799 fd872598 bellard
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
800 fd872598 bellard
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
801 fd872598 bellard
        goto fail;
802 fd872598 bellard
    }
803 fd872598 bellard
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
804 fd872598 bellard
    fail:
805 fd872598 bellard
        close(rtc_fd);
806 fd872598 bellard
        return -1;
807 fd872598 bellard
    }
808 fd872598 bellard
    pit_min_timer_count = PIT_FREQ / RTC_FREQ;
809 fd872598 bellard
    return 0;
810 fd872598 bellard
}
811 fd872598 bellard
812 829309c7 bellard
#else
813 829309c7 bellard
814 829309c7 bellard
static int start_rtc_timer(void)
815 829309c7 bellard
{
816 829309c7 bellard
    return -1;
817 829309c7 bellard
}
818 829309c7 bellard
819 829309c7 bellard
#endif /* !defined(__linux__) */
820 829309c7 bellard
821 829309c7 bellard
#endif /* !defined(_WIN32) */
822 fd872598 bellard
823 8a7ddc38 bellard
static void init_timers(void)
824 8a7ddc38 bellard
{
825 8a7ddc38 bellard
    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
826 8a7ddc38 bellard
    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
827 8a7ddc38 bellard
828 67b915a5 bellard
#ifdef _WIN32
829 67b915a5 bellard
    {
830 67b915a5 bellard
        int count=0;
831 40c3bac3 bellard
        timerID = timeSetEvent(10,    // interval (ms)
832 40c3bac3 bellard
                               0,     // resolution
833 40c3bac3 bellard
                               host_alarm_handler, // function
834 40c3bac3 bellard
                               (DWORD)&count,  // user parameter
835 40c3bac3 bellard
                               TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
836 67b915a5 bellard
         if( !timerID ) {
837 67b915a5 bellard
            perror("failed timer alarm");
838 67b915a5 bellard
            exit(1);
839 67b915a5 bellard
         }
840 67b915a5 bellard
    }
841 67b915a5 bellard
    pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
842 67b915a5 bellard
#else
843 67b915a5 bellard
    {
844 67b915a5 bellard
        struct sigaction act;
845 67b915a5 bellard
        struct itimerval itv;
846 67b915a5 bellard
        
847 67b915a5 bellard
        /* get times() syscall frequency */
848 67b915a5 bellard
        timer_freq = sysconf(_SC_CLK_TCK);
849 67b915a5 bellard
        
850 67b915a5 bellard
        /* timer signal */
851 67b915a5 bellard
        sigfillset(&act.sa_mask);
852 67b915a5 bellard
        act.sa_flags = 0;
853 8a7ddc38 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
854 67b915a5 bellard
        act.sa_flags |= SA_ONSTACK;
855 67b915a5 bellard
#endif
856 67b915a5 bellard
        act.sa_handler = host_alarm_handler;
857 67b915a5 bellard
        sigaction(SIGALRM, &act, NULL);
858 fd872598 bellard
859 67b915a5 bellard
        itv.it_interval.tv_sec = 0;
860 67b915a5 bellard
        itv.it_interval.tv_usec = 1000;
861 67b915a5 bellard
        itv.it_value.tv_sec = 0;
862 67b915a5 bellard
        itv.it_value.tv_usec = 10 * 1000;
863 67b915a5 bellard
        setitimer(ITIMER_REAL, &itv, NULL);
864 67b915a5 bellard
        /* we probe the tick duration of the kernel to inform the user if
865 67b915a5 bellard
           the emulated kernel requested a too high timer frequency */
866 67b915a5 bellard
        getitimer(ITIMER_REAL, &itv);
867 fd872598 bellard
868 fd872598 bellard
        if (itv.it_interval.tv_usec > 1000) {
869 fd872598 bellard
            /* try to use /dev/rtc to have a faster timer */
870 fd872598 bellard
            if (start_rtc_timer() < 0)
871 fd872598 bellard
                goto use_itimer;
872 fd872598 bellard
            /* disable itimer */
873 fd872598 bellard
            itv.it_interval.tv_sec = 0;
874 fd872598 bellard
            itv.it_interval.tv_usec = 0;
875 fd872598 bellard
            itv.it_value.tv_sec = 0;
876 fd872598 bellard
            itv.it_value.tv_usec = 0;
877 fd872598 bellard
            setitimer(ITIMER_REAL, &itv, NULL);
878 fd872598 bellard
879 fd872598 bellard
            /* use the RTC */
880 fd872598 bellard
            sigaction(SIGIO, &act, NULL);
881 fd872598 bellard
            fcntl(rtc_fd, F_SETFL, O_ASYNC);
882 fd872598 bellard
            fcntl(rtc_fd, F_SETOWN, getpid());
883 fd872598 bellard
        } else {
884 fd872598 bellard
        use_itimer:
885 fd872598 bellard
            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
886 fd872598 bellard
                                   PIT_FREQ) / 1000000;
887 fd872598 bellard
        }
888 67b915a5 bellard
    }
889 8a7ddc38 bellard
#endif
890 8a7ddc38 bellard
}
891 8a7ddc38 bellard
892 40c3bac3 bellard
void quit_timers(void)
893 40c3bac3 bellard
{
894 40c3bac3 bellard
#ifdef _WIN32
895 40c3bac3 bellard
    timeKillEvent(timerID);
896 40c3bac3 bellard
#endif
897 40c3bac3 bellard
}
898 40c3bac3 bellard
899 c4b1fcc0 bellard
/***********************************************************/
900 c4b1fcc0 bellard
/* serial device */
901 313aa567 bellard
902 67b915a5 bellard
#ifdef _WIN32
903 67b915a5 bellard
904 67b915a5 bellard
int serial_open_device(void)
905 67b915a5 bellard
{
906 67b915a5 bellard
    return -1;
907 67b915a5 bellard
}
908 67b915a5 bellard
909 67b915a5 bellard
#else
910 67b915a5 bellard
911 c4b1fcc0 bellard
int serial_open_device(void)
912 313aa567 bellard
{
913 c4b1fcc0 bellard
    char slave_name[1024];
914 c4b1fcc0 bellard
    int master_fd, slave_fd;
915 313aa567 bellard
916 c4b1fcc0 bellard
    if (serial_console == NULL && nographic) {
917 c4b1fcc0 bellard
        /* use console for serial port */
918 c4b1fcc0 bellard
        return 0;
919 80cabfad bellard
    } else {
920 77d4bc34 bellard
#if 0
921 77d4bc34 bellard
        /* Not satisfying */
922 c4b1fcc0 bellard
        if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
923 c4b1fcc0 bellard
            fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
924 c4b1fcc0 bellard
            return -1;
925 c4b1fcc0 bellard
        }
926 c4b1fcc0 bellard
        fprintf(stderr, "Serial port redirected to %s\n", slave_name);
927 c4b1fcc0 bellard
        return master_fd;
928 77d4bc34 bellard
#else
929 77d4bc34 bellard
        return -1;
930 77d4bc34 bellard
#endif
931 330d0414 bellard
    }
932 330d0414 bellard
}
933 330d0414 bellard
934 67b915a5 bellard
#endif
935 67b915a5 bellard
936 80cabfad bellard
/***********************************************************/
937 c20709aa bellard
/* Linux network device redirectors */
938 330d0414 bellard
939 c20709aa bellard
void hex_dump(FILE *f, const uint8_t *buf, int size)
940 c20709aa bellard
{
941 c20709aa bellard
    int len, i, j, c;
942 c20709aa bellard
943 c20709aa bellard
    for(i=0;i<size;i+=16) {
944 c20709aa bellard
        len = size - i;
945 c20709aa bellard
        if (len > 16)
946 c20709aa bellard
            len = 16;
947 c20709aa bellard
        fprintf(f, "%08x ", i);
948 c20709aa bellard
        for(j=0;j<16;j++) {
949 c20709aa bellard
            if (j < len)
950 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
951 c20709aa bellard
            else
952 c20709aa bellard
                fprintf(f, "   ");
953 c20709aa bellard
        }
954 c20709aa bellard
        fprintf(f, " ");
955 c20709aa bellard
        for(j=0;j<len;j++) {
956 c20709aa bellard
            c = buf[i+j];
957 c20709aa bellard
            if (c < ' ' || c > '~')
958 c20709aa bellard
                c = '.';
959 c20709aa bellard
            fprintf(f, "%c", c);
960 c20709aa bellard
        }
961 c20709aa bellard
        fprintf(f, "\n");
962 c20709aa bellard
    }
963 c20709aa bellard
}
964 c20709aa bellard
965 c20709aa bellard
void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
966 c20709aa bellard
{
967 c20709aa bellard
    nd->send_packet(nd, buf, size);
968 c20709aa bellard
}
969 67b915a5 bellard
970 c20709aa bellard
void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, 
971 c20709aa bellard
                          IOReadHandler *fd_read, void *opaque)
972 67b915a5 bellard
{
973 c20709aa bellard
    nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
974 c20709aa bellard
}
975 c20709aa bellard
976 c20709aa bellard
/* dummy network adapter */
977 c20709aa bellard
978 c20709aa bellard
static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
979 c20709aa bellard
{
980 c20709aa bellard
}
981 c20709aa bellard
982 c20709aa bellard
static void dummy_add_read_packet(NetDriverState *nd, 
983 c20709aa bellard
                                  IOCanRWHandler *fd_can_read, 
984 c20709aa bellard
                                  IOReadHandler *fd_read, void *opaque)
985 c20709aa bellard
{
986 c20709aa bellard
}
987 c20709aa bellard
988 c20709aa bellard
static int net_dummy_init(NetDriverState *nd)
989 c20709aa bellard
{
990 c20709aa bellard
    nd->send_packet = dummy_send_packet;
991 c20709aa bellard
    nd->add_read_packet = dummy_add_read_packet;
992 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
993 67b915a5 bellard
    return 0;
994 67b915a5 bellard
}
995 67b915a5 bellard
996 c20709aa bellard
#if defined(CONFIG_SLIRP)
997 c20709aa bellard
998 c20709aa bellard
/* slirp network adapter */
999 c20709aa bellard
1000 c20709aa bellard
static void *slirp_fd_opaque;
1001 c20709aa bellard
static IOCanRWHandler *slirp_fd_can_read;
1002 c20709aa bellard
static IOReadHandler *slirp_fd_read;
1003 c20709aa bellard
static int slirp_inited;
1004 c20709aa bellard
1005 c20709aa bellard
int slirp_can_output(void)
1006 c20709aa bellard
{
1007 c20709aa bellard
    return slirp_fd_can_read(slirp_fd_opaque);
1008 c20709aa bellard
}
1009 c20709aa bellard
1010 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
1011 67b915a5 bellard
{
1012 c20709aa bellard
#if 0
1013 c20709aa bellard
    printf("output:\n");
1014 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
1015 c20709aa bellard
#endif
1016 c20709aa bellard
    slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
1017 67b915a5 bellard
}
1018 67b915a5 bellard
1019 c20709aa bellard
static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1020 c20709aa bellard
{
1021 c20709aa bellard
#if 0
1022 c20709aa bellard
    printf("input:\n");
1023 c20709aa bellard
    hex_dump(stdout, buf, size);
1024 c20709aa bellard
#endif
1025 c20709aa bellard
    slirp_input(buf, size);
1026 c20709aa bellard
}
1027 c20709aa bellard
1028 c20709aa bellard
static void slirp_add_read_packet(NetDriverState *nd, 
1029 c20709aa bellard
                                  IOCanRWHandler *fd_can_read, 
1030 c20709aa bellard
                                  IOReadHandler *fd_read, void *opaque)
1031 c20709aa bellard
{
1032 c20709aa bellard
    slirp_fd_opaque = opaque;
1033 c20709aa bellard
    slirp_fd_can_read = fd_can_read;
1034 c20709aa bellard
    slirp_fd_read = fd_read;
1035 c20709aa bellard
}
1036 c20709aa bellard
1037 c20709aa bellard
static int net_slirp_init(NetDriverState *nd)
1038 c20709aa bellard
{
1039 c20709aa bellard
    if (!slirp_inited) {
1040 c20709aa bellard
        slirp_inited = 1;
1041 c20709aa bellard
        slirp_init();
1042 c20709aa bellard
    }
1043 c20709aa bellard
    nd->send_packet = slirp_send_packet;
1044 c20709aa bellard
    nd->add_read_packet = slirp_add_read_packet;
1045 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
1046 c20709aa bellard
    return 0;
1047 c20709aa bellard
}
1048 c20709aa bellard
1049 c20709aa bellard
#endif /* CONFIG_SLIRP */
1050 c20709aa bellard
1051 c20709aa bellard
#if !defined(_WIN32)
1052 7d3505c5 bellard
#ifdef _BSD
1053 7d3505c5 bellard
static int tun_open(char *ifname, int ifname_size)
1054 7d3505c5 bellard
{
1055 7d3505c5 bellard
    int fd;
1056 7d3505c5 bellard
    char *dev;
1057 7d3505c5 bellard
    struct stat s;
1058 67b915a5 bellard
1059 7d3505c5 bellard
    fd = open("/dev/tap", O_RDWR);
1060 7d3505c5 bellard
    if (fd < 0) {
1061 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
1062 7d3505c5 bellard
        return -1;
1063 7d3505c5 bellard
    }
1064 7d3505c5 bellard
1065 7d3505c5 bellard
    fstat(fd, &s);
1066 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
1067 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
1068 7d3505c5 bellard
1069 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1070 7d3505c5 bellard
    return fd;
1071 7d3505c5 bellard
}
1072 7d3505c5 bellard
#else
1073 c4b1fcc0 bellard
static int tun_open(char *ifname, int ifname_size)
1074 330d0414 bellard
{
1075 80cabfad bellard
    struct ifreq ifr;
1076 c4b1fcc0 bellard
    int fd, ret;
1077 80cabfad bellard
    
1078 80cabfad bellard
    fd = open("/dev/net/tun", O_RDWR);
1079 80cabfad bellard
    if (fd < 0) {
1080 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1081 80cabfad bellard
        return -1;
1082 330d0414 bellard
    }
1083 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
1084 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1085 80cabfad bellard
    pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1086 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1087 80cabfad bellard
    if (ret != 0) {
1088 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1089 80cabfad bellard
        close(fd);
1090 80cabfad bellard
        return -1;
1091 80cabfad bellard
    }
1092 80cabfad bellard
    printf("Connected to host network interface: %s\n", ifr.ifr_name);
1093 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
1094 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1095 c4b1fcc0 bellard
    return fd;
1096 c4b1fcc0 bellard
}
1097 7d3505c5 bellard
#endif
1098 330d0414 bellard
1099 c20709aa bellard
static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1100 c20709aa bellard
{
1101 c20709aa bellard
    write(nd->fd, buf, size);
1102 c20709aa bellard
}
1103 c20709aa bellard
1104 c20709aa bellard
static void tun_add_read_packet(NetDriverState *nd, 
1105 c20709aa bellard
                                IOCanRWHandler *fd_can_read, 
1106 c20709aa bellard
                                IOReadHandler *fd_read, void *opaque)
1107 c4b1fcc0 bellard
{
1108 c20709aa bellard
    qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
1109 c20709aa bellard
}
1110 c20709aa bellard
1111 c20709aa bellard
static int net_tun_init(NetDriverState *nd)
1112 c20709aa bellard
{
1113 c20709aa bellard
    int pid, status;
1114 c20709aa bellard
    char *args[3];
1115 c4b1fcc0 bellard
    char **parg;
1116 c4b1fcc0 bellard
1117 c20709aa bellard
    nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
1118 c20709aa bellard
    if (nd->fd < 0)
1119 c20709aa bellard
        return -1;
1120 c4b1fcc0 bellard
1121 c20709aa bellard
    /* try to launch network init script */
1122 c20709aa bellard
    pid = fork();
1123 c20709aa bellard
    if (pid >= 0) {
1124 c20709aa bellard
        if (pid == 0) {
1125 c20709aa bellard
            parg = args;
1126 c20709aa bellard
            *parg++ = network_script;
1127 c20709aa bellard
            *parg++ = nd->ifname;
1128 c20709aa bellard
            *parg++ = NULL;
1129 c20709aa bellard
            execv(network_script, args);
1130 c20709aa bellard
            exit(1);
1131 c20709aa bellard
        }
1132 c20709aa bellard
        while (waitpid(pid, &status, 0) != pid);
1133 c20709aa bellard
        if (!WIFEXITED(status) ||
1134 c20709aa bellard
            WEXITSTATUS(status) != 0) {
1135 c20709aa bellard
            fprintf(stderr, "%s: could not launch network script\n",
1136 c20709aa bellard
                    network_script);
1137 80cabfad bellard
        }
1138 330d0414 bellard
    }
1139 c20709aa bellard
    nd->send_packet = tun_send_packet;
1140 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1141 80cabfad bellard
    return 0;
1142 330d0414 bellard
}
1143 330d0414 bellard
1144 c20709aa bellard
static int net_fd_init(NetDriverState *nd, int fd)
1145 330d0414 bellard
{
1146 c20709aa bellard
    nd->fd = fd;
1147 c20709aa bellard
    nd->send_packet = tun_send_packet;
1148 c20709aa bellard
    nd->add_read_packet = tun_add_read_packet;
1149 c20709aa bellard
    pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
1150 c20709aa bellard
    return 0;
1151 80cabfad bellard
}
1152 330d0414 bellard
1153 c20709aa bellard
#endif /* !_WIN32 */
1154 67b915a5 bellard
1155 330d0414 bellard
/***********************************************************/
1156 313aa567 bellard
/* dumb display */
1157 313aa567 bellard
1158 67b915a5 bellard
#ifdef _WIN32
1159 67b915a5 bellard
1160 67b915a5 bellard
static void term_exit(void)
1161 67b915a5 bellard
{
1162 67b915a5 bellard
}
1163 67b915a5 bellard
1164 67b915a5 bellard
static void term_init(void)
1165 67b915a5 bellard
{
1166 67b915a5 bellard
}
1167 67b915a5 bellard
1168 67b915a5 bellard
#else
1169 67b915a5 bellard
1170 313aa567 bellard
/* init terminal so that we can grab keys */
1171 313aa567 bellard
static struct termios oldtty;
1172 313aa567 bellard
1173 313aa567 bellard
static void term_exit(void)
1174 313aa567 bellard
{
1175 313aa567 bellard
    tcsetattr (0, TCSANOW, &oldtty);
1176 313aa567 bellard
}
1177 313aa567 bellard
1178 313aa567 bellard
static void term_init(void)
1179 313aa567 bellard
{
1180 313aa567 bellard
    struct termios tty;
1181 313aa567 bellard
1182 313aa567 bellard
    tcgetattr (0, &tty);
1183 313aa567 bellard
    oldtty = tty;
1184 313aa567 bellard
1185 313aa567 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1186 313aa567 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
1187 313aa567 bellard
    tty.c_oflag |= OPOST;
1188 a20dd508 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1189 a20dd508 bellard
    /* if graphical mode, we allow Ctrl-C handling */
1190 a20dd508 bellard
    if (nographic)
1191 a20dd508 bellard
        tty.c_lflag &= ~ISIG;
1192 313aa567 bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
1193 313aa567 bellard
    tty.c_cflag |= CS8;
1194 313aa567 bellard
    tty.c_cc[VMIN] = 1;
1195 313aa567 bellard
    tty.c_cc[VTIME] = 0;
1196 313aa567 bellard
    
1197 313aa567 bellard
    tcsetattr (0, TCSANOW, &tty);
1198 313aa567 bellard
1199 313aa567 bellard
    atexit(term_exit);
1200 313aa567 bellard
1201 313aa567 bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
1202 313aa567 bellard
}
1203 313aa567 bellard
1204 67b915a5 bellard
#endif
1205 67b915a5 bellard
1206 313aa567 bellard
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
1207 313aa567 bellard
{
1208 313aa567 bellard
}
1209 313aa567 bellard
1210 313aa567 bellard
static void dumb_resize(DisplayState *ds, int w, int h)
1211 313aa567 bellard
{
1212 313aa567 bellard
}
1213 313aa567 bellard
1214 313aa567 bellard
static void dumb_refresh(DisplayState *ds)
1215 313aa567 bellard
{
1216 313aa567 bellard
    vga_update_display();
1217 313aa567 bellard
}
1218 313aa567 bellard
1219 313aa567 bellard
void dumb_display_init(DisplayState *ds)
1220 313aa567 bellard
{
1221 313aa567 bellard
    ds->data = NULL;
1222 313aa567 bellard
    ds->linesize = 0;
1223 313aa567 bellard
    ds->depth = 0;
1224 313aa567 bellard
    ds->dpy_update = dumb_update;
1225 313aa567 bellard
    ds->dpy_resize = dumb_resize;
1226 313aa567 bellard
    ds->dpy_refresh = dumb_refresh;
1227 313aa567 bellard
}
1228 313aa567 bellard
1229 3a51dee6 bellard
#if !defined(CONFIG_SOFTMMU)
1230 313aa567 bellard
/***********************************************************/
1231 0824d6fc bellard
/* cpu signal handler */
1232 0824d6fc bellard
static void host_segv_handler(int host_signum, siginfo_t *info, 
1233 0824d6fc bellard
                              void *puc)
1234 0824d6fc bellard
{
1235 0824d6fc bellard
    if (cpu_signal_handler(host_signum, info, puc))
1236 0824d6fc bellard
        return;
1237 0824d6fc bellard
    term_exit();
1238 0824d6fc bellard
    abort();
1239 0824d6fc bellard
}
1240 3a51dee6 bellard
#endif
1241 0824d6fc bellard
1242 8a7ddc38 bellard
/***********************************************************/
1243 8a7ddc38 bellard
/* I/O handling */
1244 0824d6fc bellard
1245 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
1246 c4b1fcc0 bellard
1247 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
1248 c4b1fcc0 bellard
    int fd;
1249 c4b1fcc0 bellard
    IOCanRWHandler *fd_can_read;
1250 c4b1fcc0 bellard
    IOReadHandler *fd_read;
1251 c4b1fcc0 bellard
    void *opaque;
1252 c4b1fcc0 bellard
    /* temporary data */
1253 c4b1fcc0 bellard
    struct pollfd *ufd;
1254 c4b1fcc0 bellard
    int max_size;
1255 8a7ddc38 bellard
    struct IOHandlerRecord *next;
1256 c4b1fcc0 bellard
} IOHandlerRecord;
1257 c4b1fcc0 bellard
1258 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
1259 c4b1fcc0 bellard
1260 8a7ddc38 bellard
int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
1261 8a7ddc38 bellard
                             IOReadHandler *fd_read, void *opaque)
1262 c4b1fcc0 bellard
{
1263 c4b1fcc0 bellard
    IOHandlerRecord *ioh;
1264 c4b1fcc0 bellard
1265 8a7ddc38 bellard
    ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1266 8a7ddc38 bellard
    if (!ioh)
1267 c4b1fcc0 bellard
        return -1;
1268 c4b1fcc0 bellard
    ioh->fd = fd;
1269 c4b1fcc0 bellard
    ioh->fd_can_read = fd_can_read;
1270 c4b1fcc0 bellard
    ioh->fd_read = fd_read;
1271 c4b1fcc0 bellard
    ioh->opaque = opaque;
1272 8a7ddc38 bellard
    ioh->next = first_io_handler;
1273 8a7ddc38 bellard
    first_io_handler = ioh;
1274 c4b1fcc0 bellard
    return 0;
1275 c4b1fcc0 bellard
}
1276 c4b1fcc0 bellard
1277 8a7ddc38 bellard
void qemu_del_fd_read_handler(int fd)
1278 8a7ddc38 bellard
{
1279 8a7ddc38 bellard
    IOHandlerRecord **pioh, *ioh;
1280 b4608c04 bellard
1281 8a7ddc38 bellard
    pioh = &first_io_handler;
1282 8a7ddc38 bellard
    for(;;) {
1283 8a7ddc38 bellard
        ioh = *pioh;
1284 8a7ddc38 bellard
        if (ioh == NULL)
1285 8a7ddc38 bellard
            break;
1286 8a7ddc38 bellard
        if (ioh->fd == fd) {
1287 8a7ddc38 bellard
            *pioh = ioh->next;
1288 8a7ddc38 bellard
            break;
1289 8a7ddc38 bellard
        }
1290 8a7ddc38 bellard
        pioh = &ioh->next;
1291 8a7ddc38 bellard
    }
1292 8a7ddc38 bellard
}
1293 8a7ddc38 bellard
1294 8a7ddc38 bellard
/***********************************************************/
1295 8a7ddc38 bellard
/* savevm/loadvm support */
1296 8a7ddc38 bellard
1297 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
1298 b4608c04 bellard
{
1299 8a7ddc38 bellard
    fwrite(buf, 1, size, f);
1300 b4608c04 bellard
}
1301 b4608c04 bellard
1302 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
1303 b4608c04 bellard
{
1304 8a7ddc38 bellard
    fputc(v, f);
1305 8a7ddc38 bellard
}
1306 8a7ddc38 bellard
1307 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
1308 8a7ddc38 bellard
{
1309 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
1310 8a7ddc38 bellard
    qemu_put_byte(f, v);
1311 8a7ddc38 bellard
}
1312 8a7ddc38 bellard
1313 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
1314 8a7ddc38 bellard
{
1315 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
1316 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
1317 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
1318 8a7ddc38 bellard
    qemu_put_byte(f, v);
1319 8a7ddc38 bellard
}
1320 8a7ddc38 bellard
1321 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
1322 8a7ddc38 bellard
{
1323 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
1324 8a7ddc38 bellard
    qemu_put_be32(f, v);
1325 8a7ddc38 bellard
}
1326 8a7ddc38 bellard
1327 8a7ddc38 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
1328 8a7ddc38 bellard
{
1329 8a7ddc38 bellard
    return fread(buf, 1, size, f);
1330 8a7ddc38 bellard
}
1331 8a7ddc38 bellard
1332 8a7ddc38 bellard
int qemu_get_byte(QEMUFile *f)
1333 8a7ddc38 bellard
{
1334 8a7ddc38 bellard
    int v;
1335 8a7ddc38 bellard
    v = fgetc(f);
1336 8a7ddc38 bellard
    if (v == EOF)
1337 8a7ddc38 bellard
        return 0;
1338 8a7ddc38 bellard
    else
1339 8a7ddc38 bellard
        return v;
1340 8a7ddc38 bellard
}
1341 8a7ddc38 bellard
1342 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
1343 8a7ddc38 bellard
{
1344 8a7ddc38 bellard
    unsigned int v;
1345 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
1346 8a7ddc38 bellard
    v |= qemu_get_byte(f);
1347 8a7ddc38 bellard
    return v;
1348 8a7ddc38 bellard
}
1349 8a7ddc38 bellard
1350 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
1351 8a7ddc38 bellard
{
1352 8a7ddc38 bellard
    unsigned int v;
1353 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
1354 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
1355 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
1356 8a7ddc38 bellard
    v |= qemu_get_byte(f);
1357 8a7ddc38 bellard
    return v;
1358 8a7ddc38 bellard
}
1359 8a7ddc38 bellard
1360 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
1361 8a7ddc38 bellard
{
1362 8a7ddc38 bellard
    uint64_t v;
1363 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
1364 8a7ddc38 bellard
    v |= qemu_get_be32(f);
1365 8a7ddc38 bellard
    return v;
1366 8a7ddc38 bellard
}
1367 8a7ddc38 bellard
1368 8a7ddc38 bellard
int64_t qemu_ftell(QEMUFile *f)
1369 8a7ddc38 bellard
{
1370 8a7ddc38 bellard
    return ftell(f);
1371 8a7ddc38 bellard
}
1372 8a7ddc38 bellard
1373 8a7ddc38 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
1374 8a7ddc38 bellard
{
1375 8a7ddc38 bellard
    if (fseek(f, pos, whence) < 0)
1376 8a7ddc38 bellard
        return -1;
1377 8a7ddc38 bellard
    return ftell(f);
1378 8a7ddc38 bellard
}
1379 8a7ddc38 bellard
1380 8a7ddc38 bellard
typedef struct SaveStateEntry {
1381 8a7ddc38 bellard
    char idstr[256];
1382 8a7ddc38 bellard
    int instance_id;
1383 8a7ddc38 bellard
    int version_id;
1384 8a7ddc38 bellard
    SaveStateHandler *save_state;
1385 8a7ddc38 bellard
    LoadStateHandler *load_state;
1386 8a7ddc38 bellard
    void *opaque;
1387 8a7ddc38 bellard
    struct SaveStateEntry *next;
1388 8a7ddc38 bellard
} SaveStateEntry;
1389 b4608c04 bellard
1390 8a7ddc38 bellard
static SaveStateEntry *first_se;
1391 8a7ddc38 bellard
1392 8a7ddc38 bellard
int register_savevm(const char *idstr, 
1393 8a7ddc38 bellard
                    int instance_id, 
1394 8a7ddc38 bellard
                    int version_id,
1395 8a7ddc38 bellard
                    SaveStateHandler *save_state,
1396 8a7ddc38 bellard
                    LoadStateHandler *load_state,
1397 8a7ddc38 bellard
                    void *opaque)
1398 8a7ddc38 bellard
{
1399 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
1400 8a7ddc38 bellard
1401 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
1402 8a7ddc38 bellard
    if (!se)
1403 8a7ddc38 bellard
        return -1;
1404 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1405 8a7ddc38 bellard
    se->instance_id = instance_id;
1406 8a7ddc38 bellard
    se->version_id = version_id;
1407 8a7ddc38 bellard
    se->save_state = save_state;
1408 8a7ddc38 bellard
    se->load_state = load_state;
1409 8a7ddc38 bellard
    se->opaque = opaque;
1410 8a7ddc38 bellard
    se->next = NULL;
1411 8a7ddc38 bellard
1412 8a7ddc38 bellard
    /* add at the end of list */
1413 8a7ddc38 bellard
    pse = &first_se;
1414 8a7ddc38 bellard
    while (*pse != NULL)
1415 8a7ddc38 bellard
        pse = &(*pse)->next;
1416 8a7ddc38 bellard
    *pse = se;
1417 8a7ddc38 bellard
    return 0;
1418 8a7ddc38 bellard
}
1419 8a7ddc38 bellard
1420 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
1421 8a7ddc38 bellard
#define QEMU_VM_FILE_VERSION 0x00000001
1422 8a7ddc38 bellard
1423 8a7ddc38 bellard
int qemu_savevm(const char *filename)
1424 8a7ddc38 bellard
{
1425 8a7ddc38 bellard
    SaveStateEntry *se;
1426 8a7ddc38 bellard
    QEMUFile *f;
1427 8a7ddc38 bellard
    int len, len_pos, cur_pos, saved_vm_running, ret;
1428 8a7ddc38 bellard
1429 8a7ddc38 bellard
    saved_vm_running = vm_running;
1430 8a7ddc38 bellard
    vm_stop(0);
1431 8a7ddc38 bellard
1432 8a7ddc38 bellard
    f = fopen(filename, "wb");
1433 8a7ddc38 bellard
    if (!f) {
1434 8a7ddc38 bellard
        ret = -1;
1435 8a7ddc38 bellard
        goto the_end;
1436 313aa567 bellard
    }
1437 313aa567 bellard
1438 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1439 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1440 8a7ddc38 bellard
1441 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
1442 8a7ddc38 bellard
        /* ID string */
1443 8a7ddc38 bellard
        len = strlen(se->idstr);
1444 8a7ddc38 bellard
        qemu_put_byte(f, len);
1445 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
1446 8a7ddc38 bellard
1447 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
1448 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
1449 8a7ddc38 bellard
1450 8a7ddc38 bellard
        /* record size: filled later */
1451 8a7ddc38 bellard
        len_pos = ftell(f);
1452 8a7ddc38 bellard
        qemu_put_be32(f, 0);
1453 8a7ddc38 bellard
        
1454 8a7ddc38 bellard
        se->save_state(f, se->opaque);
1455 8a7ddc38 bellard
1456 8a7ddc38 bellard
        /* fill record size */
1457 8a7ddc38 bellard
        cur_pos = ftell(f);
1458 8a7ddc38 bellard
        len = ftell(f) - len_pos - 4;
1459 8a7ddc38 bellard
        fseek(f, len_pos, SEEK_SET);
1460 8a7ddc38 bellard
        qemu_put_be32(f, len);
1461 8a7ddc38 bellard
        fseek(f, cur_pos, SEEK_SET);
1462 8a7ddc38 bellard
    }
1463 8a7ddc38 bellard
1464 8a7ddc38 bellard
    fclose(f);
1465 8a7ddc38 bellard
    ret = 0;
1466 8a7ddc38 bellard
 the_end:
1467 8a7ddc38 bellard
    if (saved_vm_running)
1468 8a7ddc38 bellard
        vm_start();
1469 8a7ddc38 bellard
    return ret;
1470 8a7ddc38 bellard
}
1471 8a7ddc38 bellard
1472 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
1473 8a7ddc38 bellard
{
1474 8a7ddc38 bellard
    SaveStateEntry *se;
1475 8a7ddc38 bellard
1476 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
1477 8a7ddc38 bellard
        if (!strcmp(se->idstr, idstr) && 
1478 8a7ddc38 bellard
            instance_id == se->instance_id)
1479 8a7ddc38 bellard
            return se;
1480 8a7ddc38 bellard
    }
1481 8a7ddc38 bellard
    return NULL;
1482 8a7ddc38 bellard
}
1483 8a7ddc38 bellard
1484 8a7ddc38 bellard
int qemu_loadvm(const char *filename)
1485 8a7ddc38 bellard
{
1486 8a7ddc38 bellard
    SaveStateEntry *se;
1487 8a7ddc38 bellard
    QEMUFile *f;
1488 8a7ddc38 bellard
    int len, cur_pos, ret, instance_id, record_len, version_id;
1489 8a7ddc38 bellard
    int saved_vm_running;
1490 8a7ddc38 bellard
    unsigned int v;
1491 8a7ddc38 bellard
    char idstr[256];
1492 8a7ddc38 bellard
    
1493 8a7ddc38 bellard
    saved_vm_running = vm_running;
1494 8a7ddc38 bellard
    vm_stop(0);
1495 8a7ddc38 bellard
1496 8a7ddc38 bellard
    f = fopen(filename, "rb");
1497 8a7ddc38 bellard
    if (!f) {
1498 8a7ddc38 bellard
        ret = -1;
1499 8a7ddc38 bellard
        goto the_end;
1500 8a7ddc38 bellard
    }
1501 8a7ddc38 bellard
1502 8a7ddc38 bellard
    v = qemu_get_be32(f);
1503 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
1504 8a7ddc38 bellard
        goto fail;
1505 8a7ddc38 bellard
    v = qemu_get_be32(f);
1506 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
1507 8a7ddc38 bellard
    fail:
1508 8a7ddc38 bellard
        fclose(f);
1509 8a7ddc38 bellard
        ret = -1;
1510 8a7ddc38 bellard
        goto the_end;
1511 8a7ddc38 bellard
    }
1512 b4608c04 bellard
    for(;;) {
1513 a541f297 bellard
#if defined (DO_TB_FLUSH)
1514 d927637d bellard
        tb_flush(global_env);
1515 a541f297 bellard
#endif
1516 8a7ddc38 bellard
        len = qemu_get_byte(f);
1517 8a7ddc38 bellard
        if (feof(f))
1518 cd4c3e88 bellard
            break;
1519 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
1520 8a7ddc38 bellard
        idstr[len] = '\0';
1521 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
1522 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
1523 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
1524 8a7ddc38 bellard
#if 0
1525 8a7ddc38 bellard
        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
1526 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
1527 8a7ddc38 bellard
#endif
1528 8a7ddc38 bellard
        cur_pos = ftell(f);
1529 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
1530 8a7ddc38 bellard
        if (!se) {
1531 8a7ddc38 bellard
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
1532 8a7ddc38 bellard
                    instance_id, idstr);
1533 8a7ddc38 bellard
        } else {
1534 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
1535 8a7ddc38 bellard
            if (ret < 0) {
1536 8a7ddc38 bellard
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
1537 8a7ddc38 bellard
                        instance_id, idstr);
1538 8a7ddc38 bellard
            }
1539 34865134 bellard
        }
1540 8a7ddc38 bellard
        /* always seek to exact end of record */
1541 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
1542 8a7ddc38 bellard
    }
1543 8a7ddc38 bellard
    fclose(f);
1544 8a7ddc38 bellard
    ret = 0;
1545 8a7ddc38 bellard
 the_end:
1546 8a7ddc38 bellard
    if (saved_vm_running)
1547 8a7ddc38 bellard
        vm_start();
1548 8a7ddc38 bellard
    return ret;
1549 8a7ddc38 bellard
}
1550 8a7ddc38 bellard
1551 8a7ddc38 bellard
/***********************************************************/
1552 8a7ddc38 bellard
/* cpu save/restore */
1553 8a7ddc38 bellard
1554 8a7ddc38 bellard
#if defined(TARGET_I386)
1555 8a7ddc38 bellard
1556 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
1557 8a7ddc38 bellard
{
1558 8a7ddc38 bellard
    qemu_put_be32(f, (uint32_t)dt->base);
1559 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
1560 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
1561 8a7ddc38 bellard
}
1562 8a7ddc38 bellard
1563 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
1564 8a7ddc38 bellard
{
1565 8a7ddc38 bellard
    dt->base = (uint8_t *)qemu_get_be32(f);
1566 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
1567 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
1568 8a7ddc38 bellard
}
1569 8a7ddc38 bellard
1570 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
1571 8a7ddc38 bellard
{
1572 8a7ddc38 bellard
    CPUState *env = opaque;
1573 8a7ddc38 bellard
    uint16_t fptag, fpus, fpuc;
1574 8a7ddc38 bellard
    uint32_t hflags;
1575 8a7ddc38 bellard
    int i;
1576 8a7ddc38 bellard
1577 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
1578 8a7ddc38 bellard
        qemu_put_be32s(f, &env->regs[i]);
1579 8a7ddc38 bellard
    qemu_put_be32s(f, &env->eip);
1580 8a7ddc38 bellard
    qemu_put_be32s(f, &env->eflags);
1581 8a7ddc38 bellard
    qemu_put_be32s(f, &env->eflags);
1582 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
1583 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
1584 8a7ddc38 bellard
    
1585 8a7ddc38 bellard
    /* FPU */
1586 8a7ddc38 bellard
    fpuc = env->fpuc;
1587 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1588 8a7ddc38 bellard
    fptag = 0;
1589 8a7ddc38 bellard
    for (i=7; i>=0; i--) {
1590 8a7ddc38 bellard
        fptag <<= 2;
1591 8a7ddc38 bellard
        if (env->fptags[i]) {
1592 8a7ddc38 bellard
            fptag |= 3;
1593 8a7ddc38 bellard
        }
1594 8a7ddc38 bellard
    }
1595 8a7ddc38 bellard
    
1596 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
1597 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
1598 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
1599 8a7ddc38 bellard
1600 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
1601 8a7ddc38 bellard
        uint64_t mant;
1602 8a7ddc38 bellard
        uint16_t exp;
1603 8a7ddc38 bellard
        cpu_get_fp80(&mant, &exp, env->fpregs[i]);
1604 8a7ddc38 bellard
        qemu_put_be64(f, mant);
1605 8a7ddc38 bellard
        qemu_put_be16(f, exp);
1606 8a7ddc38 bellard
    }
1607 8a7ddc38 bellard
1608 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
1609 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
1610 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
1611 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
1612 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
1613 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
1614 8a7ddc38 bellard
    
1615 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
1616 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
1617 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
1618 8a7ddc38 bellard
    
1619 8a7ddc38 bellard
    qemu_put_be32s(f, &env->cr[0]);
1620 8a7ddc38 bellard
    qemu_put_be32s(f, &env->cr[2]);
1621 8a7ddc38 bellard
    qemu_put_be32s(f, &env->cr[3]);
1622 8a7ddc38 bellard
    qemu_put_be32s(f, &env->cr[4]);
1623 8a7ddc38 bellard
    
1624 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
1625 8a7ddc38 bellard
        qemu_put_be32s(f, &env->dr[i]);
1626 8a7ddc38 bellard
1627 8a7ddc38 bellard
    /* MMU */
1628 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
1629 8a7ddc38 bellard
}
1630 8a7ddc38 bellard
1631 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
1632 8a7ddc38 bellard
{
1633 8a7ddc38 bellard
    CPUState *env = opaque;
1634 8a7ddc38 bellard
    int i;
1635 8a7ddc38 bellard
    uint32_t hflags;
1636 8a7ddc38 bellard
    uint16_t fpus, fpuc, fptag;
1637 8a7ddc38 bellard
1638 8a7ddc38 bellard
    if (version_id != 1)
1639 8a7ddc38 bellard
        return -EINVAL;
1640 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
1641 8a7ddc38 bellard
        qemu_get_be32s(f, &env->regs[i]);
1642 8a7ddc38 bellard
    qemu_get_be32s(f, &env->eip);
1643 8a7ddc38 bellard
    qemu_get_be32s(f, &env->eflags);
1644 8a7ddc38 bellard
    qemu_get_be32s(f, &env->eflags);
1645 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
1646 8a7ddc38 bellard
1647 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
1648 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
1649 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
1650 8a7ddc38 bellard
1651 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
1652 8a7ddc38 bellard
        uint64_t mant;
1653 8a7ddc38 bellard
        uint16_t exp;
1654 8a7ddc38 bellard
        mant = qemu_get_be64(f);
1655 8a7ddc38 bellard
        exp = qemu_get_be16(f);
1656 8a7ddc38 bellard
        env->fpregs[i] = cpu_set_fp80(mant, exp);
1657 8a7ddc38 bellard
    }
1658 8a7ddc38 bellard
1659 8a7ddc38 bellard
    env->fpuc = fpuc;
1660 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
1661 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
1662 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
1663 8a7ddc38 bellard
        env->fptags[i] = ((fptag & 3) == 3);
1664 8a7ddc38 bellard
        fptag >>= 2;
1665 8a7ddc38 bellard
    }
1666 8a7ddc38 bellard
    
1667 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
1668 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
1669 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
1670 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
1671 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
1672 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
1673 8a7ddc38 bellard
    
1674 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
1675 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
1676 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
1677 8a7ddc38 bellard
    
1678 8a7ddc38 bellard
    qemu_get_be32s(f, &env->cr[0]);
1679 8a7ddc38 bellard
    qemu_get_be32s(f, &env->cr[2]);
1680 8a7ddc38 bellard
    qemu_get_be32s(f, &env->cr[3]);
1681 8a7ddc38 bellard
    qemu_get_be32s(f, &env->cr[4]);
1682 8a7ddc38 bellard
    
1683 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
1684 8a7ddc38 bellard
        qemu_get_be32s(f, &env->dr[i]);
1685 8a7ddc38 bellard
1686 8a7ddc38 bellard
    /* MMU */
1687 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
1688 8a7ddc38 bellard
1689 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
1690 8a7ddc38 bellard
    env->hflags = hflags;
1691 8a7ddc38 bellard
    tlb_flush(env, 1);
1692 8a7ddc38 bellard
    return 0;
1693 8a7ddc38 bellard
}
1694 8a7ddc38 bellard
1695 a541f297 bellard
#elif defined(TARGET_PPC)
1696 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
1697 a541f297 bellard
{
1698 a541f297 bellard
}
1699 a541f297 bellard
1700 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
1701 a541f297 bellard
{
1702 a541f297 bellard
    return 0;
1703 a541f297 bellard
}
1704 8a7ddc38 bellard
#else
1705 8a7ddc38 bellard
1706 8a7ddc38 bellard
#warning No CPU save/restore functions
1707 8a7ddc38 bellard
1708 8a7ddc38 bellard
#endif
1709 8a7ddc38 bellard
1710 8a7ddc38 bellard
/***********************************************************/
1711 8a7ddc38 bellard
/* ram save/restore */
1712 8a7ddc38 bellard
1713 8a7ddc38 bellard
/* we just avoid storing empty pages */
1714 8a7ddc38 bellard
static void ram_put_page(QEMUFile *f, const uint8_t *buf, int len)
1715 8a7ddc38 bellard
{
1716 8a7ddc38 bellard
    int i, v;
1717 8a7ddc38 bellard
1718 8a7ddc38 bellard
    v = buf[0];
1719 8a7ddc38 bellard
    for(i = 1; i < len; i++) {
1720 8a7ddc38 bellard
        if (buf[i] != v)
1721 8a7ddc38 bellard
            goto normal_save;
1722 8a7ddc38 bellard
    }
1723 8a7ddc38 bellard
    qemu_put_byte(f, 1);
1724 8a7ddc38 bellard
    qemu_put_byte(f, v);
1725 8a7ddc38 bellard
    return;
1726 8a7ddc38 bellard
 normal_save:
1727 8a7ddc38 bellard
    qemu_put_byte(f, 0); 
1728 8a7ddc38 bellard
    qemu_put_buffer(f, buf, len);
1729 8a7ddc38 bellard
}
1730 8a7ddc38 bellard
1731 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
1732 8a7ddc38 bellard
{
1733 8a7ddc38 bellard
    int v;
1734 8a7ddc38 bellard
1735 8a7ddc38 bellard
    v = qemu_get_byte(f);
1736 8a7ddc38 bellard
    switch(v) {
1737 8a7ddc38 bellard
    case 0:
1738 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
1739 8a7ddc38 bellard
            return -EIO;
1740 8a7ddc38 bellard
        break;
1741 8a7ddc38 bellard
    case 1:
1742 8a7ddc38 bellard
        v = qemu_get_byte(f);
1743 8a7ddc38 bellard
        memset(buf, v, len);
1744 8a7ddc38 bellard
        break;
1745 8a7ddc38 bellard
    default:
1746 8a7ddc38 bellard
        return -EINVAL;
1747 8a7ddc38 bellard
    }
1748 8a7ddc38 bellard
    return 0;
1749 8a7ddc38 bellard
}
1750 8a7ddc38 bellard
1751 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
1752 8a7ddc38 bellard
{
1753 8a7ddc38 bellard
    int i;
1754 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
1755 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
1756 8a7ddc38 bellard
        ram_put_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
1757 8a7ddc38 bellard
    }
1758 8a7ddc38 bellard
}
1759 8a7ddc38 bellard
1760 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
1761 8a7ddc38 bellard
{
1762 8a7ddc38 bellard
    int i, ret;
1763 8a7ddc38 bellard
1764 8a7ddc38 bellard
    if (version_id != 1)
1765 8a7ddc38 bellard
        return -EINVAL;
1766 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
1767 8a7ddc38 bellard
        return -EINVAL;
1768 8a7ddc38 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
1769 8a7ddc38 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
1770 8a7ddc38 bellard
        if (ret)
1771 8a7ddc38 bellard
            return ret;
1772 8a7ddc38 bellard
    }
1773 8a7ddc38 bellard
    return 0;
1774 8a7ddc38 bellard
}
1775 8a7ddc38 bellard
1776 8a7ddc38 bellard
/***********************************************************/
1777 8a7ddc38 bellard
/* main execution loop */
1778 8a7ddc38 bellard
1779 8a7ddc38 bellard
void gui_update(void *opaque)
1780 8a7ddc38 bellard
{
1781 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
1782 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
1783 8a7ddc38 bellard
}
1784 8a7ddc38 bellard
1785 8a7ddc38 bellard
/* XXX: support several handlers */
1786 8a7ddc38 bellard
VMStopHandler *vm_stop_cb;
1787 8a7ddc38 bellard
VMStopHandler *vm_stop_opaque;
1788 8a7ddc38 bellard
1789 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
1790 8a7ddc38 bellard
{
1791 8a7ddc38 bellard
    vm_stop_cb = cb;
1792 8a7ddc38 bellard
    vm_stop_opaque = opaque;
1793 8a7ddc38 bellard
    return 0;
1794 8a7ddc38 bellard
}
1795 8a7ddc38 bellard
1796 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
1797 8a7ddc38 bellard
{
1798 8a7ddc38 bellard
    vm_stop_cb = NULL;
1799 8a7ddc38 bellard
}
1800 8a7ddc38 bellard
1801 8a7ddc38 bellard
void vm_start(void)
1802 8a7ddc38 bellard
{
1803 8a7ddc38 bellard
    if (!vm_running) {
1804 8a7ddc38 bellard
        cpu_enable_ticks();
1805 8a7ddc38 bellard
        vm_running = 1;
1806 8a7ddc38 bellard
    }
1807 8a7ddc38 bellard
}
1808 8a7ddc38 bellard
1809 8a7ddc38 bellard
void vm_stop(int reason) 
1810 8a7ddc38 bellard
{
1811 8a7ddc38 bellard
    if (vm_running) {
1812 8a7ddc38 bellard
        cpu_disable_ticks();
1813 8a7ddc38 bellard
        vm_running = 0;
1814 8a7ddc38 bellard
        if (reason != 0) {
1815 8a7ddc38 bellard
            if (vm_stop_cb) {
1816 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
1817 8a7ddc38 bellard
            }
1818 34865134 bellard
        }
1819 8a7ddc38 bellard
    }
1820 8a7ddc38 bellard
}
1821 8a7ddc38 bellard
1822 bb0c6722 bellard
/* reset/shutdown handler */
1823 bb0c6722 bellard
1824 bb0c6722 bellard
typedef struct QEMUResetEntry {
1825 bb0c6722 bellard
    QEMUResetHandler *func;
1826 bb0c6722 bellard
    void *opaque;
1827 bb0c6722 bellard
    struct QEMUResetEntry *next;
1828 bb0c6722 bellard
} QEMUResetEntry;
1829 bb0c6722 bellard
1830 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
1831 bb0c6722 bellard
static int reset_requested;
1832 bb0c6722 bellard
static int shutdown_requested;
1833 bb0c6722 bellard
1834 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
1835 bb0c6722 bellard
{
1836 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
1837 bb0c6722 bellard
1838 bb0c6722 bellard
    pre = &first_reset_entry;
1839 bb0c6722 bellard
    while (*pre != NULL)
1840 bb0c6722 bellard
        pre = &(*pre)->next;
1841 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
1842 bb0c6722 bellard
    re->func = func;
1843 bb0c6722 bellard
    re->opaque = opaque;
1844 bb0c6722 bellard
    re->next = NULL;
1845 bb0c6722 bellard
    *pre = re;
1846 bb0c6722 bellard
}
1847 bb0c6722 bellard
1848 bb0c6722 bellard
void qemu_system_reset(void)
1849 bb0c6722 bellard
{
1850 bb0c6722 bellard
    QEMUResetEntry *re;
1851 bb0c6722 bellard
1852 bb0c6722 bellard
    /* reset all devices */
1853 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
1854 bb0c6722 bellard
        re->func(re->opaque);
1855 bb0c6722 bellard
    }
1856 bb0c6722 bellard
}
1857 bb0c6722 bellard
1858 bb0c6722 bellard
void qemu_system_reset_request(void)
1859 bb0c6722 bellard
{
1860 bb0c6722 bellard
    reset_requested = 1;
1861 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1862 bb0c6722 bellard
}
1863 bb0c6722 bellard
1864 bb0c6722 bellard
void qemu_system_shutdown_request(void)
1865 bb0c6722 bellard
{
1866 bb0c6722 bellard
    shutdown_requested = 1;
1867 bb0c6722 bellard
    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1868 bb0c6722 bellard
}
1869 bb0c6722 bellard
1870 bb0c6722 bellard
static void main_cpu_reset(void *opaque)
1871 bb0c6722 bellard
{
1872 bb0c6722 bellard
#ifdef TARGET_I386
1873 bb0c6722 bellard
    CPUState *env = opaque;
1874 bb0c6722 bellard
    cpu_reset(env);
1875 bb0c6722 bellard
#endif
1876 bb0c6722 bellard
}
1877 bb0c6722 bellard
1878 8a7ddc38 bellard
int main_loop(void)
1879 8a7ddc38 bellard
{
1880 67b915a5 bellard
#ifndef _WIN32
1881 8a7ddc38 bellard
    struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
1882 8a7ddc38 bellard
    IOHandlerRecord *ioh, *ioh_next;
1883 67b915a5 bellard
    uint8_t buf[4096];
1884 67b915a5 bellard
    int n, max_size;
1885 67b915a5 bellard
#endif
1886 67b915a5 bellard
    int ret, timeout;
1887 8a7ddc38 bellard
    CPUState *env = global_env;
1888 8a7ddc38 bellard
1889 8a7ddc38 bellard
    for(;;) {
1890 8a7ddc38 bellard
        if (vm_running) {
1891 8a7ddc38 bellard
            ret = cpu_exec(env);
1892 bb0c6722 bellard
            if (shutdown_requested) {
1893 8a7ddc38 bellard
                ret = EXCP_INTERRUPT; 
1894 8a7ddc38 bellard
                break;
1895 8a7ddc38 bellard
            }
1896 bb0c6722 bellard
            if (reset_requested) {
1897 bb0c6722 bellard
                reset_requested = 0;
1898 bb0c6722 bellard
                qemu_system_reset();
1899 bb0c6722 bellard
                ret = EXCP_INTERRUPT; 
1900 bb0c6722 bellard
            }
1901 8a7ddc38 bellard
            if (ret == EXCP_DEBUG) {
1902 8a7ddc38 bellard
                vm_stop(EXCP_DEBUG);
1903 8a7ddc38 bellard
            }
1904 8a7ddc38 bellard
            /* if hlt instruction, we wait until the next IRQ */
1905 8a7ddc38 bellard
            /* XXX: use timeout computed from timers */
1906 8a7ddc38 bellard
            if (ret == EXCP_HLT) 
1907 8a7ddc38 bellard
                timeout = 10;
1908 8a7ddc38 bellard
            else
1909 8a7ddc38 bellard
                timeout = 0;
1910 8a7ddc38 bellard
        } else {
1911 b4608c04 bellard
            timeout = 10;
1912 8a7ddc38 bellard
        }
1913 c4b1fcc0 bellard
1914 38e205a2 bellard
#ifdef _WIN32
1915 38e205a2 bellard
        if (timeout > 0)
1916 38e205a2 bellard
            Sleep(timeout);
1917 38e205a2 bellard
#else
1918 38e205a2 bellard
1919 b4608c04 bellard
        /* poll any events */
1920 8a7ddc38 bellard
        /* XXX: separate device handlers from system ones */
1921 b4608c04 bellard
        pf = ufds;
1922 8a7ddc38 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
1923 8a7ddc38 bellard
            if (!ioh->fd_can_read) {
1924 8a7ddc38 bellard
                max_size = 0;
1925 c4b1fcc0 bellard
                pf->fd = ioh->fd;
1926 c4b1fcc0 bellard
                pf->events = POLLIN;
1927 c4b1fcc0 bellard
                ioh->ufd = pf;
1928 c4b1fcc0 bellard
                pf++;
1929 c4b1fcc0 bellard
            } else {
1930 8a7ddc38 bellard
                max_size = ioh->fd_can_read(ioh->opaque);
1931 8a7ddc38 bellard
                if (max_size > 0) {
1932 8a7ddc38 bellard
                    if (max_size > sizeof(buf))
1933 8a7ddc38 bellard
                        max_size = sizeof(buf);
1934 8a7ddc38 bellard
                    pf->fd = ioh->fd;
1935 8a7ddc38 bellard
                    pf->events = POLLIN;
1936 8a7ddc38 bellard
                    ioh->ufd = pf;
1937 8a7ddc38 bellard
                    pf++;
1938 8a7ddc38 bellard
                } else {
1939 8a7ddc38 bellard
                    ioh->ufd = NULL;
1940 8a7ddc38 bellard
                }
1941 c4b1fcc0 bellard
            }
1942 c4b1fcc0 bellard
            ioh->max_size = max_size;
1943 b4608c04 bellard
        }
1944 73332e5c bellard
        
1945 b4608c04 bellard
        ret = poll(ufds, pf - ufds, timeout);
1946 b4608c04 bellard
        if (ret > 0) {
1947 8a7ddc38 bellard
            /* XXX: better handling of removal */
1948 8a7ddc38 bellard
            for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
1949 8a7ddc38 bellard
                ioh_next = ioh->next;
1950 c4b1fcc0 bellard
                pf = ioh->ufd;
1951 c4b1fcc0 bellard
                if (pf) {
1952 8a7ddc38 bellard
                    if (pf->revents & POLLIN) {
1953 8a7ddc38 bellard
                        if (ioh->max_size == 0) {
1954 8a7ddc38 bellard
                            /* just a read event */
1955 8a7ddc38 bellard
                            ioh->fd_read(ioh->opaque, NULL, 0);
1956 8a7ddc38 bellard
                        } else {
1957 8a7ddc38 bellard
                            n = read(ioh->fd, buf, ioh->max_size);
1958 8a7ddc38 bellard
                            if (n >= 0) {
1959 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, buf, n);
1960 158156d1 bellard
                            } else if (errno != EAGAIN) {
1961 8a7ddc38 bellard
                                ioh->fd_read(ioh->opaque, NULL, -errno);
1962 8a7ddc38 bellard
                            }
1963 8a7ddc38 bellard
                        }
1964 b4608c04 bellard
                    }
1965 b4608c04 bellard
                }
1966 b4608c04 bellard
            }
1967 b4608c04 bellard
        }
1968 c20709aa bellard
1969 c20709aa bellard
#if defined(CONFIG_SLIRP)
1970 c20709aa bellard
        /* XXX: merge with poll() */
1971 c20709aa bellard
        if (slirp_inited) {
1972 c20709aa bellard
            fd_set rfds, wfds, xfds;
1973 c20709aa bellard
            int nfds;
1974 c20709aa bellard
            struct timeval tv;
1975 c20709aa bellard
1976 c20709aa bellard
            nfds = -1;
1977 c20709aa bellard
            FD_ZERO(&rfds);
1978 c20709aa bellard
            FD_ZERO(&wfds);
1979 c20709aa bellard
            FD_ZERO(&xfds);
1980 c20709aa bellard
            slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
1981 c20709aa bellard
            tv.tv_sec = 0;
1982 c20709aa bellard
            tv.tv_usec = 0;
1983 c20709aa bellard
            ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
1984 c20709aa bellard
            if (ret >= 0) {
1985 c20709aa bellard
                slirp_select_poll(&rfds, &wfds, &xfds);
1986 c20709aa bellard
            }
1987 c20709aa bellard
        }
1988 c20709aa bellard
#endif
1989 c20709aa bellard
1990 67b915a5 bellard
#endif
1991 b4608c04 bellard
1992 8a7ddc38 bellard
        if (vm_running) {
1993 8a7ddc38 bellard
            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
1994 8a7ddc38 bellard
                            qemu_get_clock(vm_clock));
1995 8a7ddc38 bellard
            
1996 aaaa7df6 bellard
            if (audio_enabled) {
1997 aaaa7df6 bellard
                /* XXX: add explicit timer */
1998 aaaa7df6 bellard
                SB16_run();
1999 aaaa7df6 bellard
            }
2000 8a7ddc38 bellard
            
2001 8a7ddc38 bellard
            /* run dma transfers, if any */
2002 8a7ddc38 bellard
            DMA_run();
2003 b4608c04 bellard
        }
2004 313aa567 bellard
2005 8a7ddc38 bellard
        /* real time timers */
2006 8a7ddc38 bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
2007 8a7ddc38 bellard
                        qemu_get_clock(rt_clock));
2008 b4608c04 bellard
    }
2009 34865134 bellard
    cpu_disable_ticks();
2010 34865134 bellard
    return ret;
2011 b4608c04 bellard
}
2012 b4608c04 bellard
2013 0824d6fc bellard
void help(void)
2014 0824d6fc bellard
{
2015 aaaa7df6 bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
2016 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
2017 0824d6fc bellard
           "\n"
2018 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2019 fc01f7e7 bellard
           "\n"
2020 a20dd508 bellard
           "Standard options:\n"
2021 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
2022 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
2023 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
2024 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
2025 6e44ba7f bellard
           "-boot [a|b|c|d] boot on floppy (a, b), hard disk (c) or CD-ROM (d)\n"
2026 a20dd508 bellard
           "-snapshot       write to temporary files instead of disk image files\n"
2027 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
2028 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
2029 aaaa7df6 bellard
           "-enable-audio   enable audio support\n"
2030 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
2031 bb0c6722 bellard
#ifdef TARGET_PPC
2032 bb0c6722 bellard
           "-prep           Simulate a PREP system (default is PowerMAC)\n"
2033 bb0c6722 bellard
#endif
2034 c4b1fcc0 bellard
           "\n"
2035 c4b1fcc0 bellard
           "Network options:\n"
2036 c20709aa bellard
           "-nics n         simulate 'n' network cards [default=1]\n"
2037 702c651c bellard
           "-macaddr addr   set the mac address of the first interface\n"
2038 c20709aa bellard
           "-n script       set tap/tun network init script [default=%s]\n"
2039 c20709aa bellard
           "-tun-fd fd      use this fd as already opened tap/tun interface\n"
2040 c20709aa bellard
#ifdef CONFIG_SLIRP
2041 c20709aa bellard
           "-user-net       use user mode network stack [default if no tap/tun script]\n"
2042 c20709aa bellard
#endif
2043 c20709aa bellard
           "-dummy-net      use dummy network stack\n"
2044 a20dd508 bellard
           "\n"
2045 c4b1fcc0 bellard
           "Linux boot specific:\n"
2046 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
2047 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
2048 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
2049 fc01f7e7 bellard
           "\n"
2050 330d0414 bellard
           "Debug/Expert options:\n"
2051 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
2052 a20dd508 bellard
           "-s              wait gdb connection to port %d\n"
2053 a20dd508 bellard
           "-p port         change gdb connection port\n"
2054 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
2055 a20dd508 bellard
           "-hdachs c,h,s   force hard disk 0 geometry (usually qemu can guess it)\n"
2056 a20dd508 bellard
           "-L path         set the directory for the BIOS and VGA BIOS\n"
2057 77fef8c1 bellard
#ifdef USE_CODE_COPY
2058 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
2059 77fef8c1 bellard
#endif
2060 bb0c6722 bellard
#ifdef TARGET_I386
2061 bb0c6722 bellard
           "-isa            simulate an ISA-only system (default is PCI system)\n"
2062 bb0c6722 bellard
#endif
2063 0824d6fc bellard
           "\n"
2064 f1510b2c bellard
           "During emulation, use C-a h to get terminal commands:\n",
2065 0db63474 bellard
#ifdef CONFIG_SOFTMMU
2066 0db63474 bellard
           "qemu",
2067 0db63474 bellard
#else
2068 0db63474 bellard
           "qemu-fast",
2069 0db63474 bellard
#endif
2070 a00bad7e bellard
           DEFAULT_RAM_SIZE,
2071 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
2072 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
2073 6e44ba7f bellard
           "/tmp/qemu.log");
2074 0824d6fc bellard
    term_print_help();
2075 0db63474 bellard
#ifndef CONFIG_SOFTMMU
2076 0db63474 bellard
    printf("\n"
2077 0db63474 bellard
           "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
2078 0db63474 bellard
           "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
2079 0db63474 bellard
           "PC emulation.\n");
2080 0db63474 bellard
#endif
2081 0824d6fc bellard
    exit(1);
2082 0824d6fc bellard
}
2083 0824d6fc bellard
2084 cd6f1169 bellard
#define HAS_ARG 0x0001
2085 cd6f1169 bellard
2086 cd6f1169 bellard
enum {
2087 cd6f1169 bellard
    QEMU_OPTION_h,
2088 cd6f1169 bellard
2089 cd6f1169 bellard
    QEMU_OPTION_fda,
2090 cd6f1169 bellard
    QEMU_OPTION_fdb,
2091 cd6f1169 bellard
    QEMU_OPTION_hda,
2092 cd6f1169 bellard
    QEMU_OPTION_hdb,
2093 cd6f1169 bellard
    QEMU_OPTION_hdc,
2094 cd6f1169 bellard
    QEMU_OPTION_hdd,
2095 cd6f1169 bellard
    QEMU_OPTION_cdrom,
2096 cd6f1169 bellard
    QEMU_OPTION_boot,
2097 cd6f1169 bellard
    QEMU_OPTION_snapshot,
2098 cd6f1169 bellard
    QEMU_OPTION_m,
2099 cd6f1169 bellard
    QEMU_OPTION_nographic,
2100 cd6f1169 bellard
    QEMU_OPTION_enable_audio,
2101 cd6f1169 bellard
2102 cd6f1169 bellard
    QEMU_OPTION_nics,
2103 cd6f1169 bellard
    QEMU_OPTION_macaddr,
2104 cd6f1169 bellard
    QEMU_OPTION_n,
2105 cd6f1169 bellard
    QEMU_OPTION_tun_fd,
2106 cd6f1169 bellard
    QEMU_OPTION_user_net,
2107 cd6f1169 bellard
    QEMU_OPTION_dummy_net,
2108 cd6f1169 bellard
2109 cd6f1169 bellard
    QEMU_OPTION_kernel,
2110 cd6f1169 bellard
    QEMU_OPTION_append,
2111 cd6f1169 bellard
    QEMU_OPTION_initrd,
2112 cd6f1169 bellard
2113 cd6f1169 bellard
    QEMU_OPTION_S,
2114 cd6f1169 bellard
    QEMU_OPTION_s,
2115 cd6f1169 bellard
    QEMU_OPTION_p,
2116 cd6f1169 bellard
    QEMU_OPTION_d,
2117 cd6f1169 bellard
    QEMU_OPTION_hdachs,
2118 cd6f1169 bellard
    QEMU_OPTION_L,
2119 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
2120 69b91039 bellard
    QEMU_OPTION_pci,
2121 bb0c6722 bellard
    QEMU_OPTION_isa,
2122 77d4bc34 bellard
    QEMU_OPTION_prep,
2123 ee22c2f7 bellard
    QEMU_OPTION_localtime,
2124 1f04275e bellard
    QEMU_OPTION_cirrusvga,
2125 cd6f1169 bellard
};
2126 cd6f1169 bellard
2127 cd6f1169 bellard
typedef struct QEMUOption {
2128 cd6f1169 bellard
    const char *name;
2129 cd6f1169 bellard
    int flags;
2130 cd6f1169 bellard
    int index;
2131 cd6f1169 bellard
} QEMUOption;
2132 cd6f1169 bellard
2133 cd6f1169 bellard
const QEMUOption qemu_options[] = {
2134 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
2135 cd6f1169 bellard
2136 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
2137 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
2138 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
2139 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
2140 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
2141 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
2142 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
2143 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
2144 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
2145 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
2146 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
2147 cd6f1169 bellard
    { "enable-audio", 0, QEMU_OPTION_enable_audio },
2148 cd6f1169 bellard
2149 cd6f1169 bellard
    { "nics", HAS_ARG, QEMU_OPTION_nics},
2150 cd6f1169 bellard
    { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
2151 69b91039 bellard
    { "n", HAS_ARG, QEMU_OPTION_n },
2152 cd6f1169 bellard
    { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
2153 158156d1 bellard
#ifdef CONFIG_SLIRP
2154 cd6f1169 bellard
    { "user-net", 0, QEMU_OPTION_user_net },
2155 158156d1 bellard
#endif
2156 cd6f1169 bellard
    { "dummy-net", 0, QEMU_OPTION_dummy_net },
2157 cd6f1169 bellard
2158 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
2159 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
2160 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
2161 cd6f1169 bellard
2162 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
2163 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
2164 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
2165 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
2166 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
2167 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
2168 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
2169 77d4bc34 bellard
#ifdef TARGET_PPC
2170 77d4bc34 bellard
    { "prep", 0, QEMU_OPTION_prep },
2171 77d4bc34 bellard
#endif
2172 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
2173 bb0c6722 bellard
    { "isa", 0, QEMU_OPTION_isa },
2174 1f04275e bellard
2175 1f04275e bellard
    /* temporary options */
2176 1f04275e bellard
    { "pci", 0, QEMU_OPTION_pci },
2177 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
2178 cd6f1169 bellard
    { NULL },
2179 fc01f7e7 bellard
};
2180 fc01f7e7 bellard
2181 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
2182 77fef8c1 bellard
2183 77fef8c1 bellard
/* this stack is only used during signal handling */
2184 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
2185 77fef8c1 bellard
2186 77fef8c1 bellard
static uint8_t *signal_stack;
2187 77fef8c1 bellard
2188 77fef8c1 bellard
#endif
2189 77fef8c1 bellard
2190 c20709aa bellard
#define NET_IF_TUN   0
2191 c20709aa bellard
#define NET_IF_USER  1
2192 c20709aa bellard
#define NET_IF_DUMMY 2
2193 c20709aa bellard
2194 0824d6fc bellard
int main(int argc, char **argv)
2195 0824d6fc bellard
{
2196 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
2197 67b915a5 bellard
    int use_gdbstub, gdbstub_port;
2198 67b915a5 bellard
#endif
2199 cd6f1169 bellard
    int i, has_cdrom;
2200 1ccde1cb bellard
    int snapshot, linux_boot;
2201 c45886db bellard
    CPUState *env;
2202 7f7f9873 bellard
    const char *initrd_filename;
2203 c45886db bellard
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
2204 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
2205 313aa567 bellard
    DisplayState *ds = &display_state;
2206 c4b1fcc0 bellard
    int cyls, heads, secs;
2207 a541f297 bellard
    int start_emulation = 1;
2208 702c651c bellard
    uint8_t macaddr[6];
2209 c20709aa bellard
    int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
2210 cd6f1169 bellard
    int optind;
2211 cd6f1169 bellard
    const char *r, *optarg;
2212 cd6f1169 bellard
2213 67b915a5 bellard
#if !defined(CONFIG_SOFTMMU)
2214 0824d6fc bellard
    /* we never want that malloc() uses mmap() */
2215 0824d6fc bellard
    mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
2216 67b915a5 bellard
#endif
2217 fc01f7e7 bellard
    initrd_filename = NULL;
2218 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
2219 c45886db bellard
        fd_filename[i] = NULL;
2220 fc01f7e7 bellard
    for(i = 0; i < MAX_DISKS; i++)
2221 fc01f7e7 bellard
        hd_filename[i] = NULL;
2222 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
2223 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
2224 0ced6589 bellard
    bios_size = BIOS_SIZE;
2225 f1510b2c bellard
    pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
2226 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
2227 b4608c04 bellard
    use_gdbstub = 0;
2228 b4608c04 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
2229 67b915a5 bellard
#endif
2230 33e3963e bellard
    snapshot = 0;
2231 a20dd508 bellard
    nographic = 0;
2232 a20dd508 bellard
    kernel_filename = NULL;
2233 a20dd508 bellard
    kernel_cmdline = "";
2234 c4b1fcc0 bellard
    has_cdrom = 1;
2235 c4b1fcc0 bellard
    cyls = heads = secs = 0;
2236 c4b1fcc0 bellard
2237 c20709aa bellard
    nb_tun_fds = 0;
2238 c20709aa bellard
    net_if_type = -1;
2239 c4b1fcc0 bellard
    nb_nics = 1;
2240 702c651c bellard
    /* default mac address of the first network interface */
2241 702c651c bellard
    macaddr[0] = 0x52;
2242 702c651c bellard
    macaddr[1] = 0x54;
2243 702c651c bellard
    macaddr[2] = 0x00;
2244 702c651c bellard
    macaddr[3] = 0x12;
2245 702c651c bellard
    macaddr[4] = 0x34;
2246 702c651c bellard
    macaddr[5] = 0x56;
2247 c20709aa bellard
2248 cd6f1169 bellard
    optind = 1;
2249 0824d6fc bellard
    for(;;) {
2250 cd6f1169 bellard
        if (optind >= argc)
2251 0824d6fc bellard
            break;
2252 cd6f1169 bellard
        r = argv[optind];
2253 cd6f1169 bellard
        if (r[0] != '-') {
2254 cd6f1169 bellard
            hd_filename[0] = argv[optind++];
2255 cd6f1169 bellard
        } else {
2256 cd6f1169 bellard
            const QEMUOption *popt;
2257 cd6f1169 bellard
2258 cd6f1169 bellard
            optind++;
2259 cd6f1169 bellard
            popt = qemu_options;
2260 cd6f1169 bellard
            for(;;) {
2261 cd6f1169 bellard
                if (!popt->name) {
2262 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
2263 cd6f1169 bellard
                            argv[0], r);
2264 cd6f1169 bellard
                    exit(1);
2265 cd6f1169 bellard
                }
2266 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
2267 cd6f1169 bellard
                    break;
2268 cd6f1169 bellard
                popt++;
2269 cd6f1169 bellard
            }
2270 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
2271 cd6f1169 bellard
                if (optind >= argc) {
2272 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
2273 cd6f1169 bellard
                            argv[0], r);
2274 cd6f1169 bellard
                    exit(1);
2275 cd6f1169 bellard
                }
2276 cd6f1169 bellard
                optarg = argv[optind++];
2277 cd6f1169 bellard
            } else {
2278 cd6f1169 bellard
                optarg = NULL;
2279 cd6f1169 bellard
            }
2280 cd6f1169 bellard
2281 cd6f1169 bellard
            switch(popt->index) {
2282 cd6f1169 bellard
            case QEMU_OPTION_initrd:
2283 fc01f7e7 bellard
                initrd_filename = optarg;
2284 fc01f7e7 bellard
                break;
2285 cd6f1169 bellard
            case QEMU_OPTION_hda:
2286 fc01f7e7 bellard
                hd_filename[0] = optarg;
2287 fc01f7e7 bellard
                break;
2288 cd6f1169 bellard
            case QEMU_OPTION_hdb:
2289 fc01f7e7 bellard
                hd_filename[1] = optarg;
2290 fc01f7e7 bellard
                break;
2291 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
2292 33e3963e bellard
                snapshot = 1;
2293 33e3963e bellard
                break;
2294 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
2295 330d0414 bellard
                {
2296 330d0414 bellard
                    const char *p;
2297 330d0414 bellard
                    p = optarg;
2298 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
2299 330d0414 bellard
                    if (*p != ',')
2300 330d0414 bellard
                        goto chs_fail;
2301 330d0414 bellard
                    p++;
2302 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
2303 330d0414 bellard
                    if (*p != ',')
2304 330d0414 bellard
                        goto chs_fail;
2305 330d0414 bellard
                    p++;
2306 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
2307 c4b1fcc0 bellard
                    if (*p != '\0') {
2308 c4b1fcc0 bellard
                    chs_fail:
2309 c4b1fcc0 bellard
                        cyls = 0;
2310 c4b1fcc0 bellard
                    }
2311 330d0414 bellard
                }
2312 330d0414 bellard
                break;
2313 cd6f1169 bellard
            case QEMU_OPTION_nographic:
2314 a20dd508 bellard
                nographic = 1;
2315 a20dd508 bellard
                break;
2316 cd6f1169 bellard
            case QEMU_OPTION_kernel:
2317 a20dd508 bellard
                kernel_filename = optarg;
2318 a20dd508 bellard
                break;
2319 cd6f1169 bellard
            case QEMU_OPTION_append:
2320 a20dd508 bellard
                kernel_cmdline = optarg;
2321 313aa567 bellard
                break;
2322 cd6f1169 bellard
            case QEMU_OPTION_tun_fd:
2323 c4b1fcc0 bellard
                {
2324 c4b1fcc0 bellard
                    const char *p;
2325 c4b1fcc0 bellard
                    int fd;
2326 d6b86f4d bellard
                    net_if_type = NET_IF_TUN;
2327 c20709aa bellard
                    if (nb_tun_fds < MAX_NICS) {
2328 c20709aa bellard
                        fd = strtol(optarg, (char **)&p, 0);
2329 c20709aa bellard
                        if (*p != '\0') {
2330 c20709aa bellard
                            fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
2331 c4b1fcc0 bellard
                            exit(1);
2332 c4b1fcc0 bellard
                        }
2333 c20709aa bellard
                        tun_fds[nb_tun_fds++] = fd;
2334 c4b1fcc0 bellard
                    }
2335 c4b1fcc0 bellard
                }
2336 42f1e0e4 bellard
                break;
2337 cd6f1169 bellard
            case QEMU_OPTION_hdc:
2338 36b486bb bellard
                hd_filename[2] = optarg;
2339 c4b1fcc0 bellard
                has_cdrom = 0;
2340 36b486bb bellard
                break;
2341 cd6f1169 bellard
            case QEMU_OPTION_hdd:
2342 36b486bb bellard
                hd_filename[3] = optarg;
2343 36b486bb bellard
                break;
2344 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
2345 36b486bb bellard
                hd_filename[2] = optarg;
2346 c4b1fcc0 bellard
                has_cdrom = 1;
2347 36b486bb bellard
                break;
2348 cd6f1169 bellard
            case QEMU_OPTION_boot:
2349 36b486bb bellard
                boot_device = optarg[0];
2350 c45886db bellard
                if (boot_device != 'a' && boot_device != 'b' &&
2351 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
2352 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
2353 36b486bb bellard
                    exit(1);
2354 36b486bb bellard
                }
2355 36b486bb bellard
                break;
2356 cd6f1169 bellard
            case QEMU_OPTION_fda:
2357 c45886db bellard
                fd_filename[0] = optarg;
2358 c45886db bellard
                break;
2359 cd6f1169 bellard
            case QEMU_OPTION_fdb:
2360 c45886db bellard
                fd_filename[1] = optarg;
2361 c45886db bellard
                break;
2362 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
2363 77fef8c1 bellard
                code_copy_enabled = 0;
2364 77fef8c1 bellard
                break;
2365 cd6f1169 bellard
            case QEMU_OPTION_nics:
2366 c4b1fcc0 bellard
                nb_nics = atoi(optarg);
2367 3a1bc175 bellard
                if (nb_nics < 0 || nb_nics > MAX_NICS) {
2368 c4b1fcc0 bellard
                    fprintf(stderr, "qemu: invalid number of network interfaces\n");
2369 c4b1fcc0 bellard
                    exit(1);
2370 c4b1fcc0 bellard
                }
2371 c4b1fcc0 bellard
                break;
2372 cd6f1169 bellard
            case QEMU_OPTION_macaddr:
2373 702c651c bellard
                {
2374 702c651c bellard
                    const char *p;
2375 702c651c bellard
                    int i;
2376 702c651c bellard
                    p = optarg;
2377 702c651c bellard
                    for(i = 0; i < 6; i++) {
2378 702c651c bellard
                        macaddr[i] = strtol(p, (char **)&p, 16);
2379 702c651c bellard
                        if (i == 5) {
2380 702c651c bellard
                            if (*p != '\0') 
2381 702c651c bellard
                                goto macaddr_error;
2382 702c651c bellard
                        } else {
2383 702c651c bellard
                            if (*p != ':') {
2384 702c651c bellard
                            macaddr_error:
2385 702c651c bellard
                                fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
2386 702c651c bellard
                                exit(1);
2387 702c651c bellard
                            }
2388 702c651c bellard
                            p++;
2389 702c651c bellard
                        }
2390 702c651c bellard
                    }
2391 702c651c bellard
                }
2392 702c651c bellard
                break;
2393 cd6f1169 bellard
            case QEMU_OPTION_user_net:
2394 c20709aa bellard
                net_if_type = NET_IF_USER;
2395 c20709aa bellard
                break;
2396 cd6f1169 bellard
            case QEMU_OPTION_dummy_net:
2397 c20709aa bellard
                net_if_type = NET_IF_DUMMY;
2398 c20709aa bellard
                break;
2399 cd6f1169 bellard
            case QEMU_OPTION_enable_audio:
2400 aaaa7df6 bellard
                audio_enabled = 1;
2401 aaaa7df6 bellard
                break;
2402 cd6f1169 bellard
            case QEMU_OPTION_h:
2403 0824d6fc bellard
                help();
2404 cd6f1169 bellard
                break;
2405 cd6f1169 bellard
            case QEMU_OPTION_m:
2406 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
2407 cd6f1169 bellard
                if (ram_size <= 0)
2408 cd6f1169 bellard
                    help();
2409 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
2410 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
2411 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
2412 cd6f1169 bellard
                    exit(1);
2413 cd6f1169 bellard
                }
2414 cd6f1169 bellard
                break;
2415 cd6f1169 bellard
            case QEMU_OPTION_d:
2416 cd6f1169 bellard
                {
2417 cd6f1169 bellard
                    int mask;
2418 cd6f1169 bellard
                    CPULogItem *item;
2419 cd6f1169 bellard
                    
2420 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
2421 cd6f1169 bellard
                    if (!mask) {
2422 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
2423 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
2424 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
2425 f193c797 bellard
                    }
2426 f193c797 bellard
                    exit(1);
2427 cd6f1169 bellard
                    }
2428 cd6f1169 bellard
                    cpu_set_log(mask);
2429 f193c797 bellard
                }
2430 cd6f1169 bellard
                break;
2431 cd6f1169 bellard
            case QEMU_OPTION_n:
2432 cd6f1169 bellard
                pstrcpy(network_script, sizeof(network_script), optarg);
2433 cd6f1169 bellard
                break;
2434 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
2435 cd6f1169 bellard
            case QEMU_OPTION_s:
2436 cd6f1169 bellard
                use_gdbstub = 1;
2437 cd6f1169 bellard
                break;
2438 cd6f1169 bellard
            case QEMU_OPTION_p:
2439 cd6f1169 bellard
                gdbstub_port = atoi(optarg);
2440 cd6f1169 bellard
                break;
2441 67b915a5 bellard
#endif
2442 cd6f1169 bellard
            case QEMU_OPTION_L:
2443 cd6f1169 bellard
                bios_dir = optarg;
2444 cd6f1169 bellard
                break;
2445 cd6f1169 bellard
            case QEMU_OPTION_S:
2446 cd6f1169 bellard
                start_emulation = 0;
2447 cd6f1169 bellard
                break;
2448 69b91039 bellard
            case QEMU_OPTION_pci:
2449 69b91039 bellard
                pci_enabled = 1;
2450 69b91039 bellard
                break;
2451 bb0c6722 bellard
            case QEMU_OPTION_isa:
2452 bb0c6722 bellard
                pci_enabled = 0;
2453 bb0c6722 bellard
                break;
2454 77d4bc34 bellard
            case QEMU_OPTION_prep:
2455 77d4bc34 bellard
                prep_enabled = 1;
2456 77d4bc34 bellard
                break;
2457 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
2458 ee22c2f7 bellard
                rtc_utc = 0;
2459 ee22c2f7 bellard
                break;
2460 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
2461 1f04275e bellard
                cirrus_vga_enabled = 1;
2462 1f04275e bellard
                break;
2463 cd6f1169 bellard
            }
2464 0824d6fc bellard
        }
2465 0824d6fc bellard
    }
2466 330d0414 bellard
2467 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
2468 330d0414 bellard
        
2469 c45886db bellard
    if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
2470 c45886db bellard
        fd_filename[0] == '\0')
2471 0824d6fc bellard
        help();
2472 8f2b1fb0 bellard
    
2473 8f2b1fb0 bellard
    /* boot to cd by default if no hard disk */
2474 d0309311 bellard
    if (hd_filename[0] == '\0' && boot_device == 'c') {
2475 d0309311 bellard
        if (fd_filename[0] != '\0')
2476 d0309311 bellard
            boot_device = 'a';
2477 d0309311 bellard
        else
2478 d0309311 bellard
            boot_device = 'd';
2479 d0309311 bellard
    }
2480 0824d6fc bellard
2481 dc887a4d bellard
#if !defined(CONFIG_SOFTMMU)
2482 dc887a4d bellard
    /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
2483 dc887a4d bellard
    {
2484 dc887a4d bellard
        static uint8_t stdout_buf[4096];
2485 dc887a4d bellard
        setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
2486 dc887a4d bellard
    }
2487 dc887a4d bellard
#else
2488 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
2489 dc887a4d bellard
#endif
2490 0824d6fc bellard
2491 c4b1fcc0 bellard
    /* init host network redirectors */
2492 c20709aa bellard
    if (net_if_type == -1) {
2493 c20709aa bellard
        net_if_type = NET_IF_TUN;
2494 c20709aa bellard
#if defined(CONFIG_SLIRP)
2495 c20709aa bellard
        if (access(network_script, R_OK) < 0) {
2496 c20709aa bellard
            net_if_type = NET_IF_USER;
2497 c20709aa bellard
        }
2498 c20709aa bellard
#endif
2499 c20709aa bellard
    }
2500 c20709aa bellard
2501 c20709aa bellard
    for(i = 0; i < nb_nics; i++) {
2502 702c651c bellard
        NetDriverState *nd = &nd_table[i];
2503 c20709aa bellard
        nd->index = i;
2504 702c651c bellard
        /* init virtual mac address */
2505 702c651c bellard
        nd->macaddr[0] = macaddr[0];
2506 702c651c bellard
        nd->macaddr[1] = macaddr[1];
2507 702c651c bellard
        nd->macaddr[2] = macaddr[2];
2508 702c651c bellard
        nd->macaddr[3] = macaddr[3];
2509 702c651c bellard
        nd->macaddr[4] = macaddr[4];
2510 702c651c bellard
        nd->macaddr[5] = macaddr[5] + i;
2511 c20709aa bellard
        switch(net_if_type) {
2512 c20709aa bellard
#if defined(CONFIG_SLIRP)
2513 c20709aa bellard
        case NET_IF_USER:
2514 c20709aa bellard
            net_slirp_init(nd);
2515 c20709aa bellard
            break;
2516 c20709aa bellard
#endif
2517 c20709aa bellard
#if !defined(_WIN32)
2518 c20709aa bellard
        case NET_IF_TUN:
2519 c20709aa bellard
            if (i < nb_tun_fds) {
2520 c20709aa bellard
                net_fd_init(nd, tun_fds[i]);
2521 c20709aa bellard
            } else {
2522 d927637d bellard
                if (net_tun_init(nd) < 0)
2523 d927637d bellard
                    net_dummy_init(nd);
2524 c20709aa bellard
            }
2525 c20709aa bellard
            break;
2526 c20709aa bellard
#endif
2527 c20709aa bellard
        case NET_IF_DUMMY:
2528 c20709aa bellard
        default:
2529 c20709aa bellard
            net_dummy_init(nd);
2530 c20709aa bellard
            break;
2531 c20709aa bellard
        }
2532 702c651c bellard
    }
2533 f1510b2c bellard
2534 0824d6fc bellard
    /* init the memory */
2535 0ced6589 bellard
    phys_ram_size = ram_size + vga_ram_size + bios_size;
2536 7f7f9873 bellard
2537 7f7f9873 bellard
#ifdef CONFIG_SOFTMMU
2538 7d3505c5 bellard
#ifdef _BSD
2539 7d3505c5 bellard
    /* mallocs are always aligned on BSD. */
2540 7d3505c5 bellard
    phys_ram_base = malloc(phys_ram_size);
2541 7d3505c5 bellard
#else
2542 1ccde1cb bellard
    phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size);
2543 7d3505c5 bellard
#endif
2544 7f7f9873 bellard
    if (!phys_ram_base) {
2545 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
2546 0824d6fc bellard
        exit(1);
2547 0824d6fc bellard
    }
2548 7f7f9873 bellard
#else
2549 7f7f9873 bellard
    /* as we must map the same page at several addresses, we must use
2550 7f7f9873 bellard
       a fd */
2551 7f7f9873 bellard
    {
2552 7f7f9873 bellard
        const char *tmpdir;
2553 7f7f9873 bellard
2554 7f7f9873 bellard
        tmpdir = getenv("QEMU_TMPDIR");
2555 7f7f9873 bellard
        if (!tmpdir)
2556 7f7f9873 bellard
            tmpdir = "/tmp";
2557 7f7f9873 bellard
        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/vlXXXXXX", tmpdir);
2558 7f7f9873 bellard
        if (mkstemp(phys_ram_file) < 0) {
2559 7f7f9873 bellard
            fprintf(stderr, "Could not create temporary memory file '%s'\n", 
2560 7f7f9873 bellard
                    phys_ram_file);
2561 7f7f9873 bellard
            exit(1);
2562 7f7f9873 bellard
        }
2563 7f7f9873 bellard
        phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600);
2564 7f7f9873 bellard
        if (phys_ram_fd < 0) {
2565 7f7f9873 bellard
            fprintf(stderr, "Could not open temporary memory file '%s'\n", 
2566 7f7f9873 bellard
                    phys_ram_file);
2567 7f7f9873 bellard
            exit(1);
2568 7f7f9873 bellard
        }
2569 1ccde1cb bellard
        ftruncate(phys_ram_fd, phys_ram_size);
2570 7f7f9873 bellard
        unlink(phys_ram_file);
2571 1ccde1cb bellard
        phys_ram_base = mmap(get_mmap_addr(phys_ram_size), 
2572 1ccde1cb bellard
                             phys_ram_size, 
2573 7f7f9873 bellard
                             PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, 
2574 7f7f9873 bellard
                             phys_ram_fd, 0);
2575 7f7f9873 bellard
        if (phys_ram_base == MAP_FAILED) {
2576 7f7f9873 bellard
            fprintf(stderr, "Could not map physical memory\n");
2577 7f7f9873 bellard
            exit(1);
2578 7f7f9873 bellard
        }
2579 7f7f9873 bellard
    }
2580 7f7f9873 bellard
#endif
2581 0824d6fc bellard
2582 c4b1fcc0 bellard
    /* we always create the cdrom drive, even if no disk is there */
2583 c4b1fcc0 bellard
    if (has_cdrom) {
2584 c4b1fcc0 bellard
        bs_table[2] = bdrv_new("cdrom");
2585 c4b1fcc0 bellard
        bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
2586 c4b1fcc0 bellard
    }
2587 c4b1fcc0 bellard
2588 33e3963e bellard
    /* open the virtual block devices */
2589 33e3963e bellard
    for(i = 0; i < MAX_DISKS; i++) {
2590 33e3963e bellard
        if (hd_filename[i]) {
2591 33e3963e bellard
            if (!bs_table[i]) {
2592 c4b1fcc0 bellard
                char buf[64];
2593 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
2594 c4b1fcc0 bellard
                bs_table[i] = bdrv_new(buf);
2595 c4b1fcc0 bellard
            }
2596 c4b1fcc0 bellard
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
2597 36b486bb bellard
                fprintf(stderr, "qemu: could not open hard disk image '%s\n",
2598 33e3963e bellard
                        hd_filename[i]);
2599 33e3963e bellard
                exit(1);
2600 33e3963e bellard
            }
2601 c4b1fcc0 bellard
            if (i == 0 && cyls != 0) 
2602 c4b1fcc0 bellard
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
2603 c4b1fcc0 bellard
        }
2604 c4b1fcc0 bellard
    }
2605 c4b1fcc0 bellard
2606 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
2607 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
2608 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
2609 c4b1fcc0 bellard
2610 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
2611 c4b1fcc0 bellard
        if (fd_filename[i]) {
2612 c4b1fcc0 bellard
            if (!fd_table[i]) {
2613 c4b1fcc0 bellard
                char buf[64];
2614 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
2615 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
2616 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
2617 c4b1fcc0 bellard
            }
2618 c4b1fcc0 bellard
            if (fd_filename[i] != '\0') {
2619 c4b1fcc0 bellard
                if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
2620 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
2621 c4b1fcc0 bellard
                            fd_filename[i]);
2622 c4b1fcc0 bellard
                    exit(1);
2623 c4b1fcc0 bellard
                }
2624 c4b1fcc0 bellard
            }
2625 33e3963e bellard
        }
2626 33e3963e bellard
    }
2627 33e3963e bellard
2628 330d0414 bellard
    /* init CPU state */
2629 330d0414 bellard
    env = cpu_init();
2630 330d0414 bellard
    global_env = env;
2631 330d0414 bellard
    cpu_single_env = env;
2632 330d0414 bellard
2633 8a7ddc38 bellard
    register_savevm("timer", 0, 1, timer_save, timer_load, env);
2634 8a7ddc38 bellard
    register_savevm("cpu", 0, 1, cpu_save, cpu_load, env);
2635 8a7ddc38 bellard
    register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
2636 bb0c6722 bellard
    qemu_register_reset(main_cpu_reset, global_env);
2637 8a7ddc38 bellard
2638 330d0414 bellard
    init_ioports();
2639 80cabfad bellard
    cpu_calibrate_ticks();
2640 0824d6fc bellard
2641 313aa567 bellard
    /* terminal init */
2642 a20dd508 bellard
    if (nographic) {
2643 313aa567 bellard
        dumb_display_init(ds);
2644 313aa567 bellard
    } else {
2645 313aa567 bellard
#ifdef CONFIG_SDL
2646 313aa567 bellard
        sdl_display_init(ds);
2647 313aa567 bellard
#else
2648 313aa567 bellard
        dumb_display_init(ds);
2649 313aa567 bellard
#endif
2650 313aa567 bellard
    }
2651 0824d6fc bellard
2652 0824d6fc bellard
    /* setup cpu signal handlers for MMU / self modifying code handling */
2653 77fef8c1 bellard
#if !defined(CONFIG_SOFTMMU)
2654 8a7ddc38 bellard
    
2655 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
2656 77fef8c1 bellard
    {
2657 77fef8c1 bellard
        stack_t stk;
2658 73332e5c bellard
        signal_stack = memalign(16, SIGNAL_STACK_SIZE);
2659 77fef8c1 bellard
        stk.ss_sp = signal_stack;
2660 77fef8c1 bellard
        stk.ss_size = SIGNAL_STACK_SIZE;
2661 77fef8c1 bellard
        stk.ss_flags = 0;
2662 77fef8c1 bellard
2663 77fef8c1 bellard
        if (sigaltstack(&stk, NULL) < 0) {
2664 77fef8c1 bellard
            perror("sigaltstack");
2665 77fef8c1 bellard
            exit(1);
2666 77fef8c1 bellard
        }
2667 77fef8c1 bellard
    }
2668 77fef8c1 bellard
#endif
2669 8a7ddc38 bellard
    {
2670 8a7ddc38 bellard
        struct sigaction act;
2671 77fef8c1 bellard
        
2672 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
2673 8a7ddc38 bellard
        act.sa_flags = SA_SIGINFO;
2674 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
2675 8a7ddc38 bellard
        act.sa_flags |= SA_ONSTACK;
2676 77fef8c1 bellard
#endif
2677 8a7ddc38 bellard
        act.sa_sigaction = host_segv_handler;
2678 8a7ddc38 bellard
        sigaction(SIGSEGV, &act, NULL);
2679 8a7ddc38 bellard
        sigaction(SIGBUS, &act, NULL);
2680 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
2681 8a7ddc38 bellard
        sigaction(SIGFPE, &act, NULL);
2682 77fef8c1 bellard
#endif
2683 8a7ddc38 bellard
    }
2684 3a51dee6 bellard
#endif
2685 0824d6fc bellard
2686 67b915a5 bellard
#ifndef _WIN32
2687 8a7ddc38 bellard
    {
2688 8a7ddc38 bellard
        struct sigaction act;
2689 8a7ddc38 bellard
        sigfillset(&act.sa_mask);
2690 8a7ddc38 bellard
        act.sa_flags = 0;
2691 8a7ddc38 bellard
        act.sa_handler = SIG_IGN;
2692 8a7ddc38 bellard
        sigaction(SIGPIPE, &act, NULL);
2693 8a7ddc38 bellard
    }
2694 67b915a5 bellard
#endif
2695 73332e5c bellard
    init_timers();
2696 73332e5c bellard
2697 73332e5c bellard
#if defined(TARGET_I386)
2698 73332e5c bellard
    pc_init(ram_size, vga_ram_size, boot_device,
2699 73332e5c bellard
            ds, fd_filename, snapshot,
2700 73332e5c bellard
            kernel_filename, kernel_cmdline, initrd_filename);
2701 73332e5c bellard
#elif defined(TARGET_PPC)
2702 a541f297 bellard
    ppc_init(ram_size, vga_ram_size, boot_device,
2703 a541f297 bellard
             ds, fd_filename, snapshot,
2704 a541f297 bellard
             kernel_filename, kernel_cmdline, initrd_filename);
2705 73332e5c bellard
#endif
2706 73332e5c bellard
2707 73332e5c bellard
    /* launched after the device init so that it can display or not a
2708 73332e5c bellard
       banner */
2709 73332e5c bellard
    monitor_init();
2710 0824d6fc bellard
2711 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
2712 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
2713 7f7f9873 bellard
2714 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
2715 b4608c04 bellard
    if (use_gdbstub) {
2716 8a7ddc38 bellard
        if (gdbserver_start(gdbstub_port) < 0) {
2717 8a7ddc38 bellard
            fprintf(stderr, "Could not open gdbserver socket on port %d\n", 
2718 8a7ddc38 bellard
                    gdbstub_port);
2719 8a7ddc38 bellard
            exit(1);
2720 8a7ddc38 bellard
        } else {
2721 8a7ddc38 bellard
            printf("Waiting gdb connection on port %d\n", gdbstub_port);
2722 8a7ddc38 bellard
        }
2723 67b915a5 bellard
    } else 
2724 67b915a5 bellard
#endif
2725 a541f297 bellard
    if (start_emulation)
2726 67b915a5 bellard
    {
2727 8a7ddc38 bellard
        vm_start();
2728 0824d6fc bellard
    }
2729 8a7ddc38 bellard
    term_init();
2730 8a7ddc38 bellard
    main_loop();
2731 40c3bac3 bellard
    quit_timers();
2732 0824d6fc bellard
    return 0;
2733 0824d6fc bellard
}