Statistics
| Branch: | Revision:

root / vl.c @ bc9ed47b

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