Statistics
| Branch: | Revision:

root / vl.c @ e80cfcfc

History | View | Annotate | Download (91.6 kB)

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