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