ia64/xen-unstable

view tools/ioemu/vl.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents 5e5ae8340956
children 61b3b357d827 4083eb31def0
line source
1 /*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 *
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.
23 */
24 #include "vl.h"
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <signal.h>
29 #include <time.h>
30 #include <errno.h>
31 #include <sys/time.h>
33 #ifndef _WIN32
34 #include <sys/times.h>
35 #include <sys/wait.h>
36 #include <termios.h>
37 #include <sys/poll.h>
38 #include <sys/mman.h>
39 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <dirent.h>
43 #ifdef _BSD
44 #include <sys/stat.h>
45 #ifndef __APPLE__
46 #include <libutil.h>
47 #endif
48 #else
49 #include <linux/if.h>
50 #include <linux/if_tun.h>
51 #include <pty.h>
52 #include <malloc.h>
53 #include <linux/rtc.h>
54 #endif
55 #endif
57 #if defined(CONFIG_SLIRP)
58 #include "libslirp.h"
59 #endif
61 #ifdef _WIN32
62 #include <malloc.h>
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
69 #ifdef CONFIG_SDL
70 #ifdef __APPLE__
71 #include <SDL/SDL.h>
72 #endif
73 #endif /* CONFIG_SDL */
75 #include "xenctrl.h"
76 #include "exec-all.h"
78 //#define DO_TB_FLUSH
80 #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
82 #if !defined(CONFIG_SOFTMMU)
83 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
84 #else
85 #define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
86 #endif
88 #ifdef TARGET_PPC
89 #define DEFAULT_RAM_SIZE 144
90 #else
91 #define DEFAULT_RAM_SIZE 128
92 #endif
93 /* in ms */
94 #define GUI_REFRESH_INTERVAL 30
95 #define POLLING_INTERVAL 5
97 /* XXX: use a two level table to limit memory usage */
98 #define MAX_IOPORTS 65536
100 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
101 char phys_ram_file[1024];
102 CPUState *global_env;
103 CPUState *cpu_single_env;
104 void *ioport_opaque[MAX_IOPORTS];
105 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
106 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
107 BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
108 int vga_ram_size;
109 int bios_size;
110 static DisplayState display_state;
111 int nographic;
112 int usevnc; /* 1=vnc only, 2=vnc and sdl */
113 long vncport; /* server port */
114 const char* vncconnect; /* do a reverse connect to this host*/
115 const char* keyboard_layout = 0;
116 int64_t ticks_per_sec;
117 int boot_device = 'c';
118 int ram_size;
119 int domid = -1;
120 static char network_script[1024];
121 int pit_min_timer_count = 0;
122 int nb_nics;
123 NetDriverState nd_table[MAX_NICS];
124 QEMUTimer *gui_timer;
125 QEMUTimer *polling_timer;
126 int vm_running;
127 int audio_enabled = 0;
128 int nic_pcnet = 1;
129 int vcpus = 1;
130 int sb16_enabled = 1;
131 int adlib_enabled = 1;
132 int gus_enabled = 1;
133 int pci_enabled = 1;
134 int prep_enabled = 0;
135 int rtc_utc = 1;
136 int cirrus_vga_enabled = 1;
137 int vga_accelerate = 1;
138 int graphic_width = 800;
139 int graphic_height = 600;
140 int graphic_depth = 15;
141 int full_screen = 0;
142 TextConsole *vga_console;
143 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
144 int xc_handle;
145 unsigned long *vgapage_array;
146 unsigned long *freepage_array;
147 unsigned long free_pages;
148 void *vtop_table;
149 unsigned long toptab;
150 unsigned long vgaram_pages;
152 /***********************************************************/
153 /* x86 ISA bus support */
155 target_phys_addr_t isa_mem_base = 0;
157 uint32_t default_ioport_readb(void *opaque, uint32_t address)
158 {
159 #ifdef DEBUG_UNUSED_IOPORT
160 fprintf(stderr, "inb: port=0x%04x\n", address);
161 #endif
162 return 0xff;
163 }
165 void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
166 {
167 #ifdef DEBUG_UNUSED_IOPORT
168 fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
169 #endif
170 }
172 /* default is to make two byte accesses */
173 uint32_t default_ioport_readw(void *opaque, uint32_t address)
174 {
175 uint32_t data;
176 data = ioport_read_table[0][address](ioport_opaque[address], address);
177 address = (address + 1) & (MAX_IOPORTS - 1);
178 data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
179 return data;
180 }
182 void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
183 {
184 ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
185 address = (address + 1) & (MAX_IOPORTS - 1);
186 ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
187 }
189 uint32_t default_ioport_readl(void *opaque, uint32_t address)
190 {
191 #ifdef DEBUG_UNUSED_IOPORT
192 fprintf(stderr, "inl: port=0x%04x\n", address);
193 #endif
194 return 0xffffffff;
195 }
197 void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
198 {
199 #ifdef DEBUG_UNUSED_IOPORT
200 fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
201 #endif
202 }
204 void init_ioports(void)
205 {
206 int i;
208 for(i = 0; i < MAX_IOPORTS; i++) {
209 ioport_read_table[0][i] = default_ioport_readb;
210 ioport_write_table[0][i] = default_ioport_writeb;
211 ioport_read_table[1][i] = default_ioport_readw;
212 ioport_write_table[1][i] = default_ioport_writew;
213 ioport_read_table[2][i] = default_ioport_readl;
214 ioport_write_table[2][i] = default_ioport_writel;
215 }
216 }
218 /* size is the word size in byte */
219 int register_ioport_read(int start, int length, int size,
220 IOPortReadFunc *func, void *opaque)
221 {
222 int i, bsize;
224 if (size == 1) {
225 bsize = 0;
226 } else if (size == 2) {
227 bsize = 1;
228 } else if (size == 4) {
229 bsize = 2;
230 } else {
231 hw_error("register_ioport_read: invalid size");
232 return -1;
233 }
234 for(i = start; i < start + length; i += size) {
235 ioport_read_table[bsize][i] = func;
236 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
237 hw_error("register_ioport_read: invalid opaque");
238 ioport_opaque[i] = opaque;
239 }
240 return 0;
241 }
243 /* size is the word size in byte */
244 int register_ioport_write(int start, int length, int size,
245 IOPortWriteFunc *func, void *opaque)
246 {
247 int i, bsize;
249 if (size == 1) {
250 bsize = 0;
251 } else if (size == 2) {
252 bsize = 1;
253 } else if (size == 4) {
254 bsize = 2;
255 } else {
256 hw_error("register_ioport_write: invalid size");
257 return -1;
258 }
259 for(i = start; i < start + length; i += size) {
260 ioport_write_table[bsize][i] = func;
261 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
262 hw_error("register_ioport_read: invalid opaque");
263 ioport_opaque[i] = opaque;
264 }
265 return 0;
266 }
268 void isa_unassign_ioport(int start, int length)
269 {
270 int i;
272 for(i = start; i < start + length; i++) {
273 ioport_read_table[0][i] = default_ioport_readb;
274 ioport_read_table[1][i] = default_ioport_readw;
275 ioport_read_table[2][i] = default_ioport_readl;
277 ioport_write_table[0][i] = default_ioport_writeb;
278 ioport_write_table[1][i] = default_ioport_writew;
279 ioport_write_table[2][i] = default_ioport_writel;
280 }
281 }
283 void pstrcpy(char *buf, int buf_size, const char *str)
284 {
285 int c;
286 char *q = buf;
288 if (buf_size <= 0)
289 return;
291 for(;;) {
292 c = *str++;
293 if (c == 0 || q >= buf + buf_size - 1)
294 break;
295 *q++ = c;
296 }
297 *q = '\0';
298 }
300 /* strcat and truncate. */
301 char *pstrcat(char *buf, int buf_size, const char *s)
302 {
303 int len;
304 len = strlen(buf);
305 if (len < buf_size)
306 pstrcpy(buf + len, buf_size - len, s);
307 return buf;
308 }
310 int strstart(const char *str, const char *val, const char **ptr)
311 {
312 const char *p, *q;
313 p = str;
314 q = val;
315 while (*q != '\0') {
316 if (*p != *q)
317 return 0;
318 p++;
319 q++;
320 }
321 if (ptr)
322 *ptr = p;
323 return 1;
324 }
326 /* return the size or -1 if error */
327 int get_image_size(const char *filename)
328 {
329 int fd, size;
330 fd = open(filename, O_RDONLY | O_BINARY);
331 if (fd < 0)
332 return -1;
333 size = lseek(fd, 0, SEEK_END);
334 close(fd);
335 return size;
336 }
338 /* return the size or -1 if error */
339 int load_image(const char *filename, uint8_t *addr)
340 {
341 int fd, size;
342 fd = open(filename, O_RDONLY | O_BINARY);
343 if (fd < 0)
344 return -1;
345 size = lseek(fd, 0, SEEK_END);
346 lseek(fd, 0, SEEK_SET);
347 if (read(fd, addr, size) != size) {
348 close(fd);
349 return -1;
350 }
351 close(fd);
352 return size;
353 }
355 void cpu_outb(CPUState *env, int addr, int val)
356 {
357 #ifdef DEBUG_IOPORT
358 if (loglevel & CPU_LOG_IOPORT)
359 fprintf(logfile, "outb: %04x %02x\n", addr, val);
360 #endif
361 ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
362 }
364 void cpu_outw(CPUState *env, int addr, int val)
365 {
366 #ifdef DEBUG_IOPORT
367 if (loglevel & CPU_LOG_IOPORT)
368 fprintf(logfile, "outw: %04x %04x\n", addr, val);
369 #endif
370 ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
371 }
373 void cpu_outl(CPUState *env, int addr, int val)
374 {
375 #ifdef DEBUG_IOPORT
376 if (loglevel & CPU_LOG_IOPORT)
377 fprintf(logfile, "outl: %04x %08x\n", addr, val);
378 #endif
379 ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
380 }
382 int cpu_inb(CPUState *env, int addr)
383 {
384 int val;
385 val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
386 #ifdef DEBUG_IOPORT
387 if (loglevel & CPU_LOG_IOPORT)
388 fprintf(logfile, "inb : %04x %02x\n", addr, val);
389 #endif
390 return val;
391 }
393 int cpu_inw(CPUState *env, int addr)
394 {
395 int val;
396 val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
397 #ifdef DEBUG_IOPORT
398 if (loglevel & CPU_LOG_IOPORT)
399 fprintf(logfile, "inw : %04x %04x\n", addr, val);
400 #endif
401 return val;
402 }
404 int cpu_inl(CPUState *env, int addr)
405 {
406 int val;
407 val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
408 #ifdef DEBUG_IOPORT
409 if (loglevel & CPU_LOG_IOPORT)
410 fprintf(logfile, "inl : %04x %08x\n", addr, val);
411 #endif
412 return val;
413 }
415 /***********************************************************/
416 void hw_error(const char *fmt, ...)
417 {
418 va_list ap;
420 va_start(ap, fmt);
421 fprintf(stderr, "qemu: hardware error: ");
422 vfprintf(stderr, fmt, ap);
423 fprintf(stderr, "\n");
424 if (logfile) {
425 fprintf(logfile, "qemu: hardware error: ");
426 vfprintf(logfile, fmt, ap);
427 fprintf(logfile, "\n");
428 }
429 va_end(ap);
430 abort();
431 }
433 /***********************************************************/
434 /* keyboard/mouse */
436 static QEMUPutKBDEvent *qemu_put_kbd_event;
437 static void *qemu_put_kbd_event_opaque;
438 static QEMUPutMouseEvent *qemu_put_mouse_event;
439 static void *qemu_put_mouse_event_opaque;
441 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
442 {
443 qemu_put_kbd_event_opaque = opaque;
444 qemu_put_kbd_event = func;
445 }
447 void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
448 {
449 qemu_put_mouse_event_opaque = opaque;
450 qemu_put_mouse_event = func;
451 }
453 void kbd_put_keycode(int keycode)
454 {
455 if (qemu_put_kbd_event) {
456 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
457 }
458 }
460 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
461 {
462 if (qemu_put_mouse_event) {
463 qemu_put_mouse_event(qemu_put_mouse_event_opaque,
464 dx, dy, dz, buttons_state);
465 }
466 }
468 /***********************************************************/
469 /* timers */
471 #if defined(__powerpc__)
473 static inline uint32_t get_tbl(void)
474 {
475 uint32_t tbl;
476 asm volatile("mftb %0" : "=r" (tbl));
477 return tbl;
478 }
480 static inline uint32_t get_tbu(void)
481 {
482 uint32_t tbl;
483 asm volatile("mftbu %0" : "=r" (tbl));
484 return tbl;
485 }
487 int64_t cpu_get_real_ticks(void)
488 {
489 uint32_t l, h, h1;
490 /* NOTE: we test if wrapping has occurred */
491 do {
492 h = get_tbu();
493 l = get_tbl();
494 h1 = get_tbu();
495 } while (h != h1);
496 return ((int64_t)h << 32) | l;
497 }
499 #elif defined(__i386__)
501 int64_t cpu_get_real_ticks(void)
502 {
503 int64_t val;
504 asm volatile ("rdtsc" : "=A" (val));
505 return val;
506 }
508 #elif defined(__x86_64__)
510 int64_t cpu_get_real_ticks(void)
511 {
512 uint32_t low,high;
513 int64_t val;
514 asm volatile("rdtsc" : "=a" (low), "=d" (high));
515 val = high;
516 val <<= 32;
517 val |= low;
518 return val;
519 }
521 #else
522 #error unsupported CPU
523 #endif
525 static int64_t cpu_ticks_offset;
526 static int cpu_ticks_enabled;
527 int64_t cpu_virt_tsc;
529 static inline int64_t cpu_get_ticks(void)
530 {
531 if (!cpu_ticks_enabled) {
532 return cpu_ticks_offset;
533 } else {
534 return cpu_get_real_ticks() + cpu_ticks_offset;
535 }
537 }
539 /* enable cpu_get_ticks() */
540 void cpu_enable_ticks(void)
541 {
542 if (!cpu_ticks_enabled) {
543 cpu_ticks_offset -= cpu_get_real_ticks();
544 cpu_ticks_enabled = 1;
545 }
546 }
548 /* disable cpu_get_ticks() : the clock is stopped. You must not call
549 cpu_get_ticks() after that. */
550 void cpu_disable_ticks(void)
551 {
552 if (cpu_ticks_enabled) {
553 cpu_ticks_offset = cpu_get_ticks();
554 cpu_ticks_enabled = 0;
555 }
556 }
558 static int64_t get_clock(void)
559 {
560 #ifdef _WIN32
561 struct _timeb tb;
562 _ftime(&tb);
563 return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
564 #else
565 struct timeval tv;
566 gettimeofday(&tv, NULL);
567 return tv.tv_sec * 1000000LL + tv.tv_usec;
568 #endif
569 }
571 void cpu_calibrate_ticks(void)
572 {
573 int64_t usec, ticks;
575 usec = get_clock();
576 ticks = cpu_get_real_ticks();
577 #ifdef _WIN32
578 Sleep(50);
579 #else
580 usleep(50 * 1000);
581 #endif
582 usec = get_clock() - usec;
583 ticks = cpu_get_real_ticks() - ticks;
584 ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
585 }
587 /* compute with 96 bit intermediate result: (a*b)/c */
588 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
589 {
590 union {
591 uint64_t ll;
592 struct {
593 #ifdef WORDS_BIGENDIAN
594 uint32_t high, low;
595 #else
596 uint32_t low, high;
597 #endif
598 } l;
599 } u, res;
600 uint64_t rl, rh;
602 u.ll = a;
603 rl = (uint64_t)u.l.low * (uint64_t)b;
604 rh = (uint64_t)u.l.high * (uint64_t)b;
605 rh += (rl >> 32);
606 res.l.high = rh / c;
607 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
608 return res.ll;
609 }
611 #define QEMU_TIMER_REALTIME 0
612 #define QEMU_TIMER_VIRTUAL 1
614 struct QEMUClock {
615 int type;
616 /* XXX: add frequency */
617 };
619 struct QEMUTimer {
620 QEMUClock *clock;
621 int64_t expire_time;
622 QEMUTimerCB *cb;
623 void *opaque;
624 struct QEMUTimer *next;
625 };
627 QEMUClock *rt_clock;
628 QEMUClock *vm_clock;
630 static QEMUTimer *active_timers[2];
631 #ifdef _WIN32
632 static MMRESULT timerID;
633 #else
634 /* frequency of the times() clock tick */
635 static int timer_freq;
636 #endif
638 QEMUClock *qemu_new_clock(int type)
639 {
640 QEMUClock *clock;
641 clock = qemu_mallocz(sizeof(QEMUClock));
642 if (!clock)
643 return NULL;
644 clock->type = type;
645 return clock;
646 }
648 QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
649 {
650 QEMUTimer *ts;
652 ts = qemu_mallocz(sizeof(QEMUTimer));
653 ts->clock = clock;
654 ts->cb = cb;
655 ts->opaque = opaque;
656 return ts;
657 }
659 void qemu_free_timer(QEMUTimer *ts)
660 {
661 qemu_free(ts);
662 }
664 /* stop a timer, but do not dealloc it */
665 void qemu_del_timer(QEMUTimer *ts)
666 {
667 QEMUTimer **pt, *t;
669 /* NOTE: this code must be signal safe because
670 qemu_timer_expired() can be called from a signal. */
671 pt = &active_timers[ts->clock->type];
672 for(;;) {
673 t = *pt;
674 if (!t)
675 break;
676 if (t == ts) {
677 *pt = t->next;
678 break;
679 }
680 pt = &t->next;
681 }
682 }
684 /* modify the current timer so that it will be fired when current_time
685 >= expire_time. The corresponding callback will be called. */
686 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
687 {
688 QEMUTimer **pt, *t;
690 qemu_del_timer(ts);
692 /* add the timer in the sorted list */
693 /* NOTE: this code must be signal safe because
694 qemu_timer_expired() can be called from a signal. */
695 pt = &active_timers[ts->clock->type];
696 for(;;) {
697 t = *pt;
698 if (!t)
699 break;
700 if (t->expire_time > expire_time)
701 break;
702 pt = &t->next;
703 }
704 ts->expire_time = expire_time;
705 ts->next = *pt;
706 *pt = ts;
707 }
709 int qemu_timer_pending(QEMUTimer *ts)
710 {
711 QEMUTimer *t;
712 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
713 if (t == ts)
714 return 1;
715 }
716 return 0;
717 }
719 static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
720 {
721 if (!timer_head)
722 return 0;
723 return (timer_head->expire_time <= current_time);
724 }
726 static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
727 {
728 QEMUTimer *ts;
730 for(;;) {
731 ts = *ptimer_head;
732 if (!ts || ts->expire_time > current_time)
733 break;
734 /* remove timer from the list before calling the callback */
735 *ptimer_head = ts->next;
736 ts->next = NULL;
738 /* run the callback (the timer list can be modified) */
739 ts->cb(ts->opaque);
740 }
741 }
743 int64_t qemu_get_clock(QEMUClock *clock)
744 {
745 switch(clock->type) {
746 case QEMU_TIMER_REALTIME:
747 #ifdef _WIN32
748 return GetTickCount();
749 #else
750 {
751 struct tms tp;
753 /* Note that using gettimeofday() is not a good solution
754 for timers because its value change when the date is
755 modified. */
756 if (timer_freq == 100) {
757 return times(&tp) * 10;
758 } else {
759 return ((int64_t)times(&tp) * 1000) / timer_freq;
760 }
761 }
762 #endif
763 default:
764 case QEMU_TIMER_VIRTUAL:
765 return cpu_get_ticks();
766 }
767 }
769 /* save a timer */
770 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
771 {
772 uint64_t expire_time;
774 if (qemu_timer_pending(ts)) {
775 expire_time = ts->expire_time;
776 } else {
777 expire_time = -1;
778 }
779 qemu_put_be64(f, expire_time);
780 }
782 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
783 {
784 uint64_t expire_time;
786 expire_time = qemu_get_be64(f);
787 if (expire_time != -1) {
788 qemu_mod_timer(ts, expire_time);
789 } else {
790 qemu_del_timer(ts);
791 }
792 }
794 static void init_timers(void)
795 {
796 rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
797 vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
799 #ifdef _WIN32
800 {
801 int count=0;
802 timerID = timeSetEvent(10, // interval (ms)
803 0, // resolution
804 host_alarm_handler, // function
805 (DWORD)&count, // user parameter
806 TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
807 if( !timerID ) {
808 perror("failed timer alarm");
809 exit(1);
810 }
811 }
812 pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
813 #else
814 {
815 /* get times() syscall frequency */
816 timer_freq = sysconf(_SC_CLK_TCK);
818 #ifndef TARGET_VMX
819 /* timer signal */
820 sigfillset(&act.sa_mask);
821 act.sa_flags = 0;
822 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
823 act.sa_flags |= SA_ONSTACK;
824 #endif
825 act.sa_handler = host_alarm_handler;
826 sigaction(SIGALRM, &act, NULL);
828 itv.it_interval.tv_sec = 0;
829 itv.it_interval.tv_usec = 1000;
830 itv.it_value.tv_sec = 0;
831 itv.it_value.tv_usec = 10 * 1000;
832 setitimer(ITIMER_REAL, &itv, NULL);
833 /* we probe the tick duration of the kernel to inform the user if
834 the emulated kernel requested a too high timer frequency */
835 getitimer(ITIMER_REAL, &itv);
837 #if defined(__linux__)
838 if (itv.it_interval.tv_usec > 1000) {
839 /* try to use /dev/rtc to have a faster timer */
840 if (start_rtc_timer() < 0)
841 goto use_itimer;
842 /* disable itimer */
843 itv.it_interval.tv_sec = 0;
844 itv.it_interval.tv_usec = 0;
845 itv.it_value.tv_sec = 0;
846 itv.it_value.tv_usec = 0;
847 setitimer(ITIMER_REAL, &itv, NULL);
849 /* use the RTC */
850 sigaction(SIGIO, &act, NULL);
851 fcntl(rtc_fd, F_SETFL, O_ASYNC);
852 fcntl(rtc_fd, F_SETOWN, getpid());
853 } else
854 #endif /* defined(__linux__) */
855 {
856 use_itimer:
857 pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
858 PIT_FREQ) / 1000000;
859 }
860 #endif /* TARGET_VMX */
861 }
862 #endif
863 }
865 void quit_timers(void)
866 {
867 #ifdef _WIN32
868 timeKillEvent(timerID);
869 #endif
870 }
872 /***********************************************************/
873 /* character device */
875 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
876 {
877 return s->chr_write(s, buf, len);
878 }
880 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
881 {
882 char buf[4096];
883 va_list ap;
884 va_start(ap, fmt);
885 vsnprintf(buf, sizeof(buf), fmt, ap);
886 qemu_chr_write(s, buf, strlen(buf));
887 va_end(ap);
888 }
890 void qemu_chr_send_event(CharDriverState *s, int event)
891 {
892 if (s->chr_send_event)
893 s->chr_send_event(s, event);
894 }
896 void qemu_chr_add_read_handler(CharDriverState *s,
897 IOCanRWHandler *fd_can_read,
898 IOReadHandler *fd_read, void *opaque)
899 {
900 s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
901 }
903 void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
904 {
905 s->chr_event = chr_event;
906 }
908 static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
909 {
910 return len;
911 }
913 static void null_chr_add_read_handler(CharDriverState *chr,
914 IOCanRWHandler *fd_can_read,
915 IOReadHandler *fd_read, void *opaque)
916 {
917 }
919 CharDriverState *qemu_chr_open_null(void)
920 {
921 CharDriverState *chr;
923 chr = qemu_mallocz(sizeof(CharDriverState));
924 if (!chr)
925 return NULL;
926 chr->chr_write = null_chr_write;
927 chr->chr_add_read_handler = null_chr_add_read_handler;
928 return chr;
929 }
931 #ifndef _WIN32
933 typedef struct {
934 int fd_in, fd_out;
935 /* for nographic stdio only */
936 IOCanRWHandler *fd_can_read;
937 IOReadHandler *fd_read;
938 void *fd_opaque;
939 } FDCharDriver;
941 #define STDIO_MAX_CLIENTS 2
943 static int stdio_nb_clients;
944 static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
946 static int unix_write(int fd, const uint8_t *buf, int len1)
947 {
948 int ret, len;
950 len = len1;
951 while (len > 0) {
952 ret = write(fd, buf, len);
953 if (ret < 0) {
954 if (errno != EINTR && errno != EAGAIN)
955 return -1;
956 } else if (ret == 0) {
957 break;
958 } else {
959 buf += ret;
960 len -= ret;
961 }
962 }
963 return len1 - len;
964 }
966 static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
967 {
968 FDCharDriver *s = chr->opaque;
969 return unix_write(s->fd_out, buf, len);
970 }
972 static void fd_chr_add_read_handler(CharDriverState *chr,
973 IOCanRWHandler *fd_can_read,
974 IOReadHandler *fd_read, void *opaque)
975 {
976 FDCharDriver *s = chr->opaque;
978 if (nographic && s->fd_in == 0) {
979 s->fd_can_read = fd_can_read;
980 s->fd_read = fd_read;
981 s->fd_opaque = opaque;
982 } else {
983 qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
984 }
985 }
987 /* open a character device to a unix fd */
988 CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
989 {
990 CharDriverState *chr;
991 FDCharDriver *s;
993 chr = qemu_mallocz(sizeof(CharDriverState));
994 if (!chr)
995 return NULL;
996 s = qemu_mallocz(sizeof(FDCharDriver));
997 if (!s) {
998 free(chr);
999 return NULL;
1001 s->fd_in = fd_in;
1002 s->fd_out = fd_out;
1003 chr->opaque = s;
1004 chr->chr_write = fd_chr_write;
1005 chr->chr_add_read_handler = fd_chr_add_read_handler;
1006 return chr;
1009 /* for STDIO, we handle the case where several clients use it
1010 (nographic mode) */
1012 #define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
1014 static int term_got_escape, client_index;
1016 void term_print_help(void)
1018 printf("\n"
1019 "C-a h print this help\n"
1020 "C-a x exit emulator\n"
1021 "C-a s save disk data back to file (if -snapshot)\n"
1022 "C-a b send break (magic sysrq)\n"
1023 "C-a c switch between console and monitor\n"
1024 "C-a C-a send C-a\n"
1025 );
1028 /* called when a char is received */
1029 static void stdio_received_byte(int ch)
1031 if (term_got_escape) {
1032 term_got_escape = 0;
1033 switch(ch) {
1034 case 'h':
1035 term_print_help();
1036 break;
1037 case 'x':
1038 exit(0);
1039 break;
1040 case 's':
1042 int i;
1043 for (i = 0; i < MAX_DISKS; i++) {
1044 if (bs_table[i])
1045 bdrv_commit(bs_table[i]);
1048 break;
1049 case 'b':
1050 if (client_index < stdio_nb_clients) {
1051 CharDriverState *chr;
1052 FDCharDriver *s;
1054 chr = stdio_clients[client_index];
1055 s = chr->opaque;
1056 chr->chr_event(s->fd_opaque, CHR_EVENT_BREAK);
1058 break;
1059 case 'c':
1060 client_index++;
1061 if (client_index >= stdio_nb_clients)
1062 client_index = 0;
1063 if (client_index == 0) {
1064 /* send a new line in the monitor to get the prompt */
1065 ch = '\r';
1066 goto send_char;
1068 break;
1069 case TERM_ESCAPE:
1070 goto send_char;
1072 } else if (ch == TERM_ESCAPE) {
1073 term_got_escape = 1;
1074 } else {
1075 send_char:
1076 if (client_index < stdio_nb_clients) {
1077 uint8_t buf[1];
1078 CharDriverState *chr;
1079 FDCharDriver *s;
1081 chr = stdio_clients[client_index];
1082 s = chr->opaque;
1083 buf[0] = ch;
1084 /* XXX: should queue the char if the device is not
1085 ready */
1086 if (s->fd_can_read(s->fd_opaque) > 0)
1087 s->fd_read(s->fd_opaque, buf, 1);
1092 static int stdio_can_read(void *opaque)
1094 /* XXX: not strictly correct */
1095 return 1;
1098 static void stdio_read(void *opaque, const uint8_t *buf, int size)
1100 int i;
1101 for(i = 0; i < size; i++)
1102 stdio_received_byte(buf[i]);
1105 /* init terminal so that we can grab keys */
1106 static struct termios oldtty;
1107 static int old_fd0_flags;
1109 static void term_exit(void)
1111 tcsetattr (0, TCSANOW, &oldtty);
1112 fcntl(0, F_SETFL, old_fd0_flags);
1115 static void term_init(void)
1117 struct termios tty;
1119 tcgetattr (0, &tty);
1120 oldtty = tty;
1121 old_fd0_flags = fcntl(0, F_GETFL);
1123 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1124 |INLCR|IGNCR|ICRNL|IXON);
1125 tty.c_oflag |= OPOST;
1126 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1127 /* if graphical mode, we allow Ctrl-C handling */
1128 if (nographic)
1129 tty.c_lflag &= ~ISIG;
1130 tty.c_cflag &= ~(CSIZE|PARENB);
1131 tty.c_cflag |= CS8;
1132 tty.c_cc[VMIN] = 1;
1133 tty.c_cc[VTIME] = 0;
1135 tcsetattr (0, TCSANOW, &tty);
1137 atexit(term_exit);
1139 fcntl(0, F_SETFL, O_NONBLOCK);
1142 CharDriverState *qemu_chr_open_stdio(void)
1144 CharDriverState *chr;
1146 if (nographic) {
1147 if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
1148 return NULL;
1149 chr = qemu_chr_open_fd(0, 1);
1150 if (stdio_nb_clients == 0)
1151 qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);
1152 client_index = stdio_nb_clients;
1153 } else {
1154 if (stdio_nb_clients != 0)
1155 return NULL;
1156 chr = qemu_chr_open_fd(0, 1);
1158 stdio_clients[stdio_nb_clients++] = chr;
1159 if (stdio_nb_clients == 1) {
1160 /* set the terminal in raw mode */
1161 term_init();
1163 return chr;
1166 #if defined(__linux__)
1167 CharDriverState *qemu_chr_open_pty(void)
1169 char slave_name[1024];
1170 int master_fd, slave_fd;
1172 /* Not satisfying */
1173 if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
1174 return NULL;
1176 fprintf(stderr, "char device redirected to %s\n", slave_name);
1177 return qemu_chr_open_fd(master_fd, master_fd);
1179 #else
1180 CharDriverState *qemu_chr_open_pty(void)
1182 return NULL;
1184 #endif
1186 #endif /* !defined(_WIN32) */
1188 CharDriverState *qemu_chr_open(const char *filename)
1190 if (!strcmp(filename, "vc")) {
1191 return text_console_init(&display_state);
1192 } else if (!strcmp(filename, "null")) {
1193 return qemu_chr_open_null();
1194 } else
1195 #ifndef _WIN32
1196 if (!strcmp(filename, "pty")) {
1197 return qemu_chr_open_pty();
1198 } else if (!strcmp(filename, "stdio")) {
1199 return qemu_chr_open_stdio();
1200 } else
1201 #endif
1203 return NULL;
1207 /***********************************************************/
1208 /* Linux network device redirectors */
1210 void hex_dump(FILE *f, const uint8_t *buf, int size)
1212 int len, i, j, c;
1214 for(i=0;i<size;i+=16) {
1215 len = size - i;
1216 if (len > 16)
1217 len = 16;
1218 fprintf(f, "%08x ", i);
1219 for(j=0;j<16;j++) {
1220 if (j < len)
1221 fprintf(f, " %02x", buf[i+j]);
1222 else
1223 fprintf(f, " ");
1225 fprintf(f, " ");
1226 for(j=0;j<len;j++) {
1227 c = buf[i+j];
1228 if (c < ' ' || c > '~')
1229 c = '.';
1230 fprintf(f, "%c", c);
1232 fprintf(f, "\n");
1236 void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1238 nd->send_packet(nd, buf, size);
1241 void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
1242 IOReadHandler *fd_read, void *opaque)
1244 nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
1247 /* dummy network adapter */
1249 static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1253 static void dummy_add_read_packet(NetDriverState *nd,
1254 IOCanRWHandler *fd_can_read,
1255 IOReadHandler *fd_read, void *opaque)
1259 static int net_dummy_init(NetDriverState *nd)
1261 nd->send_packet = dummy_send_packet;
1262 nd->add_read_packet = dummy_add_read_packet;
1263 pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
1264 return 0;
1267 #if defined(CONFIG_SLIRP)
1269 /* slirp network adapter */
1271 static void *slirp_fd_opaque;
1272 static IOCanRWHandler *slirp_fd_can_read;
1273 static IOReadHandler *slirp_fd_read;
1274 static int slirp_inited;
1276 int slirp_can_output(void)
1278 return slirp_fd_can_read(slirp_fd_opaque);
1281 void slirp_output(const uint8_t *pkt, int pkt_len)
1283 #if 0
1284 printf("output:\n");
1285 hex_dump(stdout, pkt, pkt_len);
1286 #endif
1287 slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
1290 static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1292 #if 0
1293 printf("input:\n");
1294 hex_dump(stdout, buf, size);
1295 #endif
1296 slirp_input(buf, size);
1299 static void slirp_add_read_packet(NetDriverState *nd,
1300 IOCanRWHandler *fd_can_read,
1301 IOReadHandler *fd_read, void *opaque)
1303 slirp_fd_opaque = opaque;
1304 slirp_fd_can_read = fd_can_read;
1305 slirp_fd_read = fd_read;
1308 static int net_slirp_init(NetDriverState *nd)
1310 if (!slirp_inited) {
1311 slirp_inited = 1;
1312 slirp_init();
1314 nd->send_packet = slirp_send_packet;
1315 nd->add_read_packet = slirp_add_read_packet;
1316 pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
1317 return 0;
1320 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
1322 const char *p, *p1;
1323 int len;
1324 p = *pp;
1325 p1 = strchr(p, sep);
1326 if (!p1)
1327 return -1;
1328 len = p1 - p;
1329 p1++;
1330 if (buf_size > 0) {
1331 if (len > buf_size - 1)
1332 len = buf_size - 1;
1333 memcpy(buf, p, len);
1334 buf[len] = '\0';
1336 *pp = p1;
1337 return 0;
1340 static void net_slirp_redir(const char *redir_str)
1342 int is_udp;
1343 char buf[256], *r;
1344 const char *p;
1345 struct in_addr guest_addr;
1346 int host_port, guest_port;
1348 if (!slirp_inited) {
1349 slirp_inited = 1;
1350 slirp_init();
1353 p = redir_str;
1354 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1355 goto fail;
1356 if (!strcmp(buf, "tcp")) {
1357 is_udp = 0;
1358 } else if (!strcmp(buf, "udp")) {
1359 is_udp = 1;
1360 } else {
1361 goto fail;
1364 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1365 goto fail;
1366 host_port = strtol(buf, &r, 0);
1367 if (r == buf)
1368 goto fail;
1370 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
1371 goto fail;
1372 if (buf[0] == '\0') {
1373 pstrcpy(buf, sizeof(buf), "10.0.2.15");
1375 if (!inet_aton(buf, &guest_addr))
1376 goto fail;
1378 guest_port = strtol(p, &r, 0);
1379 if (r == p)
1380 goto fail;
1382 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
1383 fprintf(stderr, "qemu: could not set up redirection\n");
1384 exit(1);
1386 return;
1387 fail:
1388 fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
1389 exit(1);
1392 #ifndef _WIN32
1394 char smb_dir[1024];
1396 static void smb_exit(void)
1398 DIR *d;
1399 struct dirent *de;
1400 char filename[1024];
1402 /* erase all the files in the directory */
1403 d = opendir(smb_dir);
1404 for(;;) {
1405 de = readdir(d);
1406 if (!de)
1407 break;
1408 if (strcmp(de->d_name, ".") != 0 &&
1409 strcmp(de->d_name, "..") != 0) {
1410 snprintf(filename, sizeof(filename), "%s/%s",
1411 smb_dir, de->d_name);
1412 unlink(filename);
1415 closedir(d);
1416 rmdir(smb_dir);
1419 /* automatic user mode samba server configuration */
1420 void net_slirp_smb(const char *exported_dir)
1422 char smb_conf[1024];
1423 char smb_cmdline[1024];
1424 FILE *f;
1426 if (!slirp_inited) {
1427 slirp_inited = 1;
1428 slirp_init();
1431 /* XXX: better tmp dir construction */
1432 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
1433 if (mkdir(smb_dir, 0700) < 0) {
1434 fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
1435 exit(1);
1437 snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
1439 f = fopen(smb_conf, "w");
1440 if (!f) {
1441 fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
1442 exit(1);
1444 fprintf(f,
1445 "[global]\n"
1446 "pid directory=%s\n"
1447 "lock directory=%s\n"
1448 "log file=%s/log.smbd\n"
1449 "smb passwd file=%s/smbpasswd\n"
1450 "security = share\n"
1451 "[qemu]\n"
1452 "path=%s\n"
1453 "read only=no\n"
1454 "guest ok=yes\n",
1455 smb_dir,
1456 smb_dir,
1457 smb_dir,
1458 smb_dir,
1459 exported_dir
1460 );
1461 fclose(f);
1462 atexit(smb_exit);
1464 snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
1465 smb_conf);
1467 slirp_add_exec(0, smb_cmdline, 4, 139);
1470 #endif /* !defined(_WIN32) */
1472 #endif /* CONFIG_SLIRP */
1474 #if !defined(_WIN32)
1475 #ifdef _BSD
1476 static int tun_open(char *ifname, int ifname_size)
1478 int fd;
1479 char *dev;
1480 struct stat s;
1482 fd = open("/dev/tap", O_RDWR);
1483 if (fd < 0) {
1484 fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
1485 return -1;
1488 fstat(fd, &s);
1489 dev = devname(s.st_rdev, S_IFCHR);
1490 pstrcpy(ifname, ifname_size, dev);
1492 fcntl(fd, F_SETFL, O_NONBLOCK);
1493 return fd;
1495 #else
1496 static int tun_open(char *ifname, int ifname_size)
1498 struct ifreq ifr;
1499 int fd, ret;
1501 fd = open("/dev/net/tun", O_RDWR);
1502 if (fd < 0) {
1503 fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1504 return -1;
1506 memset(&ifr, 0, sizeof(ifr));
1507 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1508 pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1509 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1510 if (ret != 0) {
1511 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1512 close(fd);
1513 return -1;
1515 printf("Connected to host network interface: %s\n", ifr.ifr_name);
1516 pstrcpy(ifname, ifname_size, ifr.ifr_name);
1517 fcntl(fd, F_SETFL, O_NONBLOCK);
1518 return fd;
1520 #endif
1522 static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
1524 write(nd->fd, buf, size);
1527 static void tun_add_read_packet(NetDriverState *nd,
1528 IOCanRWHandler *fd_can_read,
1529 IOReadHandler *fd_read, void *opaque)
1531 qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
1534 static int net_tun_init(NetDriverState *nd)
1536 int pid, status;
1537 char *args[3];
1538 char **parg;
1540 nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
1541 if (nd->fd < 0)
1542 return -1;
1544 /* try to launch network init script */
1545 pid = fork();
1546 if (pid >= 0) {
1547 if (pid == 0) {
1548 parg = args;
1549 *parg++ = network_script;
1550 *parg++ = nd->ifname;
1551 *parg++ = NULL;
1552 execv(network_script, args);
1553 exit(1);
1555 while (waitpid(pid, &status, 0) != pid);
1556 if (!WIFEXITED(status) ||
1557 WEXITSTATUS(status) != 0) {
1558 fprintf(stderr, "%s: could not launch network script\n",
1559 network_script);
1562 nd->send_packet = tun_send_packet;
1563 nd->add_read_packet = tun_add_read_packet;
1564 return 0;
1567 static int net_fd_init(NetDriverState *nd, int fd)
1569 nd->fd = fd;
1570 nd->send_packet = tun_send_packet;
1571 nd->add_read_packet = tun_add_read_packet;
1572 pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
1573 return 0;
1576 #endif /* !_WIN32 */
1578 /***********************************************************/
1579 /* dumb display */
1581 static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
1585 static void dumb_resize(DisplayState *ds, int w, int h)
1589 static void dumb_refresh(DisplayState *ds)
1591 vga_update_display();
1594 void dumb_display_init(DisplayState *ds)
1596 ds->data = NULL;
1597 ds->linesize = 0;
1598 ds->depth = 0;
1599 ds->dpy_update = dumb_update;
1600 ds->dpy_resize = dumb_resize;
1601 ds->dpy_refresh = dumb_refresh;
1604 #if !defined(CONFIG_SOFTMMU)
1605 /***********************************************************/
1606 /* cpu signal handler */
1607 static void host_segv_handler(int host_signum, siginfo_t *info,
1608 void *puc)
1610 abort();
1612 #endif
1614 /***********************************************************/
1615 /* I/O handling */
1617 #define MAX_IO_HANDLERS 64
1619 typedef struct IOHandlerRecord {
1620 int fd;
1621 IOCanRWHandler *fd_can_read;
1622 IOReadHandler *fd_read;
1623 void *opaque;
1624 /* temporary data */
1625 struct pollfd *ufd;
1626 int max_size;
1627 struct IOHandlerRecord *next;
1628 } IOHandlerRecord;
1630 static IOHandlerRecord *first_io_handler;
1632 int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
1633 IOReadHandler *fd_read, void *opaque)
1635 IOHandlerRecord *ioh;
1637 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1638 if (!ioh)
1639 return -1;
1640 ioh->fd = fd;
1641 ioh->fd_can_read = fd_can_read;
1642 ioh->fd_read = fd_read;
1643 ioh->opaque = opaque;
1644 ioh->next = first_io_handler;
1645 first_io_handler = ioh;
1646 return 0;
1649 void qemu_del_fd_read_handler(int fd)
1651 IOHandlerRecord **pioh, *ioh;
1653 pioh = &first_io_handler;
1654 for(;;) {
1655 ioh = *pioh;
1656 if (ioh == NULL)
1657 break;
1658 if (ioh->fd == fd) {
1659 *pioh = ioh->next;
1660 break;
1662 pioh = &ioh->next;
1666 /***********************************************************/
1667 /* savevm/loadvm support */
1669 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
1671 fwrite(buf, 1, size, f);
1674 void qemu_put_byte(QEMUFile *f, int v)
1676 fputc(v, f);
1679 void qemu_put_be16(QEMUFile *f, unsigned int v)
1681 qemu_put_byte(f, v >> 8);
1682 qemu_put_byte(f, v);
1685 void qemu_put_be32(QEMUFile *f, unsigned int v)
1687 qemu_put_byte(f, v >> 24);
1688 qemu_put_byte(f, v >> 16);
1689 qemu_put_byte(f, v >> 8);
1690 qemu_put_byte(f, v);
1693 void qemu_put_be64(QEMUFile *f, uint64_t v)
1695 qemu_put_be32(f, v >> 32);
1696 qemu_put_be32(f, v);
1699 int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
1701 return fread(buf, 1, size, f);
1704 int qemu_get_byte(QEMUFile *f)
1706 int v;
1707 v = fgetc(f);
1708 if (v == EOF)
1709 return 0;
1710 else
1711 return v;
1714 unsigned int qemu_get_be16(QEMUFile *f)
1716 unsigned int v;
1717 v = qemu_get_byte(f) << 8;
1718 v |= qemu_get_byte(f);
1719 return v;
1722 unsigned int qemu_get_be32(QEMUFile *f)
1724 unsigned int v;
1725 v = qemu_get_byte(f) << 24;
1726 v |= qemu_get_byte(f) << 16;
1727 v |= qemu_get_byte(f) << 8;
1728 v |= qemu_get_byte(f);
1729 return v;
1732 uint64_t qemu_get_be64(QEMUFile *f)
1734 uint64_t v;
1735 v = (uint64_t)qemu_get_be32(f) << 32;
1736 v |= qemu_get_be32(f);
1737 return v;
1740 int64_t qemu_ftell(QEMUFile *f)
1742 return ftell(f);
1745 int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
1747 if (fseek(f, pos, whence) < 0)
1748 return -1;
1749 return ftell(f);
1752 typedef struct SaveStateEntry {
1753 char idstr[256];
1754 int instance_id;
1755 int version_id;
1756 SaveStateHandler *save_state;
1757 LoadStateHandler *load_state;
1758 void *opaque;
1759 struct SaveStateEntry *next;
1760 } SaveStateEntry;
1762 static SaveStateEntry *first_se;
1764 int register_savevm(const char *idstr,
1765 int instance_id,
1766 int version_id,
1767 SaveStateHandler *save_state,
1768 LoadStateHandler *load_state,
1769 void *opaque)
1771 SaveStateEntry *se, **pse;
1773 se = qemu_malloc(sizeof(SaveStateEntry));
1774 if (!se)
1775 return -1;
1776 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
1777 se->instance_id = instance_id;
1778 se->version_id = version_id;
1779 se->save_state = save_state;
1780 se->load_state = load_state;
1781 se->opaque = opaque;
1782 se->next = NULL;
1784 /* add at the end of list */
1785 pse = &first_se;
1786 while (*pse != NULL)
1787 pse = &(*pse)->next;
1788 *pse = se;
1789 return 0;
1792 #define QEMU_VM_FILE_MAGIC 0x5145564d
1793 #define QEMU_VM_FILE_VERSION 0x00000001
1795 int qemu_savevm(const char *filename)
1797 SaveStateEntry *se;
1798 QEMUFile *f;
1799 int len, len_pos, cur_pos, saved_vm_running, ret;
1801 saved_vm_running = vm_running;
1802 vm_stop(0);
1804 f = fopen(filename, "wb");
1805 if (!f) {
1806 ret = -1;
1807 goto the_end;
1810 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
1811 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
1813 for(se = first_se; se != NULL; se = se->next) {
1814 /* ID string */
1815 len = strlen(se->idstr);
1816 qemu_put_byte(f, len);
1817 qemu_put_buffer(f, se->idstr, len);
1819 qemu_put_be32(f, se->instance_id);
1820 qemu_put_be32(f, se->version_id);
1822 /* record size: filled later */
1823 len_pos = ftell(f);
1824 qemu_put_be32(f, 0);
1826 se->save_state(f, se->opaque);
1828 /* fill record size */
1829 cur_pos = ftell(f);
1830 len = ftell(f) - len_pos - 4;
1831 fseek(f, len_pos, SEEK_SET);
1832 qemu_put_be32(f, len);
1833 fseek(f, cur_pos, SEEK_SET);
1836 fclose(f);
1837 ret = 0;
1838 the_end:
1839 if (saved_vm_running)
1840 vm_start();
1841 return ret;
1844 static SaveStateEntry *find_se(const char *idstr, int instance_id)
1846 SaveStateEntry *se;
1848 for(se = first_se; se != NULL; se = se->next) {
1849 if (!strcmp(se->idstr, idstr) &&
1850 instance_id == se->instance_id)
1851 return se;
1853 return NULL;
1856 int qemu_loadvm(const char *filename)
1858 SaveStateEntry *se;
1859 QEMUFile *f;
1860 int len, cur_pos, ret, instance_id, record_len, version_id;
1861 int saved_vm_running;
1862 unsigned int v;
1863 char idstr[256];
1865 saved_vm_running = vm_running;
1866 vm_stop(0);
1868 f = fopen(filename, "rb");
1869 if (!f) {
1870 ret = -1;
1871 goto the_end;
1874 v = qemu_get_be32(f);
1875 if (v != QEMU_VM_FILE_MAGIC)
1876 goto fail;
1877 v = qemu_get_be32(f);
1878 if (v != QEMU_VM_FILE_VERSION) {
1879 fail:
1880 fclose(f);
1881 ret = -1;
1882 goto the_end;
1884 for(;;) {
1885 #if defined (DO_TB_FLUSH)
1886 tb_flush(global_env);
1887 #endif
1888 len = qemu_get_byte(f);
1889 if (feof(f))
1890 break;
1891 qemu_get_buffer(f, idstr, len);
1892 idstr[len] = '\0';
1893 instance_id = qemu_get_be32(f);
1894 version_id = qemu_get_be32(f);
1895 record_len = qemu_get_be32(f);
1896 #if 0
1897 printf("idstr=%s instance=0x%x version=%d len=%d\n",
1898 idstr, instance_id, version_id, record_len);
1899 #endif
1900 cur_pos = ftell(f);
1901 se = find_se(idstr, instance_id);
1902 if (!se) {
1903 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
1904 instance_id, idstr);
1905 } else {
1906 ret = se->load_state(f, se->opaque, version_id);
1907 if (ret < 0) {
1908 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
1909 instance_id, idstr);
1912 /* always seek to exact end of record */
1913 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
1915 fclose(f);
1916 ret = 0;
1917 the_end:
1918 if (saved_vm_running)
1919 vm_start();
1920 return ret;
1923 /***********************************************************/
1924 /* main execution loop */
1926 void gui_update(void *opaque)
1928 display_state.dpy_refresh(&display_state);
1929 qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
1931 void polling_handler(void *opaque)
1933 #ifndef _WIN32
1934 struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
1935 IOHandlerRecord *ioh, *ioh_next;
1936 uint8_t buf[4096];
1937 int n, max_size;
1938 #endif
1939 int timeout = 0;
1940 int ret;
1942 #ifdef _WIN32
1943 if (timeout > 0)
1944 Sleep(timeout);
1945 #else
1946 /* poll any events */
1947 /* XXX: separate device handlers from system ones */
1948 pf = ufds;
1949 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
1950 if (!ioh->fd_can_read) {
1951 max_size = 0;
1952 pf->fd = ioh->fd;
1953 pf->events = POLLIN;
1954 ioh->ufd = pf;
1955 pf++;
1956 } else {
1957 max_size = ioh->fd_can_read(ioh->opaque);
1958 if (max_size > 0) {
1959 if (max_size > sizeof(buf))
1960 max_size = sizeof(buf);
1961 pf->fd = ioh->fd;
1962 pf->events = POLLIN;
1963 ioh->ufd = pf;
1964 pf++;
1965 } else {
1966 ioh->ufd = NULL;
1969 ioh->max_size = max_size;
1972 ret = poll(ufds, pf - ufds, timeout);
1973 if (ret > 0) {
1974 /* XXX: better handling of removal */
1975 for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
1976 ioh_next = ioh->next;
1977 pf = ioh->ufd;
1978 if (pf) {
1979 if (pf->revents & POLLIN) {
1980 if (ioh->max_size == 0) {
1981 /* just a read event */
1982 ioh->fd_read(ioh->opaque, NULL, 0);
1983 } else {
1984 n = read(ioh->fd, buf, ioh->max_size);
1985 if (n >= 0) {
1986 ioh->fd_read(ioh->opaque, buf, n);
1987 } else if (errno != EAGAIN) {
1988 ioh->fd_read(ioh->opaque, NULL, -errno);
1995 #endif /* !defined(_WIN32) */
1997 qemu_mod_timer(polling_timer, POLLING_INTERVAL + qemu_get_clock(rt_clock));
2001 /* XXX: support several handlers */
2002 VMStopHandler *vm_stop_cb;
2003 VMStopHandler *vm_stop_opaque;
2005 int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
2007 vm_stop_cb = cb;
2008 vm_stop_opaque = opaque;
2009 return 0;
2012 void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
2014 vm_stop_cb = NULL;
2017 void vm_start(void)
2019 if (!vm_running) {
2020 cpu_enable_ticks();
2021 vm_running = 1;
2025 void vm_stop(int reason)
2027 if (vm_running) {
2028 cpu_disable_ticks();
2029 vm_running = 0;
2030 if (reason != 0) {
2031 if (vm_stop_cb) {
2032 vm_stop_cb(vm_stop_opaque, reason);
2038 /* reset/shutdown handler */
2040 typedef struct QEMUResetEntry {
2041 QEMUResetHandler *func;
2042 void *opaque;
2043 struct QEMUResetEntry *next;
2044 } QEMUResetEntry;
2046 static QEMUResetEntry *first_reset_entry;
2047 int reset_requested;
2048 int shutdown_requested;
2050 void qemu_register_reset(QEMUResetHandler *func, void *opaque)
2052 QEMUResetEntry **pre, *re;
2054 pre = &first_reset_entry;
2055 while (*pre != NULL)
2056 pre = &(*pre)->next;
2057 re = qemu_mallocz(sizeof(QEMUResetEntry));
2058 re->func = func;
2059 re->opaque = opaque;
2060 re->next = NULL;
2061 *pre = re;
2064 void qemu_system_reset(void)
2066 QEMUResetEntry *re;
2068 /* reset all devices */
2069 for(re = first_reset_entry; re != NULL; re = re->next) {
2070 re->func(re->opaque);
2074 void qemu_system_reset_request(void)
2076 reset_requested = 1;
2077 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2080 void qemu_system_shutdown_request(void)
2082 shutdown_requested = 1;
2083 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2086 void main_loop_wait(int timeout)
2088 if (vm_running) {
2089 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
2090 qemu_get_clock(vm_clock));
2091 /* run dma transfers, if any */
2092 DMA_run();
2095 /* real time timers */
2096 qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
2097 qemu_get_clock(rt_clock));
2100 void help(void)
2102 printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
2103 "usage: %s [options] [disk_image]\n"
2104 "\n"
2105 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2106 "\n"
2107 "Standard options:\n"
2108 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
2109 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
2110 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
2111 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
2112 "-boot [a|c|d] boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
2113 "-snapshot write to temporary files instead of disk image files\n"
2114 "-m megs set virtual RAM size to megs MB [default=%d]\n"
2115 "-nographic disable graphical output and redirect serial I/Os to console\n"
2116 "-vcpus set CPU number of guest platform\n"
2117 #ifdef CONFIG_VNC
2118 "-vnc port use vnc instead of sdl\n"
2119 "-vncport port use a different port\n"
2120 "-vncconnect host:port do a reverse connect\n"
2121 #ifdef CONFIG_SDL
2122 "-vnc-and-sdl use vnc and sdl simultaneously\n"
2123 #endif
2124 #endif
2125 "-k <language> use keyboard layout (for example \"fr\" for french)\n"
2126 "-enable-audio enable audio support\n"
2127 "-localtime set the real time clock to local time [default=utc]\n"
2128 "-full-screen start in full screen\n"
2129 #ifdef TARGET_PPC
2130 "-prep Simulate a PREP system (default is PowerMAC)\n"
2131 "-g WxH[xDEPTH] Set the initial VGA graphic mode\n"
2132 #endif
2133 "-nic-pcnet simulate an AMD PC-Net PCI ethernet adaptor\n"
2134 "\n"
2135 "Network options:\n"
2136 "-nics n simulate 'n' network cards [default=1]\n"
2137 "-macaddr addr set the mac address of the first interface\n"
2138 "-n script set tap/tun network init script [default=%s]\n"
2139 "-tun-fd fd use this fd as already opened tap/tun interface\n"
2140 #ifdef CONFIG_SLIRP
2141 "-user-net use user mode network stack [default if no tap/tun script]\n"
2142 "-tftp prefix allow tftp access to files starting with prefix [-user-net]\n"
2143 #ifndef _WIN32
2144 "-smb dir allow SMB access to files in 'dir' [-user-net]\n"
2145 #endif
2146 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
2147 " redirect TCP or UDP connections from host to guest [-user-net]\n"
2148 #endif
2149 "-dummy-net use dummy network stack\n"
2150 "\n"
2151 "Linux boot specific:\n"
2152 "-kernel bzImage use 'bzImage' as kernel image\n"
2153 "-append cmdline use 'cmdline' as kernel command line\n"
2154 "-initrd file use 'file' as initial ram disk\n"
2155 "\n"
2156 "Debug/Expert options:\n"
2157 "-monitor dev redirect the monitor to char device 'dev'\n"
2158 "-serial dev redirect the serial port to char device 'dev'\n"
2159 "-S freeze CPU at startup (use 'c' to start execution)\n"
2160 "-s wait gdb connection to port %d\n"
2161 "-p port ioreq port for xen\n"
2162 "-d domain domain that we're serving\n"
2163 "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
2164 "-L path set the directory for the BIOS and VGA BIOS\n"
2165 #ifdef USE_CODE_COPY
2166 "-no-code-copy disable code copy acceleration\n"
2167 #endif
2168 #ifdef TARGET_I386
2169 "-isa simulate an ISA-only system (default is PCI system)\n"
2170 "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
2171 " (default is CL-GD5446 PCI VGA)\n"
2172 "-vgaacc [0|1] 1 to accelerate CL-GD5446 speed, default is 1\n"
2173 #endif
2174 "-loadvm file start right away with a saved state (loadvm in monitor)\n"
2175 "\n"
2176 "During emulation, the following keys are useful:\n"
2177 "ctrl-alt-f toggle full screen\n"
2178 "ctrl-alt-n switch to virtual console 'n'\n"
2179 "ctrl-alt toggle mouse and keyboard grab\n"
2180 "\n"
2181 "When using -nographic, press 'ctrl-a h' to get some help.\n"
2183 #ifdef CONFIG_SOFTMMU
2184 "qemu",
2185 #else
2186 "qemu-fast",
2187 #endif
2188 DEFAULT_RAM_SIZE,
2189 DEFAULT_NETWORK_SCRIPT,
2190 DEFAULT_GDBSTUB_PORT);
2191 #ifndef CONFIG_SOFTMMU
2192 printf("\n"
2193 "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
2194 "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
2195 "PC emulation.\n");
2196 #endif
2197 exit(1);
2200 #define HAS_ARG 0x0001
2202 enum {
2203 QEMU_OPTION_h,
2205 QEMU_OPTION_fda,
2206 QEMU_OPTION_fdb,
2207 QEMU_OPTION_hda,
2208 QEMU_OPTION_hdb,
2209 QEMU_OPTION_hdc,
2210 QEMU_OPTION_hdd,
2211 QEMU_OPTION_cdrom,
2212 QEMU_OPTION_boot,
2213 QEMU_OPTION_snapshot,
2214 QEMU_OPTION_m,
2215 QEMU_OPTION_nographic,
2216 #ifdef CONFIG_VNC
2217 QEMU_OPTION_vnc,
2218 QEMU_OPTION_vncport,
2219 QEMU_OPTION_vncconnect,
2220 #ifdef CONFIG_SDL
2221 QEMU_OPTION_vnc_and_sdl,
2222 #endif
2223 #endif
2224 QEMU_OPTION_enable_audio,
2226 QEMU_OPTION_nics,
2227 QEMU_OPTION_macaddr,
2228 QEMU_OPTION_n,
2229 QEMU_OPTION_tun_fd,
2230 QEMU_OPTION_user_net,
2231 QEMU_OPTION_tftp,
2232 QEMU_OPTION_smb,
2233 QEMU_OPTION_redir,
2234 QEMU_OPTION_dummy_net,
2236 QEMU_OPTION_kernel,
2237 QEMU_OPTION_append,
2238 QEMU_OPTION_initrd,
2240 QEMU_OPTION_S,
2241 QEMU_OPTION_s,
2242 QEMU_OPTION_p,
2243 QEMU_OPTION_d,
2244 QEMU_OPTION_l,
2245 QEMU_OPTION_hdachs,
2246 QEMU_OPTION_L,
2247 QEMU_OPTION_no_code_copy,
2248 QEMU_OPTION_vcpus,
2249 QEMU_OPTION_pci,
2250 QEMU_OPTION_nic_pcnet,
2251 QEMU_OPTION_isa,
2252 QEMU_OPTION_prep,
2253 QEMU_OPTION_k,
2254 QEMU_OPTION_localtime,
2255 QEMU_OPTION_cirrusvga,
2256 QEMU_OPTION_g,
2257 QEMU_OPTION_std_vga,
2258 QEMU_OPTION_monitor,
2259 QEMU_OPTION_serial,
2260 QEMU_OPTION_loadvm,
2261 QEMU_OPTION_full_screen,
2262 QEMU_OPTION_vgaacc,
2263 };
2265 typedef struct QEMUOption {
2266 const char *name;
2267 int flags;
2268 int index;
2269 } QEMUOption;
2271 const QEMUOption qemu_options[] = {
2272 { "h", 0, QEMU_OPTION_h },
2274 { "fda", HAS_ARG, QEMU_OPTION_fda },
2275 { "fdb", HAS_ARG, QEMU_OPTION_fdb },
2276 { "hda", HAS_ARG, QEMU_OPTION_hda },
2277 { "hdb", HAS_ARG, QEMU_OPTION_hdb },
2278 { "hdc", HAS_ARG, QEMU_OPTION_hdc },
2279 { "hdd", HAS_ARG, QEMU_OPTION_hdd },
2280 { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
2281 { "boot", HAS_ARG, QEMU_OPTION_boot },
2282 { "snapshot", 0, QEMU_OPTION_snapshot },
2283 { "m", HAS_ARG, QEMU_OPTION_m },
2284 { "nographic", 0, QEMU_OPTION_nographic },
2285 #ifdef CONFIG_VNC
2286 { "vnc", 0, QEMU_OPTION_vnc },
2287 { "vncport", HAS_ARG, QEMU_OPTION_vncport },
2288 { "vncconnect", HAS_ARG, QEMU_OPTION_vncconnect },
2289 #ifdef CONFIG_SDL
2290 { "vnc-and-sdl", 0, QEMU_OPTION_vnc_and_sdl },
2291 #endif
2292 #endif
2293 { "k", HAS_ARG, QEMU_OPTION_k },
2294 { "enable-audio", 0, QEMU_OPTION_enable_audio },
2296 { "nics", HAS_ARG, QEMU_OPTION_nics},
2297 { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
2298 { "n", HAS_ARG, QEMU_OPTION_n },
2299 { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
2300 #ifdef CONFIG_SLIRP
2301 { "user-net", 0, QEMU_OPTION_user_net },
2302 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
2303 #ifndef _WIN32
2304 { "smb", HAS_ARG, QEMU_OPTION_smb },
2305 #endif
2306 { "redir", HAS_ARG, QEMU_OPTION_redir },
2307 #endif
2308 { "dummy-net", 0, QEMU_OPTION_dummy_net },
2310 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
2311 { "append", HAS_ARG, QEMU_OPTION_append },
2312 { "initrd", HAS_ARG, QEMU_OPTION_initrd },
2314 { "S", 0, QEMU_OPTION_S },
2315 { "s", 0, QEMU_OPTION_s },
2316 { "p", HAS_ARG, QEMU_OPTION_p },
2317 { "d", HAS_ARG, QEMU_OPTION_d },
2318 { "l", HAS_ARG, QEMU_OPTION_l },
2319 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
2320 { "L", HAS_ARG, QEMU_OPTION_L },
2321 { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
2322 { "vcpus", 1, QEMU_OPTION_vcpus },
2323 #ifdef TARGET_PPC
2324 { "prep", 0, QEMU_OPTION_prep },
2325 { "g", 1, QEMU_OPTION_g },
2326 #endif
2327 { "localtime", 0, QEMU_OPTION_localtime },
2328 { "isa", 0, QEMU_OPTION_isa },
2329 { "std-vga", 0, QEMU_OPTION_std_vga },
2330 { "monitor", 1, QEMU_OPTION_monitor },
2331 { "serial", 1, QEMU_OPTION_serial },
2332 { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
2333 { "full-screen", 0, QEMU_OPTION_full_screen },
2335 /* temporary options */
2336 { "pci", 0, QEMU_OPTION_pci },
2337 { "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
2338 { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
2339 { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
2340 { NULL },
2341 };
2343 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
2345 /* this stack is only used during signal handling */
2346 #define SIGNAL_STACK_SIZE 32768
2348 static uint8_t *signal_stack;
2350 #endif
2352 #define NET_IF_TUN 0
2353 #define NET_IF_USER 1
2354 #define NET_IF_DUMMY 2
2356 #include <xg_private.h>
2358 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
2359 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
2361 #ifdef __i386__
2362 #define _LEVEL_3_ 0
2363 #else
2364 #define _LEVEL_3_ 1
2365 #endif
2367 #if _LEVEL_3_
2368 #define L3_PROT (_PAGE_PRESENT)
2369 #define L1_PAGETABLE_ENTRIES 512
2370 #else
2371 #define L1_PAGETABLE_ENTRIES 1024
2372 #endif
2374 inline int
2375 get_vl2_table(unsigned long count, unsigned long start)
2377 #if _LEVEL_3_
2378 return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
2379 #else
2380 return 0;
2381 #endif
2384 int
2385 setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end)
2387 l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
2388 l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL};
2389 l2_pgentry_t *vl2e=NULL, *vl2_table = NULL;
2390 unsigned long l1tab;
2391 unsigned long ppt_alloc = 0;
2392 unsigned long count;
2393 int i = 0;
2394 #if _LEVEL_3_
2395 l3_pgentry_t *vl3tab = NULL;
2396 unsigned long l2tab;
2397 if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2398 PROT_READ|PROT_WRITE,
2399 toptab >> PAGE_SHIFT)) == NULL )
2400 goto error_out;
2401 for (i = 0; i < 4 ; i++) {
2402 l2tab = vl3tab[i] & PAGE_MASK;
2403 vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2404 PROT_READ|PROT_WRITE,
2405 l2tab >> PAGE_SHIFT);
2406 if(vl2tab[i] == NULL)
2407 goto error_out;
2409 munmap(vl3tab, PAGE_SIZE);
2410 vl3tab = NULL;
2411 #else
2412 if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2413 PROT_READ|PROT_WRITE,
2414 toptab >> PAGE_SHIFT)) == NULL )
2415 goto error_out;
2416 #endif
2418 for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
2420 if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
2422 vl2_table = vl2tab[get_vl2_table(count, v_start)];
2423 vl2e = &vl2_table[l2_table_offset(
2424 v_start + (count << PAGE_SHIFT))];
2426 l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT;
2427 if ( vl1tab != NULL )
2428 munmap(vl1tab, PAGE_SIZE);
2430 if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2431 PROT_READ|PROT_WRITE,
2432 l1tab >> PAGE_SHIFT)) == NULL )
2434 goto error_out;
2436 memset(vl1tab, 0, PAGE_SIZE);
2437 vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
2438 *vl2e = l1tab | L2_PROT;
2441 *vl1e = (mem_page_array[count] << PAGE_SHIFT) | L1_PROT;
2442 vl1e++;
2444 error_out:
2445 if(vl1tab) munmap(vl1tab, PAGE_SIZE);
2446 for(i = 0; i < 4; i++)
2447 if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
2448 return ppt_alloc;
2451 void
2452 unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long v_start, unsigned long v_end)
2454 l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
2455 l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
2456 unsigned long l1tab;
2457 unsigned long count;
2458 int i = 0;
2459 #if _LEVEL_3_
2460 l3_pgentry_t *vl3tab = NULL;
2461 unsigned long l2tab;
2462 if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2463 PROT_READ|PROT_WRITE,
2464 toptab >> PAGE_SHIFT)) == NULL )
2465 goto error_out;
2466 for (i = 0; i < 4 ; i ++){
2467 l2tab = vl3tab[i] & PAGE_MASK;
2468 vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2469 PROT_READ|PROT_WRITE,
2470 l2tab >> PAGE_SHIFT);
2471 if(vl2tab[i] == NULL)
2472 goto error_out;
2474 munmap(vl3tab, PAGE_SIZE);
2475 vl3tab = NULL;
2476 #else
2477 if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2478 PROT_READ|PROT_WRITE,
2479 toptab >> PAGE_SHIFT)) == NULL )
2480 goto error_out;
2481 #endif
2483 for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){
2484 if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
2486 vl2_table = vl2tab[get_vl2_table(count, v_start)];
2487 vl2e = &vl2_table[l2_table_offset(v_start + (count << PAGE_SHIFT))];
2488 l1tab = *vl2e & PAGE_MASK;
2490 if(l1tab == 0)
2491 continue;
2492 if ( vl1tab != NULL )
2493 munmap(vl1tab, PAGE_SIZE);
2495 if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
2496 PROT_READ|PROT_WRITE,
2497 l1tab >> PAGE_SHIFT)) == NULL )
2499 goto error_out;
2501 vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
2502 *vl2e = 0;
2505 *vl1e = 0;
2506 vl1e++;
2508 error_out:
2509 if(vl1tab) munmap(vl1tab, PAGE_SIZE);
2510 for(i = 0; i < 4; i++)
2511 if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
2514 void set_vram_mapping(unsigned long addr, unsigned long end)
2516 end = addr + VGA_RAM_SIZE;
2517 setup_mapping(xc_handle, domid, toptab,
2518 vgapage_array, freepage_array, addr, end);
2521 void unset_vram_mapping(unsigned long addr, unsigned long end)
2523 end = addr + VGA_RAM_SIZE;
2524 /* FIXME Flush the shadow page */
2525 unsetup_mapping(xc_handle, domid, toptab, addr, end);
2528 int main(int argc, char **argv)
2530 #ifdef CONFIG_GDBSTUB
2531 int use_gdbstub, gdbstub_port;
2532 #endif
2533 int i, has_cdrom;
2534 int snapshot, linux_boot;
2535 CPUState *env;
2536 const char *initrd_filename;
2537 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
2538 const char *kernel_filename, *kernel_cmdline;
2539 DisplayState *ds = &display_state;
2540 int cyls, heads, secs;
2541 int start_emulation = 1;
2542 uint8_t macaddr[6];
2543 int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
2544 int optind;
2545 const char *r, *optarg;
2546 CharDriverState *monitor_hd;
2547 char monitor_device[128];
2548 char serial_devices[MAX_SERIAL_PORTS][128];
2549 int serial_device_index;
2550 const char *loadvm = NULL;
2551 unsigned long nr_pages, extra_pages, ram_pages, *page_array;
2552 extern void *shared_page;
2553 extern void *shared_vram;
2554 /* change the qemu-dm to daemon, just like bochs dm */
2555 // daemon(0, 0);
2557 #if !defined(CONFIG_SOFTMMU)
2558 /* we never want that malloc() uses mmap() */
2559 mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
2560 #endif
2561 initrd_filename = NULL;
2562 for(i = 0; i < MAX_FD; i++)
2563 fd_filename[i] = NULL;
2564 for(i = 0; i < MAX_DISKS; i++)
2565 hd_filename[i] = NULL;
2566 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
2567 vga_ram_size = VGA_RAM_SIZE;
2568 bios_size = BIOS_SIZE;
2569 pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
2570 #ifdef CONFIG_GDBSTUB
2571 use_gdbstub = 0;
2572 gdbstub_port = DEFAULT_GDBSTUB_PORT;
2573 #endif
2574 snapshot = 0;
2575 nographic = 0;
2576 usevnc = 0;
2577 vncport=0;
2578 vncconnect=NULL;
2579 kernel_filename = NULL;
2580 kernel_cmdline = "";
2581 has_cdrom = 1;
2582 cyls = heads = secs = 0;
2583 pstrcpy(monitor_device, sizeof(monitor_device), "vc");
2585 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
2586 for(i = 1; i < MAX_SERIAL_PORTS; i++)
2587 serial_devices[i][0] = '\0';
2588 serial_device_index = 0;
2590 nb_tun_fds = 0;
2591 net_if_type = -1;
2592 nb_nics = 1;
2593 /* default mac address of the first network interface */
2594 macaddr[0] = 0x52;
2595 macaddr[1] = 0x54;
2596 macaddr[2] = 0x00;
2597 macaddr[3] = 0x12;
2598 macaddr[4] = 0x34;
2599 macaddr[5] = 0x56;
2601 /* init debug */
2602 cpu_set_log(0);
2604 optind = 1;
2605 for(;;) {
2606 if (optind >= argc)
2607 break;
2608 r = argv[optind];
2609 if (r[0] != '-') {
2610 hd_filename[0] = argv[optind++];
2611 } else {
2612 const QEMUOption *popt;
2614 optind++;
2615 popt = qemu_options;
2616 for(;;) {
2617 if (!popt->name) {
2618 fprintf(stderr, "%s: invalid option -- '%s'\n",
2619 argv[0], r);
2620 exit(1);
2622 if (!strcmp(popt->name, r + 1))
2623 break;
2624 popt++;
2626 if (popt->flags & HAS_ARG) {
2627 if (optind >= argc) {
2628 fprintf(stderr, "%s: option '%s' requires an argument\n",
2629 argv[0], r);
2630 exit(1);
2632 optarg = argv[optind++];
2633 } else {
2634 optarg = NULL;
2637 switch(popt->index) {
2638 case QEMU_OPTION_initrd:
2639 initrd_filename = optarg;
2640 break;
2641 case QEMU_OPTION_hda:
2642 hd_filename[0] = optarg;
2643 break;
2644 case QEMU_OPTION_hdb:
2645 hd_filename[1] = optarg;
2646 break;
2647 case QEMU_OPTION_snapshot:
2648 snapshot = 1;
2649 break;
2650 case QEMU_OPTION_hdachs:
2652 const char *p;
2653 p = optarg;
2654 cyls = strtol(p, (char **)&p, 0);
2655 if (*p != ',')
2656 goto chs_fail;
2657 p++;
2658 heads = strtol(p, (char **)&p, 0);
2659 if (*p != ',')
2660 goto chs_fail;
2661 p++;
2662 secs = strtol(p, (char **)&p, 0);
2663 if (*p != '\0') {
2664 chs_fail:
2665 cyls = 0;
2668 break;
2669 case QEMU_OPTION_nographic:
2670 pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
2671 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
2672 nographic = 1;
2673 break;
2674 #ifdef CONFIG_VNC
2675 case QEMU_OPTION_vnc:
2676 usevnc = 1;
2677 break;
2678 case QEMU_OPTION_vncport:
2680 const char *p;
2681 p = optarg;
2682 vncport= strtol(optarg, (char **)&p, 0);
2684 break;
2685 case QEMU_OPTION_vncconnect:
2687 vncconnect=optarg;
2689 break;
2690 #ifdef CONFIG_SDL
2691 case QEMU_OPTION_vnc_and_sdl:
2692 usevnc = 2;
2693 break;
2694 #endif
2695 #endif
2696 case QEMU_OPTION_kernel:
2697 kernel_filename = optarg;
2698 break;
2699 case QEMU_OPTION_append:
2700 kernel_cmdline = optarg;
2701 break;
2702 case QEMU_OPTION_tun_fd:
2704 const char *p;
2705 int fd;
2706 net_if_type = NET_IF_TUN;
2707 if (nb_tun_fds < MAX_NICS) {
2708 fd = strtol(optarg, (char **)&p, 0);
2709 if (*p != '\0') {
2710 fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
2711 exit(1);
2713 tun_fds[nb_tun_fds++] = fd;
2716 break;
2717 case QEMU_OPTION_hdc:
2718 hd_filename[2] = optarg;
2719 has_cdrom = 0;
2720 break;
2721 case QEMU_OPTION_hdd:
2722 hd_filename[3] = optarg;
2723 break;
2724 case QEMU_OPTION_cdrom:
2725 hd_filename[2] = optarg;
2726 has_cdrom = 1;
2727 break;
2728 case QEMU_OPTION_boot:
2729 boot_device = optarg[0];
2730 if (boot_device != 'a' &&
2731 boot_device != 'c' && boot_device != 'd') {
2732 fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
2733 exit(1);
2735 break;
2736 case QEMU_OPTION_fda:
2737 fd_filename[0] = optarg;
2738 break;
2739 case QEMU_OPTION_fdb:
2740 fd_filename[1] = optarg;
2741 break;
2742 case QEMU_OPTION_nics:
2743 nb_nics = atoi(optarg);
2744 if (nb_nics < 0 || nb_nics > MAX_NICS) {
2745 fprintf(stderr, "qemu: invalid number of network interfaces\n");
2746 exit(1);
2748 break;
2749 case QEMU_OPTION_macaddr:
2751 const char *p;
2752 int i;
2753 p = optarg;
2754 for(i = 0; i < 6; i++) {
2755 macaddr[i] = strtol(p, (char **)&p, 16);
2756 if (i == 5) {
2757 if (*p != '\0')
2758 goto macaddr_error;
2759 } else {
2760 if (*p != ':') {
2761 macaddr_error:
2762 fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
2763 exit(1);
2765 p++;
2769 break;
2770 #ifdef CONFIG_SLIRP
2771 case QEMU_OPTION_tftp:
2772 tftp_prefix = optarg;
2773 break;
2774 #ifndef _WIN32
2775 case QEMU_OPTION_smb:
2776 net_slirp_smb(optarg);
2777 break;
2778 #endif
2779 case QEMU_OPTION_user_net:
2780 net_if_type = NET_IF_USER;
2781 break;
2782 case QEMU_OPTION_redir:
2783 net_slirp_redir(optarg);
2784 break;
2785 #endif
2786 case QEMU_OPTION_dummy_net:
2787 net_if_type = NET_IF_DUMMY;
2788 break;
2789 case QEMU_OPTION_enable_audio:
2790 audio_enabled = 1;
2791 break;
2792 case QEMU_OPTION_h:
2793 help();
2794 break;
2795 case QEMU_OPTION_m:
2796 ram_size = atoi(optarg) * 1024 * 1024;
2797 if (ram_size <= 0)
2798 help();
2799 break;
2800 case QEMU_OPTION_d:
2802 domid = atoi(optarg);
2803 printf("domid: %d\n", domid);
2805 break;
2807 case QEMU_OPTION_p:
2809 extern short ioreq_port;
2810 ioreq_port = atoi(optarg);
2811 printf("port: %d\n", ioreq_port);
2813 break;
2814 case QEMU_OPTION_l:
2816 int mask;
2817 mask = cpu_str_to_log_mask(optarg);
2818 printf("mask: %x\n", mask);
2819 cpu_set_log(mask);
2821 break;
2822 case QEMU_OPTION_n:
2823 pstrcpy(network_script, sizeof(network_script), optarg);
2824 break;
2825 #ifdef CONFIG_GDBSTUB
2826 case QEMU_OPTION_s:
2827 use_gdbstub = 1;
2828 break;
2829 #endif
2830 case QEMU_OPTION_L:
2831 bios_dir = optarg;
2832 break;
2833 case QEMU_OPTION_S:
2834 start_emulation = 0;
2835 break;
2836 case QEMU_OPTION_vcpus:
2837 vcpus = atoi(optarg);
2838 fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
2839 case QEMU_OPTION_pci:
2840 pci_enabled = 1;
2841 break;
2842 case QEMU_OPTION_nic_pcnet:
2843 nic_pcnet = 1;
2844 break;
2845 case QEMU_OPTION_isa:
2846 pci_enabled = 0;
2847 break;
2848 case QEMU_OPTION_prep:
2849 prep_enabled = 1;
2850 break;
2851 case QEMU_OPTION_k:
2852 keyboard_layout = optarg;
2853 break;
2854 case QEMU_OPTION_localtime:
2855 rtc_utc = 0;
2856 break;
2857 case QEMU_OPTION_cirrusvga:
2858 cirrus_vga_enabled = 1;
2859 break;
2860 case QEMU_OPTION_vgaacc:
2862 const char *p;
2863 p = optarg;
2864 vga_accelerate = strtol(p, (char **)&p, 0);
2865 if (*p != '\0') {
2866 fprintf(stderr, "qemu: invalid vgaacc option\n");
2867 exit(1);
2869 break;
2871 case QEMU_OPTION_std_vga:
2872 cirrus_vga_enabled = 0;
2873 break;
2874 case QEMU_OPTION_g:
2876 const char *p;
2877 int w, h, depth;
2878 p = optarg;
2879 w = strtol(p, (char **)&p, 10);
2880 if (w <= 0) {
2881 graphic_error:
2882 fprintf(stderr, "qemu: invalid resolution or depth\n");
2883 exit(1);
2885 if (*p != 'x')
2886 goto graphic_error;
2887 p++;
2888 h = strtol(p, (char **)&p, 10);
2889 if (h <= 0)
2890 goto graphic_error;
2891 if (*p == 'x') {
2892 p++;
2893 depth = strtol(p, (char **)&p, 10);
2894 if (depth != 8 && depth != 15 && depth != 16 &&
2895 depth != 24 && depth != 32)
2896 goto graphic_error;
2897 } else if (*p == '\0') {
2898 depth = graphic_depth;
2899 } else {
2900 goto graphic_error;
2903 graphic_width = w;
2904 graphic_height = h;
2905 graphic_depth = depth;
2907 break;
2908 case QEMU_OPTION_monitor:
2909 pstrcpy(monitor_device, sizeof(monitor_device), optarg);
2910 break;
2911 case QEMU_OPTION_serial:
2912 if (serial_device_index >= MAX_SERIAL_PORTS) {
2913 fprintf(stderr, "qemu: too many serial ports\n");
2914 exit(1);
2916 pstrcpy(serial_devices[serial_device_index],
2917 sizeof(serial_devices[0]), optarg);
2918 serial_device_index++;
2919 break;
2920 case QEMU_OPTION_loadvm:
2921 loadvm = optarg;
2922 break;
2923 case QEMU_OPTION_full_screen:
2924 full_screen = 1;
2925 break;
2930 linux_boot = (kernel_filename != NULL);
2932 if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
2933 fd_filename[0] == '\0')
2934 help();
2936 /* boot to cd by default if no hard disk */
2937 if (hd_filename[0] == '\0' && boot_device == 'c') {
2938 if (fd_filename[0] != '\0')
2939 boot_device = 'a';
2940 else
2941 boot_device = 'd';
2944 #if !defined(CONFIG_SOFTMMU)
2945 /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
2947 static uint8_t stdout_buf[4096];
2948 setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
2950 #else
2951 setvbuf(stdout, NULL, _IOLBF, 0);
2952 #endif
2954 /* init host network redirectors */
2955 if (net_if_type == -1) {
2956 net_if_type = NET_IF_TUN;
2957 #if defined(CONFIG_SLIRP)
2958 if (access(network_script, R_OK) < 0) {
2959 net_if_type = NET_IF_USER;
2961 #endif
2964 for(i = 0; i < nb_nics; i++) {
2965 NetDriverState *nd = &nd_table[i];
2966 nd->index = i;
2967 /* init virtual mac address */
2968 nd->macaddr[0] = macaddr[0];
2969 nd->macaddr[1] = macaddr[1];
2970 nd->macaddr[2] = macaddr[2];
2971 nd->macaddr[3] = macaddr[3];
2972 nd->macaddr[4] = macaddr[4];
2973 nd->macaddr[5] = macaddr[5] + i;
2974 switch(net_if_type) {
2975 #if defined(CONFIG_SLIRP)
2976 case NET_IF_USER:
2977 net_slirp_init(nd);
2978 break;
2979 #endif
2980 #if !defined(_WIN32)
2981 case NET_IF_TUN:
2982 if (i < nb_tun_fds) {
2983 net_fd_init(nd, tun_fds[i]);
2984 } else {
2985 if (net_tun_init(nd) < 0)
2986 net_dummy_init(nd);
2988 break;
2989 #endif
2990 case NET_IF_DUMMY:
2991 default:
2992 net_dummy_init(nd);
2993 break;
2997 /* init the memory */
2998 phys_ram_size = ram_size + vga_ram_size + bios_size;
3000 ram_pages = ram_size/PAGE_SIZE;
3001 vgaram_pages = (vga_ram_size -1)/PAGE_SIZE + 1;
3002 free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
3003 extra_pages = vgaram_pages + free_pages;
3005 xc_handle = xc_interface_open();
3007 xc_dominfo_t info;
3008 xc_domain_getinfo(xc_handle, domid, 1, &info);
3010 nr_pages = info.nr_pages + extra_pages;
3012 if ( xc_domain_setmaxmem(xc_handle, domid,
3013 (nr_pages) * PAGE_SIZE/1024 ) != 0)
3015 perror("set maxmem");
3016 exit(-1);
3019 if ( (page_array = (unsigned long *)
3020 malloc(nr_pages * sizeof(unsigned long))) == NULL)
3022 perror("malloc");
3023 exit(-1);
3026 if (xc_domain_memory_increase_reservation(xc_handle, domid,
3027 extra_pages , 0, 0, NULL) != 0) {
3028 perror("increase reservation");
3029 exit(-1);
3032 if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
3034 perror("xc_get_pfn_list");
3035 exit(-1);
3038 if ((phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
3039 PROT_READ|PROT_WRITE,
3040 page_array,
3041 ram_pages - 1)) == 0) {
3042 perror("xc_map_foreign_batch");
3043 exit(-1);
3046 shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
3047 PROT_READ|PROT_WRITE,
3048 page_array[ram_pages - 1]);
3050 vgapage_array = &page_array[nr_pages - vgaram_pages];
3052 if ((shared_vram = xc_map_foreign_batch(xc_handle, domid,
3053 PROT_READ|PROT_WRITE,
3054 vgapage_array,
3055 vgaram_pages)) == 0) {
3056 perror("xc_map_foreign_batch vgaram ");
3057 exit(-1);
3062 memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
3063 toptab = page_array[ram_pages] << PAGE_SHIFT;
3065 vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
3066 PROT_READ|PROT_WRITE,
3067 page_array[ram_pages]);
3069 freepage_array = &page_array[nr_pages - extra_pages];
3072 fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
3073 (page_array[nr_pages - 1]));
3075 /* we always create the cdrom drive, even if no disk is there */
3076 bdrv_init();
3077 if (has_cdrom) {
3078 bs_table[2] = bdrv_new("cdrom");
3079 bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
3082 /* open the virtual block devices */
3083 for(i = 0; i < MAX_DISKS; i++) {
3084 if (hd_filename[i]) {
3085 if (!bs_table[i]) {
3086 char buf[64];
3087 snprintf(buf, sizeof(buf), "hd%c", i + 'a');
3088 bs_table[i] = bdrv_new(buf);
3090 if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
3091 fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
3092 hd_filename[i]);
3093 exit(1);
3095 if (i == 0 && cyls != 0)
3096 bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
3100 /* we always create at least one floppy disk */
3101 fd_table[0] = bdrv_new("fda");
3102 bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
3104 for(i = 0; i < MAX_FD; i++) {
3105 if (fd_filename[i]) {
3106 if (!fd_table[i]) {
3107 char buf[64];
3108 snprintf(buf, sizeof(buf), "fd%c", i + 'a');
3109 fd_table[i] = bdrv_new(buf);
3110 bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
3112 if (fd_filename[i] != '\0') {
3113 if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
3114 fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
3115 fd_filename[i]);
3116 exit(1);
3122 /* init CPU state */
3123 env = cpu_init();
3124 global_env = env;
3125 cpu_single_env = env;
3127 init_ioports();
3128 cpu_calibrate_ticks();
3130 /* terminal init */
3131 if (nographic) {
3132 dumb_display_init(ds);
3133 } else {
3134 if (usevnc) {
3135 #ifdef CONFIG_VNC
3136 vnc_display_init(ds, (usevnc==2), vncport, vncconnect);
3137 #else
3138 perror("qemu not configured with vnc support");
3139 #endif
3140 } else {
3141 #ifdef CONFIG_SDL
3142 sdl_display_init(ds, full_screen);
3143 #else
3144 dumb_display_init(ds);
3145 #endif
3149 vga_console = graphic_console_init(ds);
3151 monitor_hd = qemu_chr_open(monitor_device);
3152 if (!monitor_hd) {
3153 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
3154 exit(1);
3156 monitor_init(monitor_hd, !nographic);
3158 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
3159 if (serial_devices[i][0] != '\0') {
3160 serial_hds[i] = qemu_chr_open(serial_devices[i]);
3161 if (!serial_hds[i]) {
3162 fprintf(stderr, "qemu: could not open serial device '%s'\n",
3163 serial_devices[i]);
3164 exit(1);
3166 if (!strcmp(serial_devices[i], "vc"))
3167 qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
3171 /* setup cpu signal handlers for MMU / self modifying code handling */
3172 #if !defined(CONFIG_SOFTMMU)
3174 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
3176 stack_t stk;
3177 signal_stack = memalign(16, SIGNAL_STACK_SIZE);
3178 stk.ss_sp = signal_stack;
3179 stk.ss_size = SIGNAL_STACK_SIZE;
3180 stk.ss_flags = 0;
3182 if (sigaltstack(&stk, NULL) < 0) {
3183 perror("sigaltstack");
3184 exit(1);
3187 #endif
3189 struct sigaction act;
3191 sigfillset(&act.sa_mask);
3192 act.sa_flags = SA_SIGINFO;
3193 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
3194 act.sa_flags |= SA_ONSTACK;
3195 #endif
3196 act.sa_sigaction = host_segv_handler;
3197 sigaction(SIGSEGV, &act, NULL);
3198 sigaction(SIGBUS, &act, NULL);
3199 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
3200 sigaction(SIGFPE, &act, NULL);
3201 #endif
3203 #endif
3205 #ifndef _WIN32
3207 struct sigaction act;
3208 sigfillset(&act.sa_mask);
3209 act.sa_flags = 0;
3210 act.sa_handler = SIG_IGN;
3211 sigaction(SIGPIPE, &act, NULL);
3213 #endif
3214 init_timers();
3216 #if defined(TARGET_I386)
3217 pc_init(ram_size, vga_ram_size, boot_device,
3218 ds, fd_filename, snapshot,
3219 kernel_filename, kernel_cmdline, initrd_filename);
3220 #elif defined(TARGET_PPC)
3221 ppc_init(ram_size, vga_ram_size, boot_device,
3222 ds, fd_filename, snapshot,
3223 kernel_filename, kernel_cmdline, initrd_filename);
3224 #elif defined(TARGET_SPARC)
3225 sun4m_init(ram_size, vga_ram_size, boot_device,
3226 ds, fd_filename, snapshot,
3227 kernel_filename, kernel_cmdline, initrd_filename);
3228 #endif
3230 gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
3231 qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
3233 polling_timer = qemu_new_timer(rt_clock, polling_handler, NULL);
3234 qemu_mod_timer(polling_timer, qemu_get_clock(rt_clock));
3236 #ifdef CONFIG_GDBSTUB
3237 if (use_gdbstub) {
3238 if (gdbserver_start(gdbstub_port) < 0) {
3239 fprintf(stderr, "Could not open gdbserver socket on port %d\n",
3240 gdbstub_port);
3241 exit(1);
3242 } else {
3243 printf("Waiting gdb connection on port %d\n", gdbstub_port);
3245 } else
3246 #endif
3247 if (loadvm)
3248 qemu_loadvm(loadvm);
3251 /* XXX: simplify init */
3252 if (start_emulation) {
3253 vm_start();
3256 main_loop();
3257 quit_timers();
3258 return 0;