Statistics
| Branch: | Revision:

root / vl.c @ a9049a07

History | View | Annotate | Download (100.3 kB)

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