Statistics
| Branch: | Revision:

root / vl.c @ c94c8d64

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