Statistics
| Branch: | Revision:

root / vl.c @ dc5d0b3d

History | View | Annotate | Download (70.8 kB)

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