blob: 31f3ad2500cc458b67a56df7b119b7bd9c4be1f4 [file] [log] [blame]
bellard0824d6f2003-06-24 13:42:40 +00001/*
bellard80cabfa2004-03-14 12:20:30 +00002 * QEMU System Emulator
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard68d0f702008-01-06 17:21:48 +00004 * Copyright (c) 2003-2008 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard1df912c2003-06-25 16:20:35 +00006 * 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.
bellard0824d6f2003-06-24 13:42:40 +000023 */
bellard0824d6f2003-06-24 13:42:40 +000024#include <unistd.h>
bellard0824d6f2003-06-24 13:42:40 +000025#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
bellard0824d6f2003-06-24 13:42:40 +000028#include <errno.h>
bellard67b915a2004-03-31 23:37:16 +000029#include <sys/time.h>
bellardc88676f2006-08-06 13:36:11 +000030#include <zlib.h>
bellard67b915a2004-03-31 23:37:16 +000031
Juan Quintela71e72a12009-07-27 16:12:56 +020032/* Needed early for CONFIG_BSD etc. */
blueswir1d40cdb12009-03-07 16:52:02 +000033#include "config-host.h"
34
bellard67b915a2004-03-31 23:37:16 +000035#ifndef _WIN32
Paul Brook5cea8592009-05-30 00:52:44 +010036#include <libgen.h>
aliguori08585322009-02-27 22:09:45 +000037#include <pwd.h>
bellard67b915a2004-03-31 23:37:16 +000038#include <sys/times.h>
bellardf1510b22003-06-25 00:07:40 +000039#include <sys/wait.h>
bellard67b915a2004-03-31 23:37:16 +000040#include <termios.h>
bellard67b915a2004-03-31 23:37:16 +000041#include <sys/mman.h>
bellardf1510b22003-06-25 00:07:40 +000042#include <sys/ioctl.h>
blueswir124646c72008-11-07 16:55:48 +000043#include <sys/resource.h>
bellardf1510b22003-06-25 00:07:40 +000044#include <sys/socket.h>
bellardc94c8d62004-09-13 21:37:34 +000045#include <netinet/in.h>
blueswir124646c72008-11-07 16:55:48 +000046#include <net/if.h>
47#if defined(__NetBSD__)
48#include <net/if_tap.h>
49#endif
50#ifdef __linux__
51#include <linux/if_tun.h>
52#endif
53#include <arpa/inet.h>
bellard9d728e82004-09-05 23:09:03 +000054#include <dirent.h>
bellard7c9d8e02005-11-15 22:16:05 +000055#include <netdb.h>
thscb4b9762007-09-13 12:39:35 +000056#include <sys/select.h>
Juan Quintela71e72a12009-07-27 16:12:56 +020057#ifdef CONFIG_BSD
bellard7d3505c2004-05-12 19:32:15 +000058#include <sys/stat.h>
blueswir1c5e97232009-03-07 20:06:23 +000059#if defined(__FreeBSD__) || defined(__DragonFly__)
bellard7d3505c2004-05-12 19:32:15 +000060#include <libutil.h>
blueswir124646c72008-11-07 16:55:48 +000061#else
62#include <util.h>
blueswir1128ab2f2008-08-15 18:33:42 +000063#endif
ths5c40d2b2007-06-23 16:03:36 +000064#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
65#include <freebsd/stdlib.h>
bellard7d3505c2004-05-12 19:32:15 +000066#else
blueswir1223f0d72008-09-30 18:12:18 +000067#ifdef __linux__
bellard7d3505c2004-05-12 19:32:15 +000068#include <pty.h>
69#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000070#include <linux/rtc.h>
Andi Kleen18894652009-07-02 09:34:17 +020071#include <sys/prctl.h>
thsbd494f42007-09-16 20:03:23 +000072
73/* For the benefit of older linux systems which don't supply it,
74 we use a local copy of hpet.h. */
75/* #include <linux/hpet.h> */
76#include "hpet.h"
77
bellarde57a8c02005-11-10 23:58:52 +000078#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000079#include <linux/parport.h>
blueswir1223f0d72008-09-30 18:12:18 +000080#endif
81#ifdef __sun__
thsd5d10bc2007-02-17 22:54:49 +000082#include <sys/stat.h>
83#include <sys/ethernet.h>
84#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000085#include <netinet/arp.h>
86#include <netinet/in.h>
87#include <netinet/in_systm.h>
88#include <netinet/ip.h>
89#include <netinet/ip_icmp.h> // must come after ip.h
90#include <netinet/udp.h>
91#include <netinet/tcp.h>
92#include <net/if.h>
93#include <syslog.h>
94#include <stropts.h>
Blue Swirl8d32cf02009-10-02 19:32:12 +000095/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
96 discussion about Solaris header problems */
97extern int madvise(caddr_t, size_t, int);
bellard67b915a2004-03-31 23:37:16 +000098#endif
bellard7d3505c2004-05-12 19:32:15 +000099#endif
bellardec530c82006-04-25 22:36:06 +0000100#endif
bellard67b915a2004-03-31 23:37:16 +0000101
blueswir19892fbf2008-08-24 10:34:20 +0000102#if defined(__OpenBSD__)
103#include <util.h>
104#endif
105
ths8a16d272008-07-19 09:56:24 +0000106#if defined(CONFIG_VDE)
107#include <libvdeplug.h>
108#endif
109
bellard67b915a2004-03-31 23:37:16 +0000110#ifdef _WIN32
aliguori49dc7682009-03-08 16:26:59 +0000111#include <windows.h>
ths4fddf622007-12-17 04:42:29 +0000112#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000113#endif
114
bellard73332e52004-04-04 20:22:28 +0000115#ifdef CONFIG_SDL
Stefan Weil59a36a22009-06-18 20:11:03 +0200116#if defined(__APPLE__) || defined(main)
Stefan Weil66936652009-06-13 13:19:11 +0200117#include <SDL.h>
malc880fec52009-02-15 20:18:41 +0000118int qemu_main(int argc, char **argv, char **envp);
119int main(int argc, char **argv)
120{
Stefan Weil59a36a22009-06-18 20:11:03 +0200121 return qemu_main(argc, argv, NULL);
malc880fec52009-02-15 20:18:41 +0000122}
123#undef main
124#define main qemu_main
bellard96bcd4f2004-07-10 16:26:15 +0000125#endif
bellard73332e52004-04-04 20:22:28 +0000126#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000127
bellard5b0753e2005-03-01 21:37:28 +0000128#ifdef CONFIG_COCOA
129#undef main
130#define main qemu_main
131#endif /* CONFIG_COCOA */
132
blueswir1511d2b12009-03-07 15:32:56 +0000133#include "hw/hw.h"
134#include "hw/boards.h"
135#include "hw/usb.h"
136#include "hw/pcmcia.h"
137#include "hw/pc.h"
138#include "hw/audiodev.h"
139#include "hw/isa.h"
140#include "hw/baum.h"
141#include "hw/bt.h"
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +0100142#include "hw/watchdog.h"
aliguorib6f6e3d2009-04-17 18:59:56 +0000143#include "hw/smbios.h"
aliguorie37630c2009-04-22 15:19:10 +0000144#include "hw/xen.h"
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +0200145#include "hw/qdev.h"
aurel325ef4efa2009-03-10 21:43:35 +0000146#include "bt-host.h"
blueswir1511d2b12009-03-07 15:32:56 +0000147#include "net.h"
148#include "monitor.h"
149#include "console.h"
150#include "sysemu.h"
151#include "gdbstub.h"
152#include "qemu-timer.h"
153#include "qemu-char.h"
154#include "cache-utils.h"
155#include "block.h"
blueswir1a718ace2009-03-28 08:24:44 +0000156#include "dma.h"
blueswir1511d2b12009-03-07 15:32:56 +0000157#include "audio/audio.h"
158#include "migration.h"
159#include "kvm.h"
160#include "balloon.h"
Kevin Wolfd3f24362009-05-18 16:42:09 +0200161#include "qemu-option.h"
Gerd Hoffmann7282a032009-07-31 12:25:35 +0200162#include "qemu-config.h"
blueswir1511d2b12009-03-07 15:32:56 +0000163
bellard0824d6f2003-06-24 13:42:40 +0000164#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000165
bellard8a7ddc32004-03-31 19:00:16 +0000166#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000167
blueswir1511d2b12009-03-07 15:32:56 +0000168#include "qemu_socket.h"
169
Jan Kiszkad918f232009-06-24 14:42:30 +0200170#include "slirp/libslirp.h"
blueswir1511d2b12009-03-07 15:32:56 +0000171
Blue Swirl72cf2d42009-09-12 07:36:22 +0000172#include "qemu-queue.h"
173
blueswir19dc63a12008-10-04 07:25:46 +0000174//#define DEBUG_NET
175//#define DEBUG_SLIRP
bellard330d0412003-07-26 18:11:40 +0000176
bellard1bfe8562004-07-08 21:17:50 +0000177#define DEFAULT_RAM_SIZE 128
bellard313aa562003-08-10 21:52:11 +0000178
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +0200179/* Maximum number of monitor devices */
180#define MAX_MONITOR_DEVICES 10
181
Paul Brook5cea8592009-05-30 00:52:44 +0100182static const char *data_dir;
j_mayer1192dad2007-10-05 13:08:35 +0000183const char *bios_name = NULL;
thse4bcb142007-12-02 04:51:10 +0000184/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000185 to store the VM snapshots */
Blue Swirl72cf2d42009-09-12 07:36:22 +0000186struct drivelist drives = QTAILQ_HEAD_INITIALIZER(drives);
187struct driveoptlist driveopts = QTAILQ_HEAD_INITIALIZER(driveopts);
malccb5a7aa2008-09-28 00:42:12 +0000188enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
aliguori3023f332009-01-16 19:04:14 +0000189static DisplayState *display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -0500190DisplayType display_type = DT_DEFAULT;
bellard3d11d0e2004-12-12 16:56:30 +0000191const char* keyboard_layout = NULL;
Anthony Liguoric227f092009-10-01 16:12:16 -0500192ram_addr_t ram_size;
bellardc4b1fcc2004-03-14 21:44:30 +0000193int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000194NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000195int vm_running;
Paolo Bonzinid399f672009-07-27 23:17:51 +0200196int autostart;
balrogf6503052008-02-17 11:42:19 +0000197static int rtc_utc = 1;
198static int rtc_date_offset = -1; /* -1 means no change */
Zachary Amsden86176752009-07-30 00:15:02 -1000199int vga_interface_type = VGA_CIRRUS;
bellardd8272202005-04-06 20:32:23 +0000200#ifdef TARGET_SPARC
201int graphic_width = 1024;
202int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000203int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000204#else
bellard1bfe8562004-07-08 21:17:50 +0000205int graphic_width = 800;
206int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000207int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000208#endif
blueswir1dbed7e42008-10-01 19:38:09 +0000209static int full_screen = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000210#ifdef CONFIG_SDL
blueswir1dbed7e42008-10-01 19:38:09 +0000211static int no_frame = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000212#endif
ths667acca2006-12-11 02:08:05 +0000213int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000214CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000215CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
aliguori9ede2fd2009-01-15 20:05:25 +0000216CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
bellarda09db212005-04-30 16:10:35 +0000217#ifdef TARGET_I386
218int win2k_install_hack = 0;
aliguori73822ec2009-01-15 20:11:34 +0000219int rtc_td_hack = 0;
bellarda09db212005-04-30 16:10:35 +0000220#endif
bellardbb36d472005-11-05 14:22:28 +0000221int usb_enabled = 0;
aurel321b530a62009-04-05 20:08:59 +0000222int singlestep = 0;
bellard6a00d602005-11-21 23:25:50 +0000223int smp_cpus = 1;
Jes Sorensen6be68d72009-07-23 17:03:42 +0200224int max_cpus = 0;
Andre Przywaradc6b1c02009-08-19 15:42:40 +0200225int smp_cores = 1;
226int smp_threads = 1;
ths73fc9742006-12-22 02:09:07 +0000227const char *vnc_display;
bellard6515b202006-05-03 22:02:44 +0000228int acpi_enabled = 1;
aliguori16b29ae2008-12-17 23:28:44 +0000229int no_hpet = 0;
bellard52ca8d62006-06-14 16:03:05 +0000230int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000231int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000232int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000233int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000234int graphic_rotate = 0;
Jes Sorensen6b35e7b2009-08-06 16:25:50 +0200235uint8_t irq0override = 1;
blueswir1b9e82a52009-04-05 18:03:31 +0000236#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +0000237int daemonize = 0;
blueswir1b9e82a52009-04-05 18:03:31 +0000238#endif
Markus Armbruster09aaa162009-08-21 10:31:34 +0200239const char *watchdog;
ths9ae02552007-01-05 17:39:04 +0000240const char *option_rom[MAX_OPTION_ROMS];
241int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000242int semihosting_enabled = 0;
balrog2b8f2d42007-07-27 22:08:46 +0000243#ifdef TARGET_ARM
244int old_param = 0;
245#endif
thsc35734b2007-03-19 15:17:08 +0000246const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000247int alt_grab = 0;
blueswir195efd112008-12-24 20:26:14 +0000248#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +0000249unsigned int nb_prom_envs = 0;
250const char *prom_envs[MAX_PROM_ENVS];
251#endif
Jan Kiszka95387492009-07-02 00:19:02 +0200252int boot_menu;
bellard0824d6f2003-06-24 13:42:40 +0000253
aliguori268a3622009-04-21 22:30:27 +0000254int nb_numa_nodes;
255uint64_t node_mem[MAX_NODES];
256uint64_t node_cpumask[MAX_NODES];
257
balrogee5605e2007-12-03 03:01:40 +0000258static CPUState *cur_cpu;
259static CPUState *next_cpu;
aliguori43b96852009-04-24 18:03:33 +0000260static int timer_alarm_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000261/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000262static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000263/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000264#define MAX_ICOUNT_SHIFT 10
265/* Compensate for varying guest execution speed. */
266static int64_t qemu_icount_bias;
blueswir1dbed7e42008-10-01 19:38:09 +0000267static QEMUTimer *icount_rt_timer;
268static QEMUTimer *icount_vm_timer;
blueswir19043b622009-01-21 19:28:13 +0000269static QEMUTimer *nographic_timer;
balrogee5605e2007-12-03 03:01:40 +0000270
blueswir18fcb1b92008-09-18 18:29:08 +0000271uint8_t qemu_uuid[16];
272
Jan Kiszka76e30d02009-07-02 00:19:02 +0200273static QEMUBootSetHandler *boot_set_handler;
274static void *boot_set_opaque;
275
bellard0824d6f2003-06-24 13:42:40 +0000276/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000277/* x86 ISA bus support */
278
Anthony Liguoric227f092009-10-01 16:12:16 -0500279target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000280PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000281
bellard0824d6f2003-06-24 13:42:40 +0000282/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000283void hw_error(const char *fmt, ...)
284{
285 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000286 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000287
288 va_start(ap, fmt);
289 fprintf(stderr, "qemu: hardware error: ");
290 vfprintf(stderr, fmt, ap);
291 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000292 for(env = first_cpu; env != NULL; env = env->next_cpu) {
293 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000294#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000295 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000296#else
bellard6a00d602005-11-21 23:25:50 +0000297 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000298#endif
bellard6a00d602005-11-21 23:25:50 +0000299 }
bellard0824d6f2003-06-24 13:42:40 +0000300 va_end(ap);
301 abort();
302}
Andi Kleen18894652009-07-02 09:34:17 +0200303
304static void set_proc_name(const char *s)
305{
Nathan Froyd6ca8d0f2009-08-03 07:32:12 -0700306#if defined(__linux__) && defined(PR_SET_NAME)
Andi Kleen18894652009-07-02 09:34:17 +0200307 char name[16];
308 if (!s)
309 return;
310 name[sizeof(name) - 1] = 0;
311 strncpy(name, s, sizeof(name));
312 /* Could rewrite argv[0] too, but that's a bit more complicated.
313 This simple way is enough for `top'. */
314 prctl(PR_SET_NAME, name);
315#endif
316}
aliguoridf751fa2008-12-04 20:19:35 +0000317
318/***************/
319/* ballooning */
320
321static QEMUBalloonEvent *qemu_balloon_event;
322void *qemu_balloon_event_opaque;
323
324void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
325{
326 qemu_balloon_event = func;
327 qemu_balloon_event_opaque = opaque;
328}
329
Anthony Liguoric227f092009-10-01 16:12:16 -0500330void qemu_balloon(ram_addr_t target)
aliguoridf751fa2008-12-04 20:19:35 +0000331{
332 if (qemu_balloon_event)
333 qemu_balloon_event(qemu_balloon_event_opaque, target);
334}
335
Anthony Liguoric227f092009-10-01 16:12:16 -0500336ram_addr_t qemu_balloon_status(void)
aliguoridf751fa2008-12-04 20:19:35 +0000337{
338 if (qemu_balloon_event)
339 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
340 return 0;
341}
bellard0824d6f2003-06-24 13:42:40 +0000342
bellard8a7ddc32004-03-31 19:00:16 +0000343/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000344/* keyboard/mouse */
345
346static QEMUPutKBDEvent *qemu_put_kbd_event;
347static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000348static QEMUPutMouseEntry *qemu_put_mouse_event_head;
349static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000350
351void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
352{
353 qemu_put_kbd_event_opaque = opaque;
354 qemu_put_kbd_event = func;
355}
356
ths455204e2007-01-05 16:42:13 +0000357QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
358 void *opaque, int absolute,
359 const char *name)
bellard63066f42004-06-03 18:45:02 +0000360{
ths455204e2007-01-05 16:42:13 +0000361 QEMUPutMouseEntry *s, *cursor;
362
363 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
ths455204e2007-01-05 16:42:13 +0000364
365 s->qemu_put_mouse_event = func;
366 s->qemu_put_mouse_event_opaque = opaque;
367 s->qemu_put_mouse_event_absolute = absolute;
368 s->qemu_put_mouse_event_name = qemu_strdup(name);
369 s->next = NULL;
370
371 if (!qemu_put_mouse_event_head) {
372 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
373 return s;
374 }
375
376 cursor = qemu_put_mouse_event_head;
377 while (cursor->next != NULL)
378 cursor = cursor->next;
379
380 cursor->next = s;
381 qemu_put_mouse_event_current = s;
382
383 return s;
384}
385
386void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
387{
388 QEMUPutMouseEntry *prev = NULL, *cursor;
389
390 if (!qemu_put_mouse_event_head || entry == NULL)
391 return;
392
393 cursor = qemu_put_mouse_event_head;
394 while (cursor != NULL && cursor != entry) {
395 prev = cursor;
396 cursor = cursor->next;
397 }
398
399 if (cursor == NULL) // does not exist or list empty
400 return;
401 else if (prev == NULL) { // entry is head
402 qemu_put_mouse_event_head = cursor->next;
403 if (qemu_put_mouse_event_current == entry)
404 qemu_put_mouse_event_current = cursor->next;
405 qemu_free(entry->qemu_put_mouse_event_name);
406 qemu_free(entry);
407 return;
408 }
409
410 prev->next = entry->next;
411
412 if (qemu_put_mouse_event_current == entry)
413 qemu_put_mouse_event_current = prev;
414
415 qemu_free(entry->qemu_put_mouse_event_name);
416 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000417}
418
419void kbd_put_keycode(int keycode)
420{
421 if (qemu_put_kbd_event) {
422 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
423 }
424}
425
426void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
427{
ths455204e2007-01-05 16:42:13 +0000428 QEMUPutMouseEvent *mouse_event;
429 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000430 int width;
ths455204e2007-01-05 16:42:13 +0000431
432 if (!qemu_put_mouse_event_current) {
433 return;
434 }
435
436 mouse_event =
437 qemu_put_mouse_event_current->qemu_put_mouse_event;
438 mouse_event_opaque =
439 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
440
441 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000442 if (graphic_rotate) {
443 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
444 width = 0x7fff;
445 else
aurel32b94ed572008-03-10 19:34:27 +0000446 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000447 mouse_event(mouse_event_opaque,
448 width - dy, dx, dz, buttons_state);
449 } else
450 mouse_event(mouse_event_opaque,
451 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000452 }
453}
454
bellard09b26c52006-04-12 21:09:08 +0000455int kbd_mouse_is_absolute(void)
456{
ths455204e2007-01-05 16:42:13 +0000457 if (!qemu_put_mouse_event_current)
458 return 0;
459
460 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
461}
462
aliguori376253e2009-03-05 23:01:23 +0000463void do_info_mice(Monitor *mon)
ths455204e2007-01-05 16:42:13 +0000464{
465 QEMUPutMouseEntry *cursor;
466 int index = 0;
467
468 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000469 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000470 return;
471 }
472
aliguori376253e2009-03-05 23:01:23 +0000473 monitor_printf(mon, "Mouse devices available:\n");
ths455204e2007-01-05 16:42:13 +0000474 cursor = qemu_put_mouse_event_head;
475 while (cursor != NULL) {
aliguori376253e2009-03-05 23:01:23 +0000476 monitor_printf(mon, "%c Mouse #%d: %s\n",
477 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
478 index, cursor->qemu_put_mouse_event_name);
ths455204e2007-01-05 16:42:13 +0000479 index++;
480 cursor = cursor->next;
481 }
482}
483
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300484void do_mouse_set(Monitor *mon, const QDict *qdict)
ths455204e2007-01-05 16:42:13 +0000485{
486 QEMUPutMouseEntry *cursor;
487 int i = 0;
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300488 int index = qdict_get_int(qdict, "index");
ths455204e2007-01-05 16:42:13 +0000489
490 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000491 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000492 return;
493 }
494
495 cursor = qemu_put_mouse_event_head;
496 while (cursor != NULL && index != i) {
497 i++;
498 cursor = cursor->next;
499 }
500
501 if (cursor != NULL)
502 qemu_put_mouse_event_current = cursor;
503 else
aliguori376253e2009-03-05 23:01:23 +0000504 monitor_printf(mon, "Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000505}
506
bellard87858c82003-06-27 12:01:39 +0000507/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000508uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000509{
510 union {
511 uint64_t ll;
512 struct {
Juan Quintelae2542fe2009-07-27 16:13:06 +0200513#ifdef HOST_WORDS_BIGENDIAN
bellard87858c82003-06-27 12:01:39 +0000514 uint32_t high, low;
515#else
516 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000517#endif
bellard87858c82003-06-27 12:01:39 +0000518 } l;
519 } u, res;
520 uint64_t rl, rh;
521
522 u.ll = a;
523 rl = (uint64_t)u.l.low * (uint64_t)b;
524 rh = (uint64_t)u.l.high * (uint64_t)b;
525 rh += (rl >> 32);
526 res.l.high = rh / c;
527 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
528 return res.ll;
529}
530
bellard1dce7c32006-07-13 23:20:22 +0000531/***********************************************************/
532/* real time host monotonic timer */
533
Jan Kiszka21d5d122009-09-15 13:36:04 +0200534static int64_t get_clock_realtime(void)
535{
536 struct timeval tv;
537
538 gettimeofday(&tv, NULL);
539 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
540}
541
bellard1dce7c32006-07-13 23:20:22 +0000542#ifdef WIN32
543
544static int64_t clock_freq;
545
546static void init_get_clock(void)
547{
bellarda8e5ac32006-07-14 09:36:13 +0000548 LARGE_INTEGER freq;
549 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000550 ret = QueryPerformanceFrequency(&freq);
551 if (ret == 0) {
552 fprintf(stderr, "Could not calibrate ticks\n");
553 exit(1);
554 }
555 clock_freq = freq.QuadPart;
556}
557
558static int64_t get_clock(void)
559{
560 LARGE_INTEGER ti;
561 QueryPerformanceCounter(&ti);
Anthony Liguori274dfed2009-09-11 10:28:26 -0500562 return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
bellard1dce7c32006-07-13 23:20:22 +0000563}
564
565#else
566
567static int use_rt_clock;
568
569static void init_get_clock(void)
570{
571 use_rt_clock = 0;
blueswir1c5e97232009-03-07 20:06:23 +0000572#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
573 || defined(__DragonFly__)
bellard1dce7c32006-07-13 23:20:22 +0000574 {
575 struct timespec ts;
576 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
577 use_rt_clock = 1;
578 }
579 }
580#endif
581}
582
583static int64_t get_clock(void)
584{
blueswir1c5e97232009-03-07 20:06:23 +0000585#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
586 || defined(__DragonFly__)
bellard1dce7c32006-07-13 23:20:22 +0000587 if (use_rt_clock) {
588 struct timespec ts;
589 clock_gettime(CLOCK_MONOTONIC, &ts);
590 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000591 } else
bellard1dce7c32006-07-13 23:20:22 +0000592#endif
593 {
594 /* XXX: using gettimeofday leads to problems if the date
595 changes, so it should be avoided. */
Jan Kiszka21d5d122009-09-15 13:36:04 +0200596 return get_clock_realtime();
bellard1dce7c32006-07-13 23:20:22 +0000597 }
598}
bellard1dce7c32006-07-13 23:20:22 +0000599#endif
600
pbrook2e70f6e2008-06-29 01:03:05 +0000601/* Return the virtual CPU time, based on the instruction counter. */
602static int64_t cpu_get_icount(void)
603{
604 int64_t icount;
605 CPUState *env = cpu_single_env;;
606 icount = qemu_icount;
607 if (env) {
608 if (!can_do_io(env))
609 fprintf(stderr, "Bad clock read\n");
610 icount -= (env->icount_decr.u16.low + env->icount_extra);
611 }
612 return qemu_icount_bias + (icount << icount_time_shift);
613}
614
bellard1dce7c32006-07-13 23:20:22 +0000615/***********************************************************/
616/* guest cycle counter */
617
Juan Quintela6f68e332009-09-10 03:04:27 +0200618typedef struct TimersState {
619 int64_t cpu_ticks_prev;
620 int64_t cpu_ticks_offset;
621 int64_t cpu_clock_offset;
622 int32_t cpu_ticks_enabled;
Anthony Liguori274dfed2009-09-11 10:28:26 -0500623 int64_t dummy;
Juan Quintela6f68e332009-09-10 03:04:27 +0200624} TimersState;
625
626TimersState timers_state;
bellard1dce7c32006-07-13 23:20:22 +0000627
628/* return the host CPU cycle counter and handle stop/restart */
629int64_t cpu_get_ticks(void)
630{
pbrook2e70f6e2008-06-29 01:03:05 +0000631 if (use_icount) {
632 return cpu_get_icount();
633 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200634 if (!timers_state.cpu_ticks_enabled) {
635 return timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000636 } else {
637 int64_t ticks;
638 ticks = cpu_get_real_ticks();
Juan Quintela6f68e332009-09-10 03:04:27 +0200639 if (timers_state.cpu_ticks_prev > ticks) {
bellard1dce7c32006-07-13 23:20:22 +0000640 /* Note: non increasing ticks may happen if the host uses
641 software suspend */
Juan Quintela6f68e332009-09-10 03:04:27 +0200642 timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
bellard1dce7c32006-07-13 23:20:22 +0000643 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200644 timers_state.cpu_ticks_prev = ticks;
645 return ticks + timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000646 }
647}
648
649/* return the host CPU monotonic timer and handle stop/restart */
650static int64_t cpu_get_clock(void)
651{
652 int64_t ti;
Juan Quintela6f68e332009-09-10 03:04:27 +0200653 if (!timers_state.cpu_ticks_enabled) {
654 return timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000655 } else {
656 ti = get_clock();
Juan Quintela6f68e332009-09-10 03:04:27 +0200657 return ti + timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000658 }
659}
660
661/* enable cpu_get_ticks() */
662void cpu_enable_ticks(void)
663{
Juan Quintela6f68e332009-09-10 03:04:27 +0200664 if (!timers_state.cpu_ticks_enabled) {
665 timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
666 timers_state.cpu_clock_offset -= get_clock();
667 timers_state.cpu_ticks_enabled = 1;
bellard1dce7c32006-07-13 23:20:22 +0000668 }
669}
670
671/* disable cpu_get_ticks() : the clock is stopped. You must not call
672 cpu_get_ticks() after that. */
673void cpu_disable_ticks(void)
674{
Juan Quintela6f68e332009-09-10 03:04:27 +0200675 if (timers_state.cpu_ticks_enabled) {
676 timers_state.cpu_ticks_offset = cpu_get_ticks();
677 timers_state.cpu_clock_offset = cpu_get_clock();
678 timers_state.cpu_ticks_enabled = 0;
bellard1dce7c32006-07-13 23:20:22 +0000679 }
680}
681
682/***********************************************************/
683/* timers */
ths5fafdf22007-09-16 21:08:06 +0000684
Jan Kiszka0fdddf82009-09-15 13:36:04 +0200685#define QEMU_CLOCK_REALTIME 0
686#define QEMU_CLOCK_VIRTUAL 1
Jan Kiszka21d5d122009-09-15 13:36:04 +0200687#define QEMU_CLOCK_HOST 2
bellard8a7ddc32004-03-31 19:00:16 +0000688
689struct QEMUClock {
690 int type;
691 /* XXX: add frequency */
692};
693
694struct QEMUTimer {
695 QEMUClock *clock;
696 int64_t expire_time;
697 QEMUTimerCB *cb;
698 void *opaque;
699 struct QEMUTimer *next;
700};
701
thsc8994012007-08-19 21:56:03 +0000702struct qemu_alarm_timer {
703 char const *name;
thsefe75412007-08-24 01:36:32 +0000704 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000705
706 int (*start)(struct qemu_alarm_timer *t);
707 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000708 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000709 void *priv;
710};
711
thsefe75412007-08-24 01:36:32 +0000712#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000713#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000714
715static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
716{
Jean-Christophe Duboise3323402009-05-17 18:38:39 +0200717 return t && (t->flags & ALARM_FLAG_DYNTICKS);
thsefe75412007-08-24 01:36:32 +0000718}
719
720static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
721{
722 if (!alarm_has_dynticks(t))
723 return;
724
725 t->rearm(t);
726}
727
728/* TODO: MIN_TIMER_REARM_US should be optimized */
729#define MIN_TIMER_REARM_US 250
730
thsc8994012007-08-19 21:56:03 +0000731static struct qemu_alarm_timer *alarm_timer;
732
733#ifdef _WIN32
734
735struct qemu_alarm_win32 {
736 MMRESULT timerId;
thsc8994012007-08-19 21:56:03 +0000737 unsigned int period;
Blue Swirlef28c4b2009-04-25 12:56:37 +0000738} alarm_win32_data = {0, -1};
thsc8994012007-08-19 21:56:03 +0000739
740static int win32_start_timer(struct qemu_alarm_timer *t);
741static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000742static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000743
744#else
745
746static int unix_start_timer(struct qemu_alarm_timer *t);
747static void unix_stop_timer(struct qemu_alarm_timer *t);
748
ths231c6582007-08-26 17:29:15 +0000749#ifdef __linux__
750
thsefe75412007-08-24 01:36:32 +0000751static int dynticks_start_timer(struct qemu_alarm_timer *t);
752static void dynticks_stop_timer(struct qemu_alarm_timer *t);
753static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
754
thsc40ec5a2007-08-19 22:09:40 +0000755static int hpet_start_timer(struct qemu_alarm_timer *t);
756static void hpet_stop_timer(struct qemu_alarm_timer *t);
757
thsc8994012007-08-19 21:56:03 +0000758static int rtc_start_timer(struct qemu_alarm_timer *t);
759static void rtc_stop_timer(struct qemu_alarm_timer *t);
760
thsefe75412007-08-24 01:36:32 +0000761#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000762
763#endif /* _WIN32 */
764
pbrook2e70f6e2008-06-29 01:03:05 +0000765/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000766 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000767 When the guest is idle real and virtual time will be aligned in
768 the IO wait loop. */
Anthony Liguori274dfed2009-09-11 10:28:26 -0500769#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
pbrook2e70f6e2008-06-29 01:03:05 +0000770
771static void icount_adjust(void)
772{
773 int64_t cur_time;
774 int64_t cur_icount;
775 int64_t delta;
776 static int64_t last_delta;
777 /* If the VM is not running, then do nothing. */
778 if (!vm_running)
779 return;
780
781 cur_time = cpu_get_clock();
782 cur_icount = qemu_get_clock(vm_clock);
783 delta = cur_icount - cur_time;
784 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
785 if (delta > 0
786 && last_delta + ICOUNT_WOBBLE < delta * 2
787 && icount_time_shift > 0) {
788 /* The guest is getting too far ahead. Slow time down. */
789 icount_time_shift--;
790 }
791 if (delta < 0
792 && last_delta - ICOUNT_WOBBLE > delta * 2
793 && icount_time_shift < MAX_ICOUNT_SHIFT) {
794 /* The guest is getting too far behind. Speed time up. */
795 icount_time_shift++;
796 }
797 last_delta = delta;
798 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
799}
800
801static void icount_adjust_rt(void * opaque)
802{
803 qemu_mod_timer(icount_rt_timer,
804 qemu_get_clock(rt_clock) + 1000);
805 icount_adjust();
806}
807
808static void icount_adjust_vm(void * opaque)
809{
810 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500811 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000812 icount_adjust();
813}
814
815static void init_icount_adjust(void)
816{
817 /* Have both realtime and virtual time triggers for speed adjustment.
818 The realtime trigger catches emulated time passing too slowly,
819 the virtual time trigger catches emulated time passing too fast.
820 Realtime triggers occur even when idle, so use them less frequently
821 than VM triggers. */
822 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
823 qemu_mod_timer(icount_rt_timer,
824 qemu_get_clock(rt_clock) + 1000);
825 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
826 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500827 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000828}
829
thsc8994012007-08-19 21:56:03 +0000830static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000831#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000832#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000833 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
834 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000835 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +0000836 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000837 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +0000838 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000839#endif
thsefe75412007-08-24 01:36:32 +0000840 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000841#else
thsefe75412007-08-24 01:36:32 +0000842 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
843 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
844 {"win32", 0, win32_start_timer,
845 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +0000846#endif
847 {NULL, }
848};
849
blueswir13f47aa82008-03-09 06:59:01 +0000850static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +0000851{
852 int i;
853
854 printf("Available alarm timers, in order of precedence:\n");
855 for (i = 0; alarm_timers[i].name; i++)
856 printf("%s\n", alarm_timers[i].name);
857}
858
859static void configure_alarms(char const *opt)
860{
861 int i;
862 int cur = 0;
malcb1503cd2008-12-22 20:33:55 +0000863 int count = ARRAY_SIZE(alarm_timers) - 1;
thsf3dcfad2007-08-24 01:26:02 +0000864 char *arg;
865 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +0000866 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +0000867
aurel323adda042008-03-09 23:43:49 +0000868 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +0000869 show_available_alarms();
870 exit(0);
871 }
872
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200873 arg = qemu_strdup(opt);
thsf3dcfad2007-08-24 01:26:02 +0000874
875 /* Reorder the array */
876 name = strtok(arg, ",");
877 while (name) {
balroge2b577e2007-09-17 21:25:20 +0000878 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +0000879 if (!strcmp(alarm_timers[i].name, name))
880 break;
881 }
882
883 if (i == count) {
884 fprintf(stderr, "Unknown clock %s\n", name);
885 goto next;
886 }
887
888 if (i < cur)
889 /* Ignore */
890 goto next;
891
892 /* Swap */
893 tmp = alarm_timers[i];
894 alarm_timers[i] = alarm_timers[cur];
895 alarm_timers[cur] = tmp;
896
897 cur++;
898next:
899 name = strtok(NULL, ",");
900 }
901
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200902 qemu_free(arg);
thsf3dcfad2007-08-24 01:26:02 +0000903
904 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +0000905 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +0000906 for (i = cur; i < count; i++)
907 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +0000908 } else {
909 show_available_alarms();
910 exit(1);
thsf3dcfad2007-08-24 01:26:02 +0000911 }
thsf3dcfad2007-08-24 01:26:02 +0000912}
913
Jan Kiszka21d5d122009-09-15 13:36:04 +0200914#define QEMU_NUM_CLOCKS 3
915
bellard8a7ddc32004-03-31 19:00:16 +0000916QEMUClock *rt_clock;
917QEMUClock *vm_clock;
Jan Kiszka21d5d122009-09-15 13:36:04 +0200918QEMUClock *host_clock;
bellard8a7ddc32004-03-31 19:00:16 +0000919
Jan Kiszka21d5d122009-09-15 13:36:04 +0200920static QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
bellard8a7ddc32004-03-31 19:00:16 +0000921
pbrook9596ebb2007-11-18 01:44:38 +0000922static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +0000923{
924 QEMUClock *clock;
925 clock = qemu_mallocz(sizeof(QEMUClock));
bellard8a7ddc32004-03-31 19:00:16 +0000926 clock->type = type;
927 return clock;
928}
929
930QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
931{
932 QEMUTimer *ts;
933
934 ts = qemu_mallocz(sizeof(QEMUTimer));
935 ts->clock = clock;
936 ts->cb = cb;
937 ts->opaque = opaque;
938 return ts;
939}
940
941void qemu_free_timer(QEMUTimer *ts)
942{
943 qemu_free(ts);
944}
945
946/* stop a timer, but do not dealloc it */
947void qemu_del_timer(QEMUTimer *ts)
948{
949 QEMUTimer **pt, *t;
950
951 /* NOTE: this code must be signal safe because
952 qemu_timer_expired() can be called from a signal. */
953 pt = &active_timers[ts->clock->type];
954 for(;;) {
955 t = *pt;
956 if (!t)
957 break;
958 if (t == ts) {
959 *pt = t->next;
960 break;
961 }
962 pt = &t->next;
963 }
964}
965
966/* modify the current timer so that it will be fired when current_time
967 >= expire_time. The corresponding callback will be called. */
968void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
969{
970 QEMUTimer **pt, *t;
971
972 qemu_del_timer(ts);
973
974 /* add the timer in the sorted list */
975 /* NOTE: this code must be signal safe because
976 qemu_timer_expired() can be called from a signal. */
977 pt = &active_timers[ts->clock->type];
978 for(;;) {
979 t = *pt;
980 if (!t)
981 break;
ths5fafdf22007-09-16 21:08:06 +0000982 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +0000983 break;
984 pt = &t->next;
985 }
986 ts->expire_time = expire_time;
987 ts->next = *pt;
988 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +0000989
990 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +0000991 if (pt == &active_timers[ts->clock->type]) {
992 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
993 qemu_rearm_alarm_timer(alarm_timer);
994 }
995 /* Interrupt execution to force deadline recalculation. */
aliguorid9f75a42009-04-24 18:03:11 +0000996 if (use_icount)
997 qemu_notify_event();
pbrook2e70f6e2008-06-29 01:03:05 +0000998 }
bellard8a7ddc32004-03-31 19:00:16 +0000999}
1000
1001int qemu_timer_pending(QEMUTimer *ts)
1002{
1003 QEMUTimer *t;
1004 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1005 if (t == ts)
1006 return 1;
1007 }
1008 return 0;
1009}
1010
Stefano Stabellini2430ffe2009-08-03 10:56:01 +01001011int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001012{
1013 if (!timer_head)
1014 return 0;
1015 return (timer_head->expire_time <= current_time);
1016}
1017
1018static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1019{
1020 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001021
bellard8a7ddc32004-03-31 19:00:16 +00001022 for(;;) {
1023 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001024 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001025 break;
1026 /* remove timer from the list before calling the callback */
1027 *ptimer_head = ts->next;
1028 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001029
bellard8a7ddc32004-03-31 19:00:16 +00001030 /* run the callback (the timer list can be modified) */
1031 ts->cb(ts->opaque);
1032 }
1033}
1034
1035int64_t qemu_get_clock(QEMUClock *clock)
1036{
1037 switch(clock->type) {
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001038 case QEMU_CLOCK_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001039 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001040 default:
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001041 case QEMU_CLOCK_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001042 if (use_icount) {
1043 return cpu_get_icount();
1044 } else {
1045 return cpu_get_clock();
1046 }
Jan Kiszka21d5d122009-09-15 13:36:04 +02001047 case QEMU_CLOCK_HOST:
1048 return get_clock_realtime();
bellard8a7ddc32004-03-31 19:00:16 +00001049 }
1050}
1051
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001052static void init_clocks(void)
bellard1dce7c32006-07-13 23:20:22 +00001053{
1054 init_get_clock();
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001055 rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
1056 vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001057 host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
bellard1dce7c32006-07-13 23:20:22 +00001058}
1059
bellard8a7ddc32004-03-31 19:00:16 +00001060/* save a timer */
1061void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1062{
1063 uint64_t expire_time;
1064
1065 if (qemu_timer_pending(ts)) {
1066 expire_time = ts->expire_time;
1067 } else {
1068 expire_time = -1;
1069 }
1070 qemu_put_be64(f, expire_time);
1071}
1072
1073void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1074{
1075 uint64_t expire_time;
1076
1077 expire_time = qemu_get_be64(f);
1078 if (expire_time != -1) {
1079 qemu_mod_timer(ts, expire_time);
1080 } else {
1081 qemu_del_timer(ts);
1082 }
1083}
1084
Juan Quintela2faf58c2009-09-10 03:04:28 +02001085static const VMStateDescription vmstate_timers = {
1086 .name = "timer",
1087 .version_id = 2,
1088 .minimum_version_id = 1,
1089 .minimum_version_id_old = 1,
1090 .fields = (VMStateField []) {
1091 VMSTATE_INT64(cpu_ticks_offset, TimersState),
Anthony Liguori274dfed2009-09-11 10:28:26 -05001092 VMSTATE_INT64(dummy, TimersState),
Juan Quintela2faf58c2009-09-10 03:04:28 +02001093 VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
1094 VMSTATE_END_OF_LIST()
bellardc88676f2006-08-06 13:36:11 +00001095 }
Juan Quintela2faf58c2009-09-10 03:04:28 +02001096};
bellard8a7ddc32004-03-31 19:00:16 +00001097
aliguori50317c72009-04-24 18:03:29 +00001098static void qemu_event_increment(void);
1099
bellard67b915a2004-03-31 23:37:16 +00001100#ifdef _WIN32
blueswir1b9e82a52009-04-05 18:03:31 +00001101static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1102 DWORD_PTR dwUser, DWORD_PTR dw1,
1103 DWORD_PTR dw2)
bellard67b915a2004-03-31 23:37:16 +00001104#else
bellard8a7ddc32004-03-31 19:00:16 +00001105static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001106#endif
bellard8a7ddc32004-03-31 19:00:16 +00001107{
bellard02ba45c2004-06-25 14:46:23 +00001108#if 0
1109#define DISP_FREQ 1000
1110 {
1111 static int64_t delta_min = INT64_MAX;
1112 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1113 static int count;
1114 ti = qemu_get_clock(vm_clock);
1115 if (last_clock != 0) {
1116 delta = ti - last_clock;
1117 if (delta < delta_min)
1118 delta_min = delta;
1119 if (delta > delta_max)
1120 delta_max = delta;
1121 delta_cum += delta;
1122 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001123 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
Juan Quintela6ee093c2009-09-10 03:04:26 +02001124 muldiv64(delta_min, 1000000, get_ticks_per_sec()),
1125 muldiv64(delta_max, 1000000, get_ticks_per_sec()),
1126 muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
1127 (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
bellard02ba45c2004-06-25 14:46:23 +00001128 count = 0;
1129 delta_min = INT64_MAX;
1130 delta_max = 0;
1131 delta_cum = 0;
1132 }
1133 }
1134 last_clock = ti;
1135 }
1136#endif
thsefe75412007-08-24 01:36:32 +00001137 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001138 (!use_icount &&
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001139 qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
pbrook2e70f6e2008-06-29 01:03:05 +00001140 qemu_get_clock(vm_clock))) ||
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001141 qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
Jan Kiszka21d5d122009-09-15 13:36:04 +02001142 qemu_get_clock(rt_clock)) ||
1143 qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
1144 qemu_get_clock(host_clock))) {
aliguori50317c72009-04-24 18:03:29 +00001145 qemu_event_increment();
Jean-Christophe Duboise3323402009-05-17 18:38:39 +02001146 if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
balrogd5d08332008-01-05 19:41:47 +00001147
aliguorid6dc3d42009-04-24 18:04:07 +00001148#ifndef CONFIG_IOTHREAD
1149 if (next_cpu) {
balrog4f8eb8d2007-12-16 12:39:38 +00001150 /* stop the currently executing cpu because a timer occured */
aliguorid6dc3d42009-04-24 18:04:07 +00001151 cpu_exit(next_cpu);
balrog4f8eb8d2007-12-16 12:39:38 +00001152 }
aliguorid6dc3d42009-04-24 18:04:07 +00001153#endif
aliguori43b96852009-04-24 18:03:33 +00001154 timer_alarm_pending = 1;
aliguorid9f75a42009-04-24 18:03:11 +00001155 qemu_notify_event();
bellard8a7ddc32004-03-31 19:00:16 +00001156 }
1157}
1158
pbrook2e70f6e2008-06-29 01:03:05 +00001159static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001160{
Jan Kiszka21d5d122009-09-15 13:36:04 +02001161 /* To avoid problems with overflow limit this to 2^32. */
1162 int64_t delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001163
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001164 if (active_timers[QEMU_CLOCK_VIRTUAL]) {
1165 delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001166 qemu_get_clock(vm_clock);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001167 }
1168 if (active_timers[QEMU_CLOCK_HOST]) {
1169 int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
1170 qemu_get_clock(host_clock);
1171 if (hdelta < delta)
1172 delta = hdelta;
thsefe75412007-08-24 01:36:32 +00001173 }
1174
pbrook2e70f6e2008-06-29 01:03:05 +00001175 if (delta < 0)
1176 delta = 0;
thsefe75412007-08-24 01:36:32 +00001177
pbrook2e70f6e2008-06-29 01:03:05 +00001178 return delta;
1179}
1180
Jan Kiszkaf64382b2009-09-15 13:36:04 +02001181#if defined(__linux__)
pbrook2e70f6e2008-06-29 01:03:05 +00001182static uint64_t qemu_next_deadline_dyntick(void)
1183{
1184 int64_t delta;
1185 int64_t rtdelta;
1186
1187 if (use_icount)
1188 delta = INT32_MAX;
1189 else
1190 delta = (qemu_next_deadline() + 999) / 1000;
1191
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001192 if (active_timers[QEMU_CLOCK_REALTIME]) {
1193 rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001194 qemu_get_clock(rt_clock))*1000;
1195 if (rtdelta < delta)
1196 delta = rtdelta;
1197 }
1198
1199 if (delta < MIN_TIMER_REARM_US)
1200 delta = MIN_TIMER_REARM_US;
1201
1202 return delta;
thsefe75412007-08-24 01:36:32 +00001203}
blueswir18632fb92008-09-14 13:59:34 +00001204#endif
thsefe75412007-08-24 01:36:32 +00001205
bellardfd872592004-05-12 19:11:15 +00001206#ifndef _WIN32
1207
aliguori7183b4b2008-11-05 20:40:18 +00001208/* Sets a specific flag */
1209static int fcntl_setfl(int fd, int flag)
1210{
1211 int flags;
1212
1213 flags = fcntl(fd, F_GETFL);
1214 if (flags == -1)
1215 return -errno;
1216
1217 if (fcntl(fd, F_SETFL, flags | flag) == -1)
1218 return -errno;
1219
1220 return 0;
1221}
1222
bellard829309c2004-05-20 13:20:12 +00001223#if defined(__linux__)
1224
bellardfd872592004-05-12 19:11:15 +00001225#define RTC_FREQ 1024
1226
aurel32de9a95f2008-11-11 13:41:01 +00001227static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001228{
thsc8994012007-08-19 21:56:03 +00001229 struct sigaction act;
1230
1231 /* timer signal */
1232 sigfillset(&act.sa_mask);
1233 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001234 act.sa_handler = host_alarm_handler;
1235
1236 sigaction(SIGIO, &act, NULL);
aliguori7183b4b2008-11-05 20:40:18 +00001237 fcntl_setfl(fd, O_ASYNC);
thsc8994012007-08-19 21:56:03 +00001238 fcntl(fd, F_SETOWN, getpid());
1239}
1240
thsc40ec5a2007-08-19 22:09:40 +00001241static int hpet_start_timer(struct qemu_alarm_timer *t)
1242{
1243 struct hpet_info info;
1244 int r, fd;
1245
1246 fd = open("/dev/hpet", O_RDONLY);
1247 if (fd < 0)
1248 return -1;
1249
1250 /* Set frequency */
1251 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1252 if (r < 0) {
1253 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1254 "error, but for better emulation accuracy type:\n"
1255 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1256 goto fail;
1257 }
1258
1259 /* Check capabilities */
1260 r = ioctl(fd, HPET_INFO, &info);
1261 if (r < 0)
1262 goto fail;
1263
1264 /* Enable periodic mode */
1265 r = ioctl(fd, HPET_EPI, 0);
1266 if (info.hi_flags && (r < 0))
1267 goto fail;
1268
1269 /* Enable interrupt */
1270 r = ioctl(fd, HPET_IE_ON, 0);
1271 if (r < 0)
1272 goto fail;
1273
1274 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001275 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001276
1277 return 0;
1278fail:
1279 close(fd);
1280 return -1;
1281}
1282
1283static void hpet_stop_timer(struct qemu_alarm_timer *t)
1284{
pbrookfcdc2122007-08-23 20:22:22 +00001285 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001286
1287 close(fd);
1288}
1289
thsc8994012007-08-19 21:56:03 +00001290static int rtc_start_timer(struct qemu_alarm_timer *t)
1291{
1292 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001293 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001294
balrogaeb30be2007-07-02 15:03:13 +00001295 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001296 if (rtc_fd < 0)
1297 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001298 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1299 if (current_rtc_freq != RTC_FREQ &&
1300 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001301 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1302 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1303 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1304 goto fail;
1305 }
1306 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1307 fail:
1308 close(rtc_fd);
1309 return -1;
1310 }
thsc8994012007-08-19 21:56:03 +00001311
1312 enable_sigio_timer(rtc_fd);
1313
pbrookfcdc2122007-08-23 20:22:22 +00001314 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001315
bellardfd872592004-05-12 19:11:15 +00001316 return 0;
1317}
1318
thsc8994012007-08-19 21:56:03 +00001319static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001320{
pbrookfcdc2122007-08-23 20:22:22 +00001321 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001322
1323 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001324}
1325
thsefe75412007-08-24 01:36:32 +00001326static int dynticks_start_timer(struct qemu_alarm_timer *t)
1327{
1328 struct sigevent ev;
1329 timer_t host_timer;
1330 struct sigaction act;
1331
1332 sigfillset(&act.sa_mask);
1333 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001334 act.sa_handler = host_alarm_handler;
1335
1336 sigaction(SIGALRM, &act, NULL);
1337
Jean-Christophe Dubois9ed415b2009-05-17 18:41:16 +02001338 /*
1339 * Initialize ev struct to 0 to avoid valgrind complaining
1340 * about uninitialized data in timer_create call
1341 */
1342 memset(&ev, 0, sizeof(ev));
thsefe75412007-08-24 01:36:32 +00001343 ev.sigev_value.sival_int = 0;
1344 ev.sigev_notify = SIGEV_SIGNAL;
1345 ev.sigev_signo = SIGALRM;
1346
1347 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1348 perror("timer_create");
1349
1350 /* disable dynticks */
1351 fprintf(stderr, "Dynamic Ticks disabled\n");
1352
1353 return -1;
1354 }
1355
blueswir10399bfe2008-11-16 11:37:18 +00001356 t->priv = (void *)(long)host_timer;
thsefe75412007-08-24 01:36:32 +00001357
1358 return 0;
1359}
1360
1361static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1362{
blueswir10399bfe2008-11-16 11:37:18 +00001363 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001364
1365 timer_delete(host_timer);
1366}
1367
1368static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1369{
blueswir10399bfe2008-11-16 11:37:18 +00001370 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001371 struct itimerspec timeout;
1372 int64_t nearest_delta_us = INT64_MAX;
1373 int64_t current_us;
1374
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001375 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001376 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1377 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001378 return;
thsefe75412007-08-24 01:36:32 +00001379
pbrook2e70f6e2008-06-29 01:03:05 +00001380 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001381
1382 /* check whether a timer is already running */
1383 if (timer_gettime(host_timer, &timeout)) {
1384 perror("gettime");
1385 fprintf(stderr, "Internal timer error: aborting\n");
1386 exit(1);
1387 }
1388 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1389 if (current_us && current_us <= nearest_delta_us)
1390 return;
1391
1392 timeout.it_interval.tv_sec = 0;
1393 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1394 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1395 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1396 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1397 perror("settime");
1398 fprintf(stderr, "Internal timer error: aborting\n");
1399 exit(1);
1400 }
1401}
1402
ths70744b32007-08-26 17:31:30 +00001403#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001404
thsc8994012007-08-19 21:56:03 +00001405static int unix_start_timer(struct qemu_alarm_timer *t)
1406{
1407 struct sigaction act;
1408 struct itimerval itv;
1409 int err;
1410
1411 /* timer signal */
1412 sigfillset(&act.sa_mask);
1413 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001414 act.sa_handler = host_alarm_handler;
1415
1416 sigaction(SIGALRM, &act, NULL);
1417
1418 itv.it_interval.tv_sec = 0;
1419 /* for i386 kernel 2.6 to get 1 ms */
1420 itv.it_interval.tv_usec = 999;
1421 itv.it_value.tv_sec = 0;
1422 itv.it_value.tv_usec = 10 * 1000;
1423
1424 err = setitimer(ITIMER_REAL, &itv, NULL);
1425 if (err)
1426 return -1;
1427
1428 return 0;
1429}
1430
1431static void unix_stop_timer(struct qemu_alarm_timer *t)
1432{
1433 struct itimerval itv;
1434
1435 memset(&itv, 0, sizeof(itv));
1436 setitimer(ITIMER_REAL, &itv, NULL);
1437}
1438
bellard829309c2004-05-20 13:20:12 +00001439#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001440
aliguorif49e58d2008-11-05 21:22:34 +00001441
thsc8994012007-08-19 21:56:03 +00001442#ifdef _WIN32
1443
1444static int win32_start_timer(struct qemu_alarm_timer *t)
1445{
1446 TIMECAPS tc;
1447 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001448 UINT flags;
thsc8994012007-08-19 21:56:03 +00001449
thsc8994012007-08-19 21:56:03 +00001450 memset(&tc, 0, sizeof(tc));
1451 timeGetDevCaps(&tc, sizeof(tc));
1452
1453 if (data->period < tc.wPeriodMin)
1454 data->period = tc.wPeriodMin;
1455
1456 timeBeginPeriod(data->period);
1457
thsefe75412007-08-24 01:36:32 +00001458 flags = TIME_CALLBACK_FUNCTION;
1459 if (alarm_has_dynticks(t))
1460 flags |= TIME_ONESHOT;
1461 else
1462 flags |= TIME_PERIODIC;
1463
thsc8994012007-08-19 21:56:03 +00001464 data->timerId = timeSetEvent(1, // interval (ms)
1465 data->period, // resolution
1466 host_alarm_handler, // function
1467 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001468 flags);
thsc8994012007-08-19 21:56:03 +00001469
1470 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001471 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
malc705e83f2009-09-27 14:30:33 +04001472 GetLastError());
thsc8994012007-08-19 21:56:03 +00001473 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001474 return -1;
1475 }
1476
thsc8994012007-08-19 21:56:03 +00001477 return 0;
1478}
1479
1480static void win32_stop_timer(struct qemu_alarm_timer *t)
1481{
1482 struct qemu_alarm_win32 *data = t->priv;
1483
1484 timeKillEvent(data->timerId);
1485 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001486}
1487
thsefe75412007-08-24 01:36:32 +00001488static void win32_rearm_timer(struct qemu_alarm_timer *t)
1489{
1490 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001491
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001492 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001493 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1494 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001495 return;
thsefe75412007-08-24 01:36:32 +00001496
thsefe75412007-08-24 01:36:32 +00001497 timeKillEvent(data->timerId);
1498
1499 data->timerId = timeSetEvent(1,
1500 data->period,
1501 host_alarm_handler,
1502 (DWORD)t,
1503 TIME_ONESHOT | TIME_PERIODIC);
1504
1505 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001506 fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
malc705e83f2009-09-27 14:30:33 +04001507 GetLastError());
thsefe75412007-08-24 01:36:32 +00001508
1509 timeEndPeriod(data->period);
thsefe75412007-08-24 01:36:32 +00001510 exit(1);
1511 }
1512}
1513
thsc8994012007-08-19 21:56:03 +00001514#endif /* _WIN32 */
1515
aliguori7183b4b2008-11-05 20:40:18 +00001516static int init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001517{
blueswir1223f0d72008-09-30 18:12:18 +00001518 struct qemu_alarm_timer *t = NULL;
thsc8994012007-08-19 21:56:03 +00001519 int i, err = -1;
aliguorif49e58d2008-11-05 21:22:34 +00001520
thsc8994012007-08-19 21:56:03 +00001521 for (i = 0; alarm_timers[i].name; i++) {
1522 t = &alarm_timers[i];
1523
thsc8994012007-08-19 21:56:03 +00001524 err = t->start(t);
1525 if (!err)
1526 break;
bellard67b915a2004-03-31 23:37:16 +00001527 }
bellardfd872592004-05-12 19:11:15 +00001528
thsc8994012007-08-19 21:56:03 +00001529 if (err) {
aliguori7183b4b2008-11-05 20:40:18 +00001530 err = -ENOENT;
1531 goto fail;
bellard67b915a2004-03-31 23:37:16 +00001532 }
thsc8994012007-08-19 21:56:03 +00001533
1534 alarm_timer = t;
aliguori7183b4b2008-11-05 20:40:18 +00001535
aliguori6abfbd72008-11-05 20:49:37 +00001536 return 0;
aliguori7183b4b2008-11-05 20:40:18 +00001537
1538fail:
aliguori7183b4b2008-11-05 20:40:18 +00001539 return err;
bellard8a7ddc32004-03-31 19:00:16 +00001540}
1541
pbrook9596ebb2007-11-18 01:44:38 +00001542static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001543{
thsc8994012007-08-19 21:56:03 +00001544 alarm_timer->stop(alarm_timer);
1545 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001546}
1547
bellardc4b1fcc2004-03-14 21:44:30 +00001548/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001549/* host time/date access */
1550void qemu_get_timedate(struct tm *tm, int offset)
1551{
1552 time_t ti;
1553 struct tm *ret;
1554
1555 time(&ti);
1556 ti += offset;
1557 if (rtc_date_offset == -1) {
1558 if (rtc_utc)
1559 ret = gmtime(&ti);
1560 else
1561 ret = localtime(&ti);
1562 } else {
1563 ti -= rtc_date_offset;
1564 ret = gmtime(&ti);
1565 }
1566
1567 memcpy(tm, ret, sizeof(struct tm));
1568}
1569
1570int qemu_timedate_diff(struct tm *tm)
1571{
1572 time_t seconds;
1573
1574 if (rtc_date_offset == -1)
1575 if (rtc_utc)
1576 seconds = mktimegm(tm);
1577 else
1578 seconds = mktime(tm);
1579 else
1580 seconds = mktimegm(tm) + rtc_date_offset;
1581
1582 return seconds - time(NULL);
1583}
1584
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02001585static void configure_rtc_date_offset(const char *startdate, int legacy)
1586{
1587 time_t rtc_start_date;
1588 struct tm tm;
1589
1590 if (!strcmp(startdate, "now") && legacy) {
1591 rtc_date_offset = -1;
1592 } else {
1593 if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
1594 &tm.tm_year,
1595 &tm.tm_mon,
1596 &tm.tm_mday,
1597 &tm.tm_hour,
1598 &tm.tm_min,
1599 &tm.tm_sec) == 6) {
1600 /* OK */
1601 } else if (sscanf(startdate, "%d-%d-%d",
1602 &tm.tm_year,
1603 &tm.tm_mon,
1604 &tm.tm_mday) == 3) {
1605 tm.tm_hour = 0;
1606 tm.tm_min = 0;
1607 tm.tm_sec = 0;
1608 } else {
1609 goto date_fail;
1610 }
1611 tm.tm_year -= 1900;
1612 tm.tm_mon--;
1613 rtc_start_date = mktimegm(&tm);
1614 if (rtc_start_date == -1) {
1615 date_fail:
1616 fprintf(stderr, "Invalid date format. Valid formats are:\n"
1617 "'2006-06-17T16:01:21' or '2006-06-17'\n");
1618 exit(1);
1619 }
1620 rtc_date_offset = time(NULL) - rtc_start_date;
1621 }
1622}
1623
1624static void configure_rtc(QemuOpts *opts)
1625{
1626 const char *value;
1627
1628 value = qemu_opt_get(opts, "base");
1629 if (value) {
1630 if (!strcmp(value, "utc")) {
1631 rtc_utc = 1;
1632 } else if (!strcmp(value, "localtime")) {
1633 rtc_utc = 0;
1634 } else {
1635 configure_rtc_date_offset(value, 0);
1636 }
1637 }
1638#ifdef CONFIG_TARGET_I386
1639 value = qemu_opt_get(opts, "driftfix");
1640 if (value) {
1641 if (!strcmp(buf, "slew")) {
1642 rtc_td_hack = 1;
1643 } else if (!strcmp(buf, "none")) {
1644 rtc_td_hack = 0;
1645 } else {
1646 fprintf(stderr, "qemu: invalid option value '%s'\n", value);
1647 exit(1);
1648 }
1649 }
1650#endif
1651}
1652
bellardfd1dff42006-02-01 21:29:26 +00001653#ifdef _WIN32
bellardfd1dff42006-02-01 21:29:26 +00001654static void socket_cleanup(void)
1655{
1656 WSACleanup();
1657}
bellard82c643f2004-07-14 17:28:13 +00001658
bellardfd1dff42006-02-01 21:29:26 +00001659static int socket_init(void)
1660{
1661 WSADATA Data;
1662 int ret, err;
1663
1664 ret = WSAStartup(MAKEWORD(2,2), &Data);
1665 if (ret != 0) {
1666 err = WSAGetLastError();
1667 fprintf(stderr, "WSAStartup: %d\n", err);
1668 return -1;
1669 }
1670 atexit(socket_cleanup);
1671 return 0;
1672}
aurel3264b7b732008-05-05 10:05:31 +00001673#endif
1674
balrog1ae26a12008-09-28 23:19:47 +00001675/***********************************************************/
1676/* Bluetooth support */
1677static int nb_hcis;
1678static int cur_hci;
1679static struct HCIInfo *hci_table[MAX_NICS];
balrogdc72ac12008-11-09 00:04:26 +00001680
balrog1ae26a12008-09-28 23:19:47 +00001681static struct bt_vlan_s {
1682 struct bt_scatternet_s net;
1683 int id;
1684 struct bt_vlan_s *next;
1685} *first_bt_vlan;
1686
1687/* find or alloc a new bluetooth "VLAN" */
blueswir1674bb262008-09-30 18:18:27 +00001688static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
balrog1ae26a12008-09-28 23:19:47 +00001689{
1690 struct bt_vlan_s **pvlan, *vlan;
1691 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
1692 if (vlan->id == id)
1693 return &vlan->net;
1694 }
1695 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
1696 vlan->id = id;
1697 pvlan = &first_bt_vlan;
1698 while (*pvlan != NULL)
1699 pvlan = &(*pvlan)->next;
1700 *pvlan = vlan;
1701 return &vlan->net;
1702}
1703
1704static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
1705{
1706}
1707
1708static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
1709{
1710 return -ENOTSUP;
1711}
1712
1713static struct HCIInfo null_hci = {
1714 .cmd_send = null_hci_send,
1715 .sco_send = null_hci_send,
1716 .acl_send = null_hci_send,
1717 .bdaddr_set = null_hci_addr_set,
1718};
1719
1720struct HCIInfo *qemu_next_hci(void)
1721{
1722 if (cur_hci == nb_hcis)
1723 return &null_hci;
1724
1725 return hci_table[cur_hci++];
1726}
1727
balrogdc72ac12008-11-09 00:04:26 +00001728static struct HCIInfo *hci_init(const char *str)
1729{
1730 char *endp;
1731 struct bt_scatternet_s *vlan = 0;
1732
1733 if (!strcmp(str, "null"))
1734 /* null */
1735 return &null_hci;
1736 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
1737 /* host[:hciN] */
1738 return bt_host_hci(str[4] ? str + 5 : "hci0");
1739 else if (!strncmp(str, "hci", 3)) {
1740 /* hci[,vlan=n] */
1741 if (str[3]) {
1742 if (!strncmp(str + 3, ",vlan=", 6)) {
1743 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
1744 if (*endp)
1745 vlan = 0;
1746 }
1747 } else
1748 vlan = qemu_find_bt_vlan(0);
1749 if (vlan)
1750 return bt_new_hci(vlan);
1751 }
1752
1753 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
1754
1755 return 0;
1756}
1757
1758static int bt_hci_parse(const char *str)
1759{
1760 struct HCIInfo *hci;
Anthony Liguoric227f092009-10-01 16:12:16 -05001761 bdaddr_t bdaddr;
balrogdc72ac12008-11-09 00:04:26 +00001762
1763 if (nb_hcis >= MAX_NICS) {
1764 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
1765 return -1;
1766 }
1767
1768 hci = hci_init(str);
1769 if (!hci)
1770 return -1;
1771
1772 bdaddr.b[0] = 0x52;
1773 bdaddr.b[1] = 0x54;
1774 bdaddr.b[2] = 0x00;
1775 bdaddr.b[3] = 0x12;
1776 bdaddr.b[4] = 0x34;
1777 bdaddr.b[5] = 0x56 + nb_hcis;
1778 hci->bdaddr_set(hci, bdaddr.b);
1779
1780 hci_table[nb_hcis++] = hci;
1781
1782 return 0;
1783}
1784
1785static void bt_vhci_add(int vlan_id)
1786{
1787 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
1788
1789 if (!vlan->slave)
1790 fprintf(stderr, "qemu: warning: adding a VHCI to "
1791 "an empty scatternet %i\n", vlan_id);
1792
1793 bt_vhci_init(bt_new_hci(vlan));
1794}
1795
1796static struct bt_device_s *bt_device_add(const char *opt)
1797{
1798 struct bt_scatternet_s *vlan;
1799 int vlan_id = 0;
1800 char *endp = strstr(opt, ",vlan=");
1801 int len = (endp ? endp - opt : strlen(opt)) + 1;
1802 char devname[10];
1803
1804 pstrcpy(devname, MIN(sizeof(devname), len), opt);
1805
1806 if (endp) {
1807 vlan_id = strtol(endp + 6, &endp, 0);
1808 if (*endp) {
1809 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
1810 return 0;
1811 }
1812 }
1813
1814 vlan = qemu_find_bt_vlan(vlan_id);
1815
1816 if (!vlan->slave)
1817 fprintf(stderr, "qemu: warning: adding a slave device to "
1818 "an empty scatternet %i\n", vlan_id);
1819
1820 if (!strcmp(devname, "keyboard"))
1821 return bt_keyboard_init(vlan);
1822
1823 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
1824 return 0;
1825}
1826
1827static int bt_parse(const char *opt)
1828{
1829 const char *endp, *p;
1830 int vlan;
1831
1832 if (strstart(opt, "hci", &endp)) {
1833 if (!*endp || *endp == ',') {
1834 if (*endp)
1835 if (!strstart(endp, ",vlan=", 0))
1836 opt = endp + 1;
1837
1838 return bt_hci_parse(opt);
1839 }
1840 } else if (strstart(opt, "vhci", &endp)) {
1841 if (!*endp || *endp == ',') {
1842 if (*endp) {
1843 if (strstart(endp, ",vlan=", &p)) {
1844 vlan = strtol(p, (char **) &endp, 0);
1845 if (*endp) {
1846 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
1847 return 1;
1848 }
1849 } else {
1850 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
1851 return 1;
1852 }
1853 } else
1854 vlan = 0;
1855
1856 bt_vhci_add(vlan);
1857 return 0;
1858 }
1859 } else if (strstart(opt, "device:", &endp))
1860 return !bt_device_add(endp);
1861
1862 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
1863 return 1;
1864}
1865
balrog1ae26a12008-09-28 23:19:47 +00001866/***********************************************************/
1867/* QEMU Block devices */
1868
balrog609497a2008-01-14 02:56:53 +00001869#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00001870#define CDROM_ALIAS "index=2,media=cdrom"
thse4bcb142007-12-02 04:51:10 +00001871#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00001872#define PFLASH_ALIAS "if=pflash"
1873#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00001874#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00001875
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001876QemuOpts *drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00001877{
1878 va_list ap;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001879 char optstr[1024];
1880 QemuOpts *opts;
thse4bcb142007-12-02 04:51:10 +00001881
thse4bcb142007-12-02 04:51:10 +00001882 va_start(ap, fmt);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001883 vsnprintf(optstr, sizeof(optstr), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00001884 va_end(ap);
1885
Gerd Hoffmann7282a032009-07-31 12:25:35 +02001886 opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001887 if (!opts) {
1888 fprintf(stderr, "%s: huh? duplicate? (%s)\n",
1889 __FUNCTION__, optstr);
1890 return NULL;
1891 }
1892 if (file)
1893 qemu_opt_set(opts, "file", file);
1894 return opts;
aliguorib01b1112009-02-11 15:20:20 +00001895}
1896
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001897DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00001898{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001899 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001900
1901 /* seek interface, bus and unit */
1902
Blue Swirl72cf2d42009-09-12 07:36:22 +00001903 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001904 if (dinfo->type == type &&
1905 dinfo->bus == bus &&
1906 dinfo->unit == unit)
1907 return dinfo;
1908 }
thse4bcb142007-12-02 04:51:10 +00001909
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001910 return NULL;
thse4bcb142007-12-02 04:51:10 +00001911}
1912
Gerd Hoffmann2e810b32009-07-31 12:25:38 +02001913DriveInfo *drive_get_by_id(const char *id)
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001914{
1915 DriveInfo *dinfo;
1916
Blue Swirl72cf2d42009-09-12 07:36:22 +00001917 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001918 if (strcmp(id, dinfo->id))
1919 continue;
1920 return dinfo;
1921 }
1922 return NULL;
1923}
1924
thsf60d39b2007-12-17 03:55:57 +00001925int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00001926{
1927 int max_bus;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001928 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001929
1930 max_bus = -1;
Blue Swirl72cf2d42009-09-12 07:36:22 +00001931 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001932 if(dinfo->type == type &&
1933 dinfo->bus > max_bus)
1934 max_bus = dinfo->bus;
thse4bcb142007-12-02 04:51:10 +00001935 }
1936 return max_bus;
1937}
1938
aliguorifa879c62009-01-07 17:32:33 +00001939const char *drive_get_serial(BlockDriverState *bdrv)
1940{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001941 DriveInfo *dinfo;
aliguorifa879c62009-01-07 17:32:33 +00001942
Blue Swirl72cf2d42009-09-12 07:36:22 +00001943 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001944 if (dinfo->bdrv == bdrv)
1945 return dinfo->serial;
1946 }
aliguorifa879c62009-01-07 17:32:33 +00001947
1948 return "\0";
1949}
1950
aliguori428c5702009-01-21 18:59:04 +00001951BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
1952{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001953 DriveInfo *dinfo;
aliguori428c5702009-01-21 18:59:04 +00001954
Blue Swirl72cf2d42009-09-12 07:36:22 +00001955 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001956 if (dinfo->bdrv == bdrv)
1957 return dinfo->onerror;
1958 }
aliguori428c5702009-01-21 18:59:04 +00001959
aliguoricdad4bd2009-02-28 16:51:01 +00001960 return BLOCK_ERR_STOP_ENOSPC;
aliguori428c5702009-01-21 18:59:04 +00001961}
1962
aurel32a1620fa2008-04-29 05:58:01 +00001963static void bdrv_format_print(void *opaque, const char *name)
1964{
1965 fprintf(stderr, " %s", name);
1966}
1967
aliguorib01b1112009-02-11 15:20:20 +00001968void drive_uninit(BlockDriverState *bdrv)
1969{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001970 DriveInfo *dinfo;
aliguorib01b1112009-02-11 15:20:20 +00001971
Blue Swirl72cf2d42009-09-12 07:36:22 +00001972 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001973 if (dinfo->bdrv != bdrv)
1974 continue;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001975 qemu_opts_del(dinfo->opts);
Blue Swirl72cf2d42009-09-12 07:36:22 +00001976 QTAILQ_REMOVE(&drives, dinfo, next);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001977 qemu_free(dinfo);
1978 break;
1979 }
aliguorib01b1112009-02-11 15:20:20 +00001980}
1981
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001982DriveInfo *drive_init(QemuOpts *opts, void *opaque,
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001983 int *fatal_error)
thse4bcb142007-12-02 04:51:10 +00001984{
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001985 const char *buf;
1986 const char *file = NULL;
balrogc8522bd2007-12-06 22:11:20 +00001987 char devname[128];
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001988 const char *serial;
balrogc8522bd2007-12-06 22:11:20 +00001989 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00001990 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00001991 enum { MEDIA_DISK, MEDIA_CDROM } media;
1992 int bus_id, unit_id;
1993 int cyls, heads, secs, translation;
aurel321e72d3b2008-04-28 20:26:45 +00001994 BlockDriver *drv = NULL;
aliguori4d73cd32009-02-11 15:20:46 +00001995 QEMUMachine *machine = opaque;
thse4bcb142007-12-02 04:51:10 +00001996 int max_devs;
1997 int index;
balrog33f00272007-12-24 14:33:24 +00001998 int cache;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02001999 int aio = 0;
aliguori428c5702009-01-21 18:59:04 +00002000 int bdrv_flags, onerror;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002001 const char *devaddr;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002002 DriveInfo *dinfo;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002003 int snapshot = 0;
2004
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002005 *fatal_error = 1;
thse4bcb142007-12-02 04:51:10 +00002006
thse4bcb142007-12-02 04:51:10 +00002007 translation = BIOS_ATA_TRANSLATION_AUTO;
Kevin Wolf0aa217e2009-06-30 13:06:04 +02002008 cache = 1;
thse4bcb142007-12-02 04:51:10 +00002009
Gerd Hoffmann4d007812009-08-31 14:23:57 +02002010 if (machine && machine->use_scsi) {
thsf60d39b2007-12-17 03:55:57 +00002011 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002012 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002013 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00002014 } else {
thsf60d39b2007-12-17 03:55:57 +00002015 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002016 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002017 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00002018 }
2019 media = MEDIA_DISK;
2020
2021 /* extract parameters */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002022 bus_id = qemu_opt_get_number(opts, "bus", 0);
2023 unit_id = qemu_opt_get_number(opts, "unit", -1);
2024 index = qemu_opt_get_number(opts, "index", -1);
thse4bcb142007-12-02 04:51:10 +00002025
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002026 cyls = qemu_opt_get_number(opts, "cyls", 0);
2027 heads = qemu_opt_get_number(opts, "heads", 0);
2028 secs = qemu_opt_get_number(opts, "secs", 0);
thse4bcb142007-12-02 04:51:10 +00002029
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002030 snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
thse4bcb142007-12-02 04:51:10 +00002031
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002032 file = qemu_opt_get(opts, "file");
2033 serial = qemu_opt_get(opts, "serial");
2034
2035 if ((buf = qemu_opt_get(opts, "if")) != NULL) {
bellardae45d362008-06-11 09:44:44 +00002036 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00002037 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00002038 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002039 max_devs = MAX_IDE_DEVS;
2040 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00002041 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002042 max_devs = MAX_SCSI_DEVS;
2043 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00002044 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00002045 max_devs = 0;
2046 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00002047 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00002048 max_devs = 0;
2049 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00002050 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00002051 max_devs = 0;
2052 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00002053 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00002054 max_devs = 0;
aliguori6e02c382008-12-04 19:52:44 +00002055 } else if (!strcmp(buf, "virtio")) {
2056 type = IF_VIRTIO;
2057 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002058 } else if (!strcmp(buf, "xen")) {
2059 type = IF_XEN;
2060 max_devs = 0;
Gerd Hoffmanna8659e92009-07-31 12:25:39 +02002061 } else if (!strcmp(buf, "none")) {
2062 type = IF_NONE;
2063 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002064 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002065 fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002066 return NULL;
thse4bcb142007-12-02 04:51:10 +00002067 }
2068 }
2069
thse4bcb142007-12-02 04:51:10 +00002070 if (cyls || heads || secs) {
2071 if (cyls < 1 || cyls > 16383) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002072 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002073 return NULL;
thse4bcb142007-12-02 04:51:10 +00002074 }
2075 if (heads < 1 || heads > 16) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002076 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002077 return NULL;
thse4bcb142007-12-02 04:51:10 +00002078 }
2079 if (secs < 1 || secs > 63) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002080 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002081 return NULL;
thse4bcb142007-12-02 04:51:10 +00002082 }
2083 }
2084
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002085 if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002086 if (!cyls) {
2087 fprintf(stderr,
2088 "qemu: '%s' trans must be used with cyls,heads and secs\n",
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002089 buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002090 return NULL;
thse4bcb142007-12-02 04:51:10 +00002091 }
2092 if (!strcmp(buf, "none"))
2093 translation = BIOS_ATA_TRANSLATION_NONE;
2094 else if (!strcmp(buf, "lba"))
2095 translation = BIOS_ATA_TRANSLATION_LBA;
2096 else if (!strcmp(buf, "auto"))
2097 translation = BIOS_ATA_TRANSLATION_AUTO;
2098 else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002099 fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002100 return NULL;
thse4bcb142007-12-02 04:51:10 +00002101 }
2102 }
2103
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002104 if ((buf = qemu_opt_get(opts, "media")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002105 if (!strcmp(buf, "disk")) {
2106 media = MEDIA_DISK;
2107 } else if (!strcmp(buf, "cdrom")) {
2108 if (cyls || secs || heads) {
2109 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002110 "qemu: '%s' invalid physical CHS format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002111 return NULL;
thse4bcb142007-12-02 04:51:10 +00002112 }
2113 media = MEDIA_CDROM;
2114 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002115 fprintf(stderr, "qemu: '%s' invalid media\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002116 return NULL;
thse4bcb142007-12-02 04:51:10 +00002117 }
2118 }
2119
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002120 if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
aliguori9f7965c2008-10-14 14:42:54 +00002121 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
balrog33f00272007-12-24 14:33:24 +00002122 cache = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002123 else if (!strcmp(buf, "writethrough"))
balrog33f00272007-12-24 14:33:24 +00002124 cache = 1;
aliguori9f7965c2008-10-14 14:42:54 +00002125 else if (!strcmp(buf, "writeback"))
2126 cache = 2;
balrog33f00272007-12-24 14:33:24 +00002127 else {
2128 fprintf(stderr, "qemu: invalid cache option\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002129 return NULL;
balrog33f00272007-12-24 14:33:24 +00002130 }
2131 }
2132
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002133#ifdef CONFIG_LINUX_AIO
2134 if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
2135 if (!strcmp(buf, "threads"))
2136 aio = 0;
2137 else if (!strcmp(buf, "native"))
2138 aio = 1;
2139 else {
2140 fprintf(stderr, "qemu: invalid aio option\n");
2141 return NULL;
2142 }
2143 }
2144#endif
2145
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002146 if ((buf = qemu_opt_get(opts, "format")) != NULL) {
aurel32a1620fa2008-04-29 05:58:01 +00002147 if (strcmp(buf, "?") == 0) {
2148 fprintf(stderr, "qemu: Supported formats:");
2149 bdrv_iterate_format(bdrv_format_print, NULL);
2150 fprintf(stderr, "\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002151 return NULL;
aurel32a1620fa2008-04-29 05:58:01 +00002152 }
aurel321e72d3b2008-04-28 20:26:45 +00002153 drv = bdrv_find_format(buf);
2154 if (!drv) {
2155 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002156 return NULL;
aurel321e72d3b2008-04-28 20:26:45 +00002157 }
2158 }
2159
aliguoricdad4bd2009-02-28 16:51:01 +00002160 onerror = BLOCK_ERR_STOP_ENOSPC;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002161 if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
aliguori869a5c62009-01-22 19:52:25 +00002162 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
aliguoriea8a5d72009-01-22 19:52:21 +00002163 fprintf(stderr, "werror is no supported by this format\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002164 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002165 }
2166 if (!strcmp(buf, "ignore"))
2167 onerror = BLOCK_ERR_IGNORE;
2168 else if (!strcmp(buf, "enospc"))
2169 onerror = BLOCK_ERR_STOP_ENOSPC;
2170 else if (!strcmp(buf, "stop"))
2171 onerror = BLOCK_ERR_STOP_ANY;
2172 else if (!strcmp(buf, "report"))
2173 onerror = BLOCK_ERR_REPORT;
2174 else {
2175 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002176 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002177 }
2178 }
2179
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002180 if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002181 if (type != IF_VIRTIO) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002182 fprintf(stderr, "addr is not supported\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002183 return NULL;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002184 }
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002185 }
2186
thse4bcb142007-12-02 04:51:10 +00002187 /* compute bus and unit according index */
2188
2189 if (index != -1) {
2190 if (bus_id != 0 || unit_id != -1) {
2191 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002192 "qemu: index cannot be used with bus and unit\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002193 return NULL;
thse4bcb142007-12-02 04:51:10 +00002194 }
2195 if (max_devs == 0)
2196 {
2197 unit_id = index;
2198 bus_id = 0;
2199 } else {
2200 unit_id = index % max_devs;
2201 bus_id = index / max_devs;
2202 }
2203 }
2204
2205 /* if user doesn't specify a unit_id,
2206 * try to find the first free
2207 */
2208
2209 if (unit_id == -1) {
2210 unit_id = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002211 while (drive_get(type, bus_id, unit_id) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002212 unit_id++;
2213 if (max_devs && unit_id >= max_devs) {
2214 unit_id -= max_devs;
2215 bus_id++;
2216 }
2217 }
2218 }
2219
2220 /* check unit id */
2221
2222 if (max_devs && unit_id >= max_devs) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002223 fprintf(stderr, "qemu: unit %d too big (max is %d)\n",
2224 unit_id, max_devs - 1);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002225 return NULL;
thse4bcb142007-12-02 04:51:10 +00002226 }
2227
2228 /*
2229 * ignore multiple definitions
2230 */
2231
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002232 if (drive_get(type, bus_id, unit_id) != NULL) {
2233 *fatal_error = 0;
2234 return NULL;
2235 }
thse4bcb142007-12-02 04:51:10 +00002236
2237 /* init */
2238
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002239 dinfo = qemu_mallocz(sizeof(*dinfo));
Gerd Hoffmanne23d9c42009-07-31 12:25:34 +02002240 if ((buf = qemu_opts_id(opts)) != NULL) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002241 dinfo->id = qemu_strdup(buf);
2242 } else {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002243 /* no id supplied -> create one */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002244 dinfo->id = qemu_mallocz(32);
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002245 if (type == IF_IDE || type == IF_SCSI)
2246 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
2247 if (max_devs)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002248 snprintf(dinfo->id, 32, "%s%i%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002249 devname, bus_id, mediastr, unit_id);
2250 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002251 snprintf(dinfo->id, 32, "%s%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002252 devname, mediastr, unit_id);
2253 }
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002254 dinfo->bdrv = bdrv_new(dinfo->id);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002255 dinfo->devaddr = devaddr;
2256 dinfo->type = type;
2257 dinfo->bus = bus_id;
2258 dinfo->unit = unit_id;
2259 dinfo->onerror = onerror;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002260 dinfo->opts = opts;
2261 if (serial)
2262 strncpy(dinfo->serial, serial, sizeof(serial));
Blue Swirl72cf2d42009-09-12 07:36:22 +00002263 QTAILQ_INSERT_TAIL(&drives, dinfo, next);
thse4bcb142007-12-02 04:51:10 +00002264
thsf60d39b2007-12-17 03:55:57 +00002265 switch(type) {
thse4bcb142007-12-02 04:51:10 +00002266 case IF_IDE:
2267 case IF_SCSI:
aliguori62d23ef2009-04-22 15:19:30 +00002268 case IF_XEN:
Gerd Hoffmannc2193312009-09-15 19:23:28 +00002269 case IF_NONE:
thse4bcb142007-12-02 04:51:10 +00002270 switch(media) {
2271 case MEDIA_DISK:
2272 if (cyls != 0) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002273 bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
2274 bdrv_set_translation_hint(dinfo->bdrv, translation);
thse4bcb142007-12-02 04:51:10 +00002275 }
2276 break;
2277 case MEDIA_CDROM:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002278 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
thse4bcb142007-12-02 04:51:10 +00002279 break;
2280 }
2281 break;
2282 case IF_SD:
2283 /* FIXME: This isn't really a floppy, but it's a reasonable
2284 approximation. */
2285 case IF_FLOPPY:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002286 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
thse4bcb142007-12-02 04:51:10 +00002287 break;
2288 case IF_PFLASH:
2289 case IF_MTD:
2290 break;
Gerd Hoffmannd176c492009-07-31 12:25:41 +02002291 case IF_VIRTIO:
2292 /* add virtio block device */
2293 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
2294 qemu_opt_set(opts, "driver", "virtio-blk-pci");
2295 qemu_opt_set(opts, "drive", dinfo->id);
2296 if (devaddr)
2297 qemu_opt_set(opts, "addr", devaddr);
2298 break;
Paul Brookaae94602009-05-14 22:35:06 +01002299 case IF_COUNT:
2300 abort();
thse4bcb142007-12-02 04:51:10 +00002301 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002302 if (!file) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002303 *fatal_error = 0;
2304 return NULL;
2305 }
balrog33f00272007-12-24 14:33:24 +00002306 bdrv_flags = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002307 if (snapshot) {
balrog33f00272007-12-24 14:33:24 +00002308 bdrv_flags |= BDRV_O_SNAPSHOT;
aliguori9f7965c2008-10-14 14:42:54 +00002309 cache = 2; /* always use write-back with snapshot */
2310 }
2311 if (cache == 0) /* no caching */
2312 bdrv_flags |= BDRV_O_NOCACHE;
2313 else if (cache == 2) /* write-back */
2314 bdrv_flags |= BDRV_O_CACHE_WB;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002315
2316 if (aio == 1) {
2317 bdrv_flags |= BDRV_O_NATIVE_AIO;
2318 } else {
2319 bdrv_flags &= ~BDRV_O_NATIVE_AIO;
2320 }
2321
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002322 if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
thse4bcb142007-12-02 04:51:10 +00002323 fprintf(stderr, "qemu: could not open disk image %s\n",
2324 file);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002325 return NULL;
thse4bcb142007-12-02 04:51:10 +00002326 }
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002327
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002328 if (bdrv_key_required(dinfo->bdrv))
aliguoric0f4ce72009-03-05 23:01:01 +00002329 autostart = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002330 *fatal_error = 0;
2331 return dinfo;
thse4bcb142007-12-02 04:51:10 +00002332}
2333
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002334static int drive_init_func(QemuOpts *opts, void *opaque)
2335{
2336 QEMUMachine *machine = opaque;
2337 int fatal_error = 0;
2338
2339 if (drive_init(opts, machine, &fatal_error) == NULL) {
2340 if (fatal_error)
2341 return 1;
2342 }
2343 return 0;
2344}
2345
2346static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
2347{
2348 if (NULL == qemu_opt_get(opts, "snapshot")) {
2349 qemu_opt_set(opts, "snapshot", "on");
2350 }
2351 return 0;
2352}
2353
Jan Kiszka76e30d02009-07-02 00:19:02 +02002354void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
2355{
2356 boot_set_handler = func;
2357 boot_set_opaque = opaque;
2358}
2359
2360int qemu_boot_set(const char *boot_devices)
2361{
2362 if (!boot_set_handler) {
2363 return -EINVAL;
2364 }
2365 return boot_set_handler(boot_set_opaque, boot_devices);
2366}
2367
Jan Kiszkaef3adf62009-07-02 00:19:02 +02002368static int parse_bootdevices(char *devices)
2369{
2370 /* We just do some generic consistency checks */
2371 const char *p;
2372 int bitmap = 0;
2373
2374 for (p = devices; *p != '\0'; p++) {
2375 /* Allowed boot devices are:
2376 * a-b: floppy disk drives
2377 * c-f: IDE disk drives
2378 * g-m: machine implementation dependant drives
2379 * n-p: network devices
2380 * It's up to each machine implementation to check if the given boot
2381 * devices match the actual hardware implementation and firmware
2382 * features.
2383 */
2384 if (*p < 'a' || *p > 'p') {
2385 fprintf(stderr, "Invalid boot device '%c'\n", *p);
2386 exit(1);
2387 }
2388 if (bitmap & (1 << (*p - 'a'))) {
2389 fprintf(stderr, "Boot device '%c' was given twice\n", *p);
2390 exit(1);
2391 }
2392 bitmap |= 1 << (*p - 'a');
2393 }
2394 return bitmap;
2395}
2396
Jan Kiszkae0f084b2009-07-02 00:19:02 +02002397static void restore_boot_devices(void *opaque)
2398{
2399 char *standard_boot_devices = opaque;
2400
2401 qemu_boot_set(standard_boot_devices);
2402
2403 qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
2404 qemu_free(standard_boot_devices);
2405}
2406
aliguori268a3622009-04-21 22:30:27 +00002407static void numa_add(const char *optarg)
2408{
2409 char option[128];
2410 char *endptr;
2411 unsigned long long value, endvalue;
2412 int nodenr;
2413
2414 optarg = get_opt_name(option, 128, optarg, ',') + 1;
2415 if (!strcmp(option, "node")) {
2416 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
2417 nodenr = nb_numa_nodes;
2418 } else {
2419 nodenr = strtoull(option, NULL, 10);
2420 }
2421
2422 if (get_param_value(option, 128, "mem", optarg) == 0) {
2423 node_mem[nodenr] = 0;
2424 } else {
2425 value = strtoull(option, &endptr, 0);
2426 switch (*endptr) {
2427 case 0: case 'M': case 'm':
2428 value <<= 20;
2429 break;
2430 case 'G': case 'g':
2431 value <<= 30;
2432 break;
2433 }
2434 node_mem[nodenr] = value;
2435 }
2436 if (get_param_value(option, 128, "cpus", optarg) == 0) {
2437 node_cpumask[nodenr] = 0;
2438 } else {
2439 value = strtoull(option, &endptr, 10);
2440 if (value >= 64) {
2441 value = 63;
2442 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
2443 } else {
2444 if (*endptr == '-') {
2445 endvalue = strtoull(endptr+1, &endptr, 10);
2446 if (endvalue >= 63) {
2447 endvalue = 62;
2448 fprintf(stderr,
2449 "only 63 CPUs in NUMA mode supported.\n");
2450 }
2451 value = (1 << (endvalue + 1)) - (1 << value);
2452 } else {
2453 value = 1 << value;
2454 }
2455 }
2456 node_cpumask[nodenr] = value;
2457 }
2458 nb_numa_nodes++;
2459 }
2460 return;
2461}
2462
Andre Przywaradc6b1c02009-08-19 15:42:40 +02002463static void smp_parse(const char *optarg)
2464{
2465 int smp, sockets = 0, threads = 0, cores = 0;
2466 char *endptr;
2467 char option[128];
2468
2469 smp = strtoul(optarg, &endptr, 10);
2470 if (endptr != optarg) {
2471 if (*endptr == ',') {
2472 endptr++;
2473 }
2474 }
2475 if (get_param_value(option, 128, "sockets", endptr) != 0)
2476 sockets = strtoull(option, NULL, 10);
2477 if (get_param_value(option, 128, "cores", endptr) != 0)
2478 cores = strtoull(option, NULL, 10);
2479 if (get_param_value(option, 128, "threads", endptr) != 0)
2480 threads = strtoull(option, NULL, 10);
2481 if (get_param_value(option, 128, "maxcpus", endptr) != 0)
2482 max_cpus = strtoull(option, NULL, 10);
2483
2484 /* compute missing values, prefer sockets over cores over threads */
2485 if (smp == 0 || sockets == 0) {
2486 sockets = sockets > 0 ? sockets : 1;
2487 cores = cores > 0 ? cores : 1;
2488 threads = threads > 0 ? threads : 1;
2489 if (smp == 0) {
2490 smp = cores * threads * sockets;
2491 } else {
2492 sockets = smp / (cores * threads);
2493 }
2494 } else {
2495 if (cores == 0) {
2496 threads = threads > 0 ? threads : 1;
2497 cores = smp / (sockets * threads);
2498 } else {
2499 if (sockets == 0) {
2500 sockets = smp / (cores * threads);
2501 } else {
2502 threads = smp / (cores * sockets);
2503 }
2504 }
2505 }
2506 smp_cpus = smp;
2507 smp_cores = cores > 0 ? cores : 1;
2508 smp_threads = threads > 0 ? threads : 1;
2509 if (max_cpus == 0)
2510 max_cpus = smp_cpus;
2511}
2512
bellard330d0412003-07-26 18:11:40 +00002513/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00002514/* USB devices */
2515
aliguoribb5fc202009-03-05 23:01:15 +00002516static void usb_msd_password_cb(void *opaque, int err)
2517{
2518 USBDevice *dev = opaque;
2519
2520 if (!err)
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002521 usb_device_attach(dev);
aliguoribb5fc202009-03-05 23:01:15 +00002522 else
Gerd Hoffmann806b6022009-08-31 14:23:59 +02002523 dev->info->handle_destroy(dev);
aliguoribb5fc202009-03-05 23:01:15 +00002524}
2525
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002526static struct {
2527 const char *name;
2528 const char *qdev;
2529} usbdevs[] = {
2530 {
2531 .name = "mouse",
2532 .qdev = "QEMU USB Mouse",
2533 },{
2534 .name = "tablet",
2535 .qdev = "QEMU USB Tablet",
2536 },{
2537 .name = "keyboard",
2538 .qdev = "QEMU USB Keyboard",
2539 },{
2540 .name = "wacom-tablet",
2541 .qdev = "QEMU PenPartner Tablet",
2542 }
2543};
2544
aliguoric0f4ce72009-03-05 23:01:01 +00002545static int usb_device_add(const char *devname, int is_hotplug)
bellarda594cfb2005-11-06 16:13:29 +00002546{
2547 const char *p;
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002548 USBBus *bus = usb_bus_find(-1 /* any */);
2549 USBDevice *dev = NULL;
2550 int i;
bellarda594cfb2005-11-06 16:13:29 +00002551
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002552 if (!usb_enabled)
bellarda594cfb2005-11-06 16:13:29 +00002553 return -1;
2554
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002555 /* simple devices which don't need extra care */
2556 for (i = 0; i < ARRAY_SIZE(usbdevs); i++) {
2557 if (strcmp(devname, usbdevs[i].name) != 0)
2558 continue;
2559 dev = usb_create_simple(bus, usbdevs[i].qdev);
2560 goto done;
2561 }
2562
2563 /* the other ones */
bellarda594cfb2005-11-06 16:13:29 +00002564 if (strstart(devname, "host:", &p)) {
2565 dev = usb_host_device_open(p);
pbrook2e5d83b2006-05-25 23:58:51 +00002566 } else if (strstart(devname, "disk:", &p)) {
aliguoric0f4ce72009-03-05 23:01:01 +00002567 BlockDriverState *bs;
2568
aliguoribb5fc202009-03-05 23:01:15 +00002569 dev = usb_msd_init(p);
aliguoric0f4ce72009-03-05 23:01:01 +00002570 if (!dev)
2571 return -1;
aliguoribb5fc202009-03-05 23:01:15 +00002572 bs = usb_msd_get_bdrv(dev);
aliguoric0f4ce72009-03-05 23:01:01 +00002573 if (bdrv_key_required(bs)) {
2574 autostart = 0;
aliguoribb5fc202009-03-05 23:01:15 +00002575 if (is_hotplug) {
aliguori376253e2009-03-05 23:01:23 +00002576 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
2577 dev);
aliguoribb5fc202009-03-05 23:01:15 +00002578 return 0;
aliguoric0f4ce72009-03-05 23:01:01 +00002579 }
2580 }
balroga7954212008-01-14 03:41:02 +00002581 } else if (strstart(devname, "serial:", &p)) {
2582 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00002583#ifdef CONFIG_BRLAPI
2584 } else if (!strcmp(devname, "braille")) {
2585 dev = usb_baum_init();
2586#endif
balrog6c9f8862008-07-17 20:47:13 +00002587 } else if (strstart(devname, "net:", &p)) {
balrog9ad97e62008-07-29 13:16:31 +00002588 int nic = nb_nics;
balrog6c9f8862008-07-17 20:47:13 +00002589
Jan Kiszka10ae5a72009-05-08 12:34:18 +02002590 if (net_client_init(NULL, "nic", p) < 0)
balrog6c9f8862008-07-17 20:47:13 +00002591 return -1;
balrog9ad97e62008-07-29 13:16:31 +00002592 nd_table[nic].model = "usb";
2593 dev = usb_net_init(&nd_table[nic]);
balrogdc72ac12008-11-09 00:04:26 +00002594 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
2595 dev = usb_bt_init(devname[2] ? hci_init(p) :
2596 bt_new_hci(qemu_find_bt_vlan(0)));
bellarda594cfb2005-11-06 16:13:29 +00002597 } else {
2598 return -1;
2599 }
pbrook0d92ed32006-05-21 16:30:15 +00002600 if (!dev)
2601 return -1;
2602
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002603done:
bellarda594cfb2005-11-06 16:13:29 +00002604 return 0;
2605}
2606
aliguori1f3870a2008-08-21 19:27:48 +00002607static int usb_device_del(const char *devname)
2608{
2609 int bus_num, addr;
2610 const char *p;
2611
aliguori5d0c5752008-09-14 01:07:41 +00002612 if (strstart(devname, "host:", &p))
2613 return usb_host_device_close(p);
2614
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002615 if (!usb_enabled)
aliguori1f3870a2008-08-21 19:27:48 +00002616 return -1;
2617
2618 p = strchr(devname, '.');
2619 if (!p)
2620 return -1;
2621 bus_num = strtoul(devname, NULL, 0);
2622 addr = strtoul(p + 1, NULL, 0);
2623
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002624 return usb_device_delete_addr(bus_num, addr);
aliguori1f3870a2008-08-21 19:27:48 +00002625}
2626
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02002627static int usb_parse(const char *cmdline)
2628{
2629 return usb_device_add(cmdline, 0);
2630}
2631
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002632void do_usb_add(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002633{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002634 usb_device_add(qdict_get_str(qdict, "devname"), 1);
bellarda594cfb2005-11-06 16:13:29 +00002635}
2636
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002637void do_usb_del(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002638{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002639 usb_device_del(qdict_get_str(qdict, "devname"));
bellarda594cfb2005-11-06 16:13:29 +00002640}
2641
bellardf7cce892004-12-08 22:21:25 +00002642/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00002643/* PCMCIA/Cardbus */
2644
2645static struct pcmcia_socket_entry_s {
Paul Brookbc24a222009-05-10 01:44:56 +01002646 PCMCIASocket *socket;
balrog201a51f2007-04-30 00:51:09 +00002647 struct pcmcia_socket_entry_s *next;
2648} *pcmcia_sockets = 0;
2649
Paul Brookbc24a222009-05-10 01:44:56 +01002650void pcmcia_socket_register(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002651{
2652 struct pcmcia_socket_entry_s *entry;
2653
2654 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
2655 entry->socket = socket;
2656 entry->next = pcmcia_sockets;
2657 pcmcia_sockets = entry;
2658}
2659
Paul Brookbc24a222009-05-10 01:44:56 +01002660void pcmcia_socket_unregister(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002661{
2662 struct pcmcia_socket_entry_s *entry, **ptr;
2663
2664 ptr = &pcmcia_sockets;
2665 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
2666 if (entry->socket == socket) {
2667 *ptr = entry->next;
2668 qemu_free(entry);
2669 }
2670}
2671
aliguori376253e2009-03-05 23:01:23 +00002672void pcmcia_info(Monitor *mon)
balrog201a51f2007-04-30 00:51:09 +00002673{
2674 struct pcmcia_socket_entry_s *iter;
aliguori376253e2009-03-05 23:01:23 +00002675
balrog201a51f2007-04-30 00:51:09 +00002676 if (!pcmcia_sockets)
aliguori376253e2009-03-05 23:01:23 +00002677 monitor_printf(mon, "No PCMCIA sockets\n");
balrog201a51f2007-04-30 00:51:09 +00002678
2679 for (iter = pcmcia_sockets; iter; iter = iter->next)
aliguori376253e2009-03-05 23:01:23 +00002680 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
2681 iter->socket->attached ? iter->socket->card_string :
2682 "Empty");
balrog201a51f2007-04-30 00:51:09 +00002683}
2684
2685/***********************************************************/
aliguori3023f332009-01-16 19:04:14 +00002686/* register display */
2687
aliguori7b5d76d2009-03-13 15:02:13 +00002688struct DisplayAllocator default_allocator = {
2689 defaultallocator_create_displaysurface,
2690 defaultallocator_resize_displaysurface,
2691 defaultallocator_free_displaysurface
2692};
2693
aliguori3023f332009-01-16 19:04:14 +00002694void register_displaystate(DisplayState *ds)
2695{
2696 DisplayState **s;
2697 s = &display_state;
2698 while (*s != NULL)
2699 s = &(*s)->next;
2700 ds->next = NULL;
2701 *s = ds;
2702}
2703
2704DisplayState *get_displaystate(void)
2705{
2706 return display_state;
2707}
2708
aliguori7b5d76d2009-03-13 15:02:13 +00002709DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
2710{
2711 if(ds->allocator == &default_allocator) ds->allocator = da;
2712 return ds->allocator;
2713}
2714
ths2ff89792007-06-21 23:34:19 +00002715/* dumb display */
2716
aliguori8f391ab2009-01-19 16:34:10 +00002717static void dumb_display_init(void)
ths2ff89792007-06-21 23:34:19 +00002718{
aliguori8f391ab2009-01-19 16:34:10 +00002719 DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
aliguori7b5d76d2009-03-13 15:02:13 +00002720 ds->allocator = &default_allocator;
2721 ds->surface = qemu_create_displaysurface(ds, 640, 480);
aliguori8f391ab2009-01-19 16:34:10 +00002722 register_displaystate(ds);
ths2ff89792007-06-21 23:34:19 +00002723}
2724
2725/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002726/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00002727
bellardc4b1fcc2004-03-14 21:44:30 +00002728typedef struct IOHandlerRecord {
2729 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00002730 IOCanRWHandler *fd_read_poll;
2731 IOHandler *fd_read;
2732 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00002733 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00002734 void *opaque;
2735 /* temporary data */
2736 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00002737 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00002738} IOHandlerRecord;
2739
bellard8a7ddc32004-03-31 19:00:16 +00002740static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00002741
bellard7c9d8e02005-11-15 22:16:05 +00002742/* XXX: fd_read_poll should be suppressed, but an API change is
2743 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00002744int qemu_set_fd_handler2(int fd,
2745 IOCanRWHandler *fd_read_poll,
2746 IOHandler *fd_read,
2747 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002748 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00002749{
bellard8a7ddc32004-03-31 19:00:16 +00002750 IOHandlerRecord **pioh, *ioh;
2751
bellard7c9d8e02005-11-15 22:16:05 +00002752 if (!fd_read && !fd_write) {
2753 pioh = &first_io_handler;
2754 for(;;) {
2755 ioh = *pioh;
2756 if (ioh == NULL)
2757 break;
2758 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00002759 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00002760 break;
2761 }
2762 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00002763 }
bellard7c9d8e02005-11-15 22:16:05 +00002764 } else {
2765 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2766 if (ioh->fd == fd)
2767 goto found;
2768 }
2769 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
bellard7c9d8e02005-11-15 22:16:05 +00002770 ioh->next = first_io_handler;
2771 first_io_handler = ioh;
2772 found:
2773 ioh->fd = fd;
2774 ioh->fd_read_poll = fd_read_poll;
2775 ioh->fd_read = fd_read;
2776 ioh->fd_write = fd_write;
2777 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00002778 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00002779 }
bellard7c9d8e02005-11-15 22:16:05 +00002780 return 0;
2781}
2782
ths5fafdf22007-09-16 21:08:06 +00002783int qemu_set_fd_handler(int fd,
2784 IOHandler *fd_read,
2785 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002786 void *opaque)
2787{
2788 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00002789}
2790
aliguori56f3a5d2008-10-31 18:07:17 +00002791#ifdef _WIN32
bellard8a7ddc32004-03-31 19:00:16 +00002792/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00002793/* Polling handling */
2794
2795typedef struct PollingEntry {
2796 PollingFunc *func;
2797 void *opaque;
2798 struct PollingEntry *next;
2799} PollingEntry;
2800
2801static PollingEntry *first_polling_entry;
2802
2803int qemu_add_polling_cb(PollingFunc *func, void *opaque)
2804{
2805 PollingEntry **ppe, *pe;
2806 pe = qemu_mallocz(sizeof(PollingEntry));
bellardf3311102006-04-12 20:21:17 +00002807 pe->func = func;
2808 pe->opaque = opaque;
2809 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
2810 *ppe = pe;
2811 return 0;
2812}
2813
2814void qemu_del_polling_cb(PollingFunc *func, void *opaque)
2815{
2816 PollingEntry **ppe, *pe;
2817 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
2818 pe = *ppe;
2819 if (pe->func == func && pe->opaque == opaque) {
2820 *ppe = pe->next;
2821 qemu_free(pe);
2822 break;
2823 }
2824 }
2825}
2826
bellarda18e5242006-06-25 17:18:27 +00002827/***********************************************************/
2828/* Wait objects support */
2829typedef struct WaitObjects {
2830 int num;
2831 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
2832 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
2833 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
2834} WaitObjects;
2835
2836static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00002837
bellarda18e5242006-06-25 17:18:27 +00002838int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2839{
2840 WaitObjects *w = &wait_objects;
2841
2842 if (w->num >= MAXIMUM_WAIT_OBJECTS)
2843 return -1;
2844 w->events[w->num] = handle;
2845 w->func[w->num] = func;
2846 w->opaque[w->num] = opaque;
2847 w->num++;
2848 return 0;
2849}
2850
2851void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2852{
2853 int i, found;
2854 WaitObjects *w = &wait_objects;
2855
2856 found = 0;
2857 for (i = 0; i < w->num; i++) {
2858 if (w->events[i] == handle)
2859 found = 1;
2860 if (found) {
2861 w->events[i] = w->events[i + 1];
2862 w->func[i] = w->func[i + 1];
2863 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00002864 }
bellarda18e5242006-06-25 17:18:27 +00002865 }
2866 if (found)
2867 w->num--;
2868}
2869#endif
2870
bellard8a7ddc32004-03-31 19:00:16 +00002871/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002872/* ram save/restore */
2873
Juan Quintela94fb0902009-09-10 03:04:23 +02002874#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
aliguori475e4272008-10-06 20:21:51 +00002875#define RAM_SAVE_FLAG_COMPRESS 0x02
2876#define RAM_SAVE_FLAG_MEM_SIZE 0x04
2877#define RAM_SAVE_FLAG_PAGE 0x08
2878#define RAM_SAVE_FLAG_EOS 0x10
2879
2880static int is_dup_page(uint8_t *page, uint8_t ch)
bellardc88676f2006-08-06 13:36:11 +00002881{
aliguori475e4272008-10-06 20:21:51 +00002882 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
2883 uint32_t *array = (uint32_t *)page;
2884 int i;
ths3b46e622007-09-17 08:09:54 +00002885
aliguori475e4272008-10-06 20:21:51 +00002886 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
2887 if (array[i] != val)
2888 return 0;
bellardc88676f2006-08-06 13:36:11 +00002889 }
aliguori475e4272008-10-06 20:21:51 +00002890
2891 return 1;
bellardc88676f2006-08-06 13:36:11 +00002892}
2893
aliguori475e4272008-10-06 20:21:51 +00002894static int ram_save_block(QEMUFile *f)
2895{
Anthony Liguoric227f092009-10-01 16:12:16 -05002896 static ram_addr_t current_addr = 0;
2897 ram_addr_t saved_addr = current_addr;
2898 ram_addr_t addr = 0;
aliguori475e4272008-10-06 20:21:51 +00002899 int found = 0;
2900
pbrook94a6b542009-04-11 17:15:54 +00002901 while (addr < last_ram_offset) {
aliguori475e4272008-10-06 20:21:51 +00002902 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
pbrook5579c7f2009-04-11 14:47:08 +00002903 uint8_t *p;
aliguori475e4272008-10-06 20:21:51 +00002904
2905 cpu_physical_memory_reset_dirty(current_addr,
2906 current_addr + TARGET_PAGE_SIZE,
2907 MIGRATION_DIRTY_FLAG);
2908
pbrook5579c7f2009-04-11 14:47:08 +00002909 p = qemu_get_ram_ptr(current_addr);
aliguori475e4272008-10-06 20:21:51 +00002910
pbrook5579c7f2009-04-11 14:47:08 +00002911 if (is_dup_page(p, *p)) {
aliguori475e4272008-10-06 20:21:51 +00002912 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
pbrook5579c7f2009-04-11 14:47:08 +00002913 qemu_put_byte(f, *p);
aliguori475e4272008-10-06 20:21:51 +00002914 } else {
2915 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
pbrook5579c7f2009-04-11 14:47:08 +00002916 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
aliguori475e4272008-10-06 20:21:51 +00002917 }
2918
2919 found = 1;
2920 break;
2921 }
2922 addr += TARGET_PAGE_SIZE;
pbrook94a6b542009-04-11 17:15:54 +00002923 current_addr = (saved_addr + addr) % last_ram_offset;
aliguori475e4272008-10-06 20:21:51 +00002924 }
2925
2926 return found;
2927}
2928
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002929static uint64_t bytes_transferred = 0;
aliguori475e4272008-10-06 20:21:51 +00002930
Anthony Liguoric227f092009-10-01 16:12:16 -05002931static ram_addr_t ram_save_remaining(void)
aliguori475e4272008-10-06 20:21:51 +00002932{
Anthony Liguoric227f092009-10-01 16:12:16 -05002933 ram_addr_t addr;
2934 ram_addr_t count = 0;
aliguori475e4272008-10-06 20:21:51 +00002935
pbrook94a6b542009-04-11 17:15:54 +00002936 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00002937 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2938 count++;
2939 }
2940
2941 return count;
2942}
2943
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002944uint64_t ram_bytes_remaining(void)
2945{
2946 return ram_save_remaining() * TARGET_PAGE_SIZE;
2947}
2948
2949uint64_t ram_bytes_transferred(void)
2950{
2951 return bytes_transferred;
2952}
2953
2954uint64_t ram_bytes_total(void)
2955{
2956 return last_ram_offset;
2957}
2958
aliguori475e4272008-10-06 20:21:51 +00002959static int ram_save_live(QEMUFile *f, int stage, void *opaque)
2960{
Anthony Liguoric227f092009-10-01 16:12:16 -05002961 ram_addr_t addr;
Glauber Costaa0a3fd62009-05-28 15:22:57 -04002962 uint64_t bytes_transferred_last;
2963 double bwidth = 0;
2964 uint64_t expected_time = 0;
aliguori475e4272008-10-06 20:21:51 +00002965
Jan Kiszka9fa06382009-05-22 23:51:45 +02002966 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
Jan Kiszkab0a46a32009-05-02 00:22:51 +02002967 qemu_file_set_error(f);
2968 return 0;
2969 }
2970
aliguori475e4272008-10-06 20:21:51 +00002971 if (stage == 1) {
2972 /* Make sure all dirty bits are set */
pbrook94a6b542009-04-11 17:15:54 +00002973 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00002974 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2975 cpu_physical_memory_set_dirty(addr);
2976 }
Jan Kiszkab0a46a32009-05-02 00:22:51 +02002977
aliguori475e4272008-10-06 20:21:51 +00002978 /* Enable dirty memory tracking */
2979 cpu_physical_memory_set_dirty_tracking(1);
2980
pbrook94a6b542009-04-11 17:15:54 +00002981 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
aliguori475e4272008-10-06 20:21:51 +00002982 }
2983
Glauber Costaa0a3fd62009-05-28 15:22:57 -04002984 bytes_transferred_last = bytes_transferred;
2985 bwidth = get_clock();
2986
aliguori475e4272008-10-06 20:21:51 +00002987 while (!qemu_file_rate_limit(f)) {
2988 int ret;
2989
2990 ret = ram_save_block(f);
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002991 bytes_transferred += ret * TARGET_PAGE_SIZE;
aliguori475e4272008-10-06 20:21:51 +00002992 if (ret == 0) /* no more blocks */
2993 break;
2994 }
2995
Glauber Costaa0a3fd62009-05-28 15:22:57 -04002996 bwidth = get_clock() - bwidth;
2997 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
2998
2999 /* if we haven't transferred anything this round, force expected_time to a
3000 * a very high value, but without crashing */
3001 if (bwidth == 0)
3002 bwidth = 0.000001;
3003
aliguori475e4272008-10-06 20:21:51 +00003004 /* try transferring iterative blocks of memory */
3005
3006 if (stage == 3) {
aliguori475e4272008-10-06 20:21:51 +00003007
3008 /* flush all remaining blocks regardless of rate limiting */
Glauber Costa9f9e28c2009-05-21 17:38:01 -04003009 while (ram_save_block(f) != 0) {
3010 bytes_transferred += TARGET_PAGE_SIZE;
3011 }
aliguori8215e912009-04-05 19:30:55 +00003012 cpu_physical_memory_set_dirty_tracking(0);
aliguori475e4272008-10-06 20:21:51 +00003013 }
3014
3015 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
3016
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003017 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
3018
3019 return (stage == 2) && (expected_time <= migrate_max_downtime());
aliguori475e4272008-10-06 20:21:51 +00003020}
3021
aliguori475e4272008-10-06 20:21:51 +00003022static int ram_load(QEMUFile *f, void *opaque, int version_id)
3023{
Anthony Liguoric227f092009-10-01 16:12:16 -05003024 ram_addr_t addr;
aliguori475e4272008-10-06 20:21:51 +00003025 int flags;
3026
aliguori475e4272008-10-06 20:21:51 +00003027 if (version_id != 3)
3028 return -EINVAL;
3029
3030 do {
3031 addr = qemu_get_be64(f);
3032
3033 flags = addr & ~TARGET_PAGE_MASK;
3034 addr &= TARGET_PAGE_MASK;
3035
3036 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
pbrook94a6b542009-04-11 17:15:54 +00003037 if (addr != last_ram_offset)
aliguori475e4272008-10-06 20:21:51 +00003038 return -EINVAL;
3039 }
3040
aliguori475e4272008-10-06 20:21:51 +00003041 if (flags & RAM_SAVE_FLAG_COMPRESS) {
3042 uint8_t ch = qemu_get_byte(f);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003043 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
3044#ifndef _WIN32
Anthony Liguori30868442009-06-17 16:46:12 -05003045 if (ch == 0 &&
3046 (!kvm_enabled() || kvm_has_sync_mmu())) {
3047 madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003048 }
Anthony Liguori30868442009-06-17 16:46:12 -05003049#endif
aliguori475e4272008-10-06 20:21:51 +00003050 } else if (flags & RAM_SAVE_FLAG_PAGE)
pbrook5579c7f2009-04-11 14:47:08 +00003051 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
aliguori475e4272008-10-06 20:21:51 +00003052 } while (!(flags & RAM_SAVE_FLAG_EOS));
3053
bellardc88676f2006-08-06 13:36:11 +00003054 return 0;
3055}
3056
aliguori9e472e12008-10-08 19:50:24 +00003057void qemu_service_io(void)
3058{
aliguorid9f75a42009-04-24 18:03:11 +00003059 qemu_notify_event();
aliguori9e472e12008-10-08 19:50:24 +00003060}
3061
bellard8a7ddc32004-03-31 19:00:16 +00003062/***********************************************************/
bellard83f64092006-08-01 16:21:11 +00003063/* bottom halves (can be seen as timers which expire ASAP) */
3064
3065struct QEMUBH {
3066 QEMUBHFunc *cb;
3067 void *opaque;
3068 int scheduled;
aliguori1b435b12008-10-31 17:24:21 +00003069 int idle;
3070 int deleted;
bellard83f64092006-08-01 16:21:11 +00003071 QEMUBH *next;
3072};
3073
3074static QEMUBH *first_bh = NULL;
3075
3076QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
3077{
3078 QEMUBH *bh;
3079 bh = qemu_mallocz(sizeof(QEMUBH));
bellard83f64092006-08-01 16:21:11 +00003080 bh->cb = cb;
3081 bh->opaque = opaque;
aliguori1b435b12008-10-31 17:24:21 +00003082 bh->next = first_bh;
3083 first_bh = bh;
bellard83f64092006-08-01 16:21:11 +00003084 return bh;
3085}
3086
bellard6eb57332006-08-06 09:51:25 +00003087int qemu_bh_poll(void)
bellard83f64092006-08-01 16:21:11 +00003088{
aliguori1b435b12008-10-31 17:24:21 +00003089 QEMUBH *bh, **bhp;
bellard6eb57332006-08-06 09:51:25 +00003090 int ret;
bellard83f64092006-08-01 16:21:11 +00003091
bellard6eb57332006-08-06 09:51:25 +00003092 ret = 0;
aliguori1b435b12008-10-31 17:24:21 +00003093 for (bh = first_bh; bh; bh = bh->next) {
3094 if (!bh->deleted && bh->scheduled) {
3095 bh->scheduled = 0;
3096 if (!bh->idle)
3097 ret = 1;
3098 bh->idle = 0;
3099 bh->cb(bh->opaque);
3100 }
bellard83f64092006-08-01 16:21:11 +00003101 }
aliguori1b435b12008-10-31 17:24:21 +00003102
3103 /* remove deleted bhs */
3104 bhp = &first_bh;
3105 while (*bhp) {
3106 bh = *bhp;
3107 if (bh->deleted) {
3108 *bhp = bh->next;
3109 qemu_free(bh);
3110 } else
3111 bhp = &bh->next;
3112 }
3113
bellard6eb57332006-08-06 09:51:25 +00003114 return ret;
bellard83f64092006-08-01 16:21:11 +00003115}
3116
aliguori1b435b12008-10-31 17:24:21 +00003117void qemu_bh_schedule_idle(QEMUBH *bh)
3118{
3119 if (bh->scheduled)
3120 return;
3121 bh->scheduled = 1;
3122 bh->idle = 1;
3123}
3124
bellard83f64092006-08-01 16:21:11 +00003125void qemu_bh_schedule(QEMUBH *bh)
3126{
bellard83f64092006-08-01 16:21:11 +00003127 if (bh->scheduled)
3128 return;
3129 bh->scheduled = 1;
aliguori1b435b12008-10-31 17:24:21 +00003130 bh->idle = 0;
bellard83f64092006-08-01 16:21:11 +00003131 /* stop the currently executing CPU to execute the BH ASAP */
aliguorid9f75a42009-04-24 18:03:11 +00003132 qemu_notify_event();
bellard83f64092006-08-01 16:21:11 +00003133}
3134
3135void qemu_bh_cancel(QEMUBH *bh)
3136{
aliguori1b435b12008-10-31 17:24:21 +00003137 bh->scheduled = 0;
bellard83f64092006-08-01 16:21:11 +00003138}
3139
3140void qemu_bh_delete(QEMUBH *bh)
3141{
aliguori1b435b12008-10-31 17:24:21 +00003142 bh->scheduled = 0;
3143 bh->deleted = 1;
bellard83f64092006-08-01 16:21:11 +00003144}
3145
aliguori56f3a5d2008-10-31 18:07:17 +00003146static void qemu_bh_update_timeout(int *timeout)
3147{
3148 QEMUBH *bh;
3149
3150 for (bh = first_bh; bh; bh = bh->next) {
3151 if (!bh->deleted && bh->scheduled) {
3152 if (bh->idle) {
3153 /* idle bottom halves will be polled at least
3154 * every 10ms */
3155 *timeout = MIN(10, *timeout);
3156 } else {
3157 /* non-idle bottom halves will be executed
3158 * immediately */
3159 *timeout = 0;
3160 break;
3161 }
3162 }
3163 }
3164}
3165
bellard83f64092006-08-01 16:21:11 +00003166/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00003167/* machine registration */
3168
blueswir1bdaf78e2008-10-04 07:24:27 +00003169static QEMUMachine *first_machine = NULL;
aliguori6f338c32009-02-11 15:21:54 +00003170QEMUMachine *current_machine = NULL;
bellardcc1daa42005-06-05 14:49:17 +00003171
3172int qemu_register_machine(QEMUMachine *m)
3173{
3174 QEMUMachine **pm;
3175 pm = &first_machine;
3176 while (*pm != NULL)
3177 pm = &(*pm)->next;
3178 m->next = NULL;
3179 *pm = m;
3180 return 0;
3181}
3182
pbrook9596ebb2007-11-18 01:44:38 +00003183static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00003184{
3185 QEMUMachine *m;
3186
3187 for(m = first_machine; m != NULL; m = m->next) {
3188 if (!strcmp(m->name, name))
3189 return m;
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01003190 if (m->alias && !strcmp(m->alias, name))
3191 return m;
bellardcc1daa42005-06-05 14:49:17 +00003192 }
3193 return NULL;
3194}
3195
Anthony Liguori0c257432009-05-21 20:41:01 -05003196static QEMUMachine *find_default_machine(void)
3197{
3198 QEMUMachine *m;
3199
3200 for(m = first_machine; m != NULL; m = m->next) {
3201 if (m->is_default) {
3202 return m;
3203 }
3204 }
3205 return NULL;
3206}
3207
bellardcc1daa42005-06-05 14:49:17 +00003208/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00003209/* main execution loop */
3210
pbrook9596ebb2007-11-18 01:44:38 +00003211static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00003212{
aliguori7d957bd2009-01-15 22:14:11 +00003213 uint64_t interval = GUI_REFRESH_INTERVAL;
ths740733b2007-06-08 01:57:56 +00003214 DisplayState *ds = opaque;
aliguori7d957bd2009-01-15 22:14:11 +00003215 DisplayChangeListener *dcl = ds->listeners;
3216
3217 dpy_refresh(ds);
3218
3219 while (dcl != NULL) {
3220 if (dcl->gui_timer_interval &&
3221 dcl->gui_timer_interval < interval)
3222 interval = dcl->gui_timer_interval;
3223 dcl = dcl->next;
3224 }
3225 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00003226}
3227
blueswir19043b622009-01-21 19:28:13 +00003228static void nographic_update(void *opaque)
3229{
3230 uint64_t interval = GUI_REFRESH_INTERVAL;
3231
3232 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
3233}
3234
bellard0bd48852005-11-11 00:00:47 +00003235struct vm_change_state_entry {
3236 VMChangeStateHandler *cb;
3237 void *opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003238 QLIST_ENTRY (vm_change_state_entry) entries;
bellard0bd48852005-11-11 00:00:47 +00003239};
3240
Blue Swirl72cf2d42009-09-12 07:36:22 +00003241static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
bellard0bd48852005-11-11 00:00:47 +00003242
3243VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
3244 void *opaque)
3245{
3246 VMChangeStateEntry *e;
3247
3248 e = qemu_mallocz(sizeof (*e));
bellard0bd48852005-11-11 00:00:47 +00003249
3250 e->cb = cb;
3251 e->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003252 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
bellard0bd48852005-11-11 00:00:47 +00003253 return e;
3254}
3255
3256void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
3257{
Blue Swirl72cf2d42009-09-12 07:36:22 +00003258 QLIST_REMOVE (e, entries);
bellard0bd48852005-11-11 00:00:47 +00003259 qemu_free (e);
3260}
3261
aliguori9781e042009-01-22 17:15:29 +00003262static void vm_state_notify(int running, int reason)
bellard0bd48852005-11-11 00:00:47 +00003263{
3264 VMChangeStateEntry *e;
3265
3266 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
aliguori9781e042009-01-22 17:15:29 +00003267 e->cb(e->opaque, running, reason);
bellard0bd48852005-11-11 00:00:47 +00003268 }
3269}
3270
aliguorid6dc3d42009-04-24 18:04:07 +00003271static void resume_all_vcpus(void);
3272static void pause_all_vcpus(void);
3273
bellard8a7ddc32004-03-31 19:00:16 +00003274void vm_start(void)
3275{
3276 if (!vm_running) {
3277 cpu_enable_ticks();
3278 vm_running = 1;
aliguori9781e042009-01-22 17:15:29 +00003279 vm_state_notify(1, 0);
thsefe75412007-08-24 01:36:32 +00003280 qemu_rearm_alarm_timer(alarm_timer);
aliguorid6dc3d42009-04-24 18:04:07 +00003281 resume_all_vcpus();
bellard8a7ddc32004-03-31 19:00:16 +00003282 }
3283}
3284
bellardbb0c6722004-06-20 12:37:32 +00003285/* reset/shutdown handler */
3286
3287typedef struct QEMUResetEntry {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003288 QTAILQ_ENTRY(QEMUResetEntry) entry;
bellardbb0c6722004-06-20 12:37:32 +00003289 QEMUResetHandler *func;
3290 void *opaque;
bellardbb0c6722004-06-20 12:37:32 +00003291} QEMUResetEntry;
3292
Blue Swirl72cf2d42009-09-12 07:36:22 +00003293static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
3294 QTAILQ_HEAD_INITIALIZER(reset_handlers);
bellardbb0c6722004-06-20 12:37:32 +00003295static int reset_requested;
3296static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00003297static int powerdown_requested;
aliguorie5689022009-04-24 18:03:54 +00003298static int debug_requested;
aliguori6e29f5d2009-04-24 18:04:02 +00003299static int vmstop_requested;
bellardbb0c6722004-06-20 12:37:32 +00003300
aurel32cf7a2fe2008-03-18 06:53:05 +00003301int qemu_shutdown_requested(void)
3302{
3303 int r = shutdown_requested;
3304 shutdown_requested = 0;
3305 return r;
3306}
3307
3308int qemu_reset_requested(void)
3309{
3310 int r = reset_requested;
3311 reset_requested = 0;
3312 return r;
3313}
3314
3315int qemu_powerdown_requested(void)
3316{
3317 int r = powerdown_requested;
3318 powerdown_requested = 0;
3319 return r;
3320}
3321
aliguorie5689022009-04-24 18:03:54 +00003322static int qemu_debug_requested(void)
3323{
3324 int r = debug_requested;
3325 debug_requested = 0;
3326 return r;
3327}
3328
aliguori6e29f5d2009-04-24 18:04:02 +00003329static int qemu_vmstop_requested(void)
3330{
3331 int r = vmstop_requested;
3332 vmstop_requested = 0;
3333 return r;
3334}
3335
3336static void do_vm_stop(int reason)
3337{
3338 if (vm_running) {
3339 cpu_disable_ticks();
3340 vm_running = 0;
aliguorid6dc3d42009-04-24 18:04:07 +00003341 pause_all_vcpus();
aliguori6e29f5d2009-04-24 18:04:02 +00003342 vm_state_notify(0, reason);
3343 }
3344}
3345
Jan Kiszkaa08d4362009-06-27 09:25:07 +02003346void qemu_register_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003347{
Jan Kiszka55ddfe82009-07-02 00:19:02 +02003348 QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
bellardbb0c6722004-06-20 12:37:32 +00003349
bellardbb0c6722004-06-20 12:37:32 +00003350 re->func = func;
3351 re->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003352 QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
bellardbb0c6722004-06-20 12:37:32 +00003353}
3354
Jan Kiszkadda9b292009-07-02 00:19:02 +02003355void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003356{
3357 QEMUResetEntry *re;
3358
Blue Swirl72cf2d42009-09-12 07:36:22 +00003359 QTAILQ_FOREACH(re, &reset_handlers, entry) {
Jan Kiszkadda9b292009-07-02 00:19:02 +02003360 if (re->func == func && re->opaque == opaque) {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003361 QTAILQ_REMOVE(&reset_handlers, re, entry);
Jan Kiszkadda9b292009-07-02 00:19:02 +02003362 qemu_free(re);
3363 return;
3364 }
3365 }
3366}
3367
3368void qemu_system_reset(void)
3369{
3370 QEMUResetEntry *re, *nre;
3371
3372 /* reset all devices */
Blue Swirl72cf2d42009-09-12 07:36:22 +00003373 QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
bellardbb0c6722004-06-20 12:37:32 +00003374 re->func(re->opaque);
3375 }
3376}
3377
3378void qemu_system_reset_request(void)
3379{
bellardd1beab82006-10-02 19:44:22 +00003380 if (no_reboot) {
3381 shutdown_requested = 1;
3382 } else {
3383 reset_requested = 1;
3384 }
aliguorid9f75a42009-04-24 18:03:11 +00003385 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003386}
3387
3388void qemu_system_shutdown_request(void)
3389{
3390 shutdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003391 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003392}
3393
bellard34751872005-07-02 14:31:34 +00003394void qemu_system_powerdown_request(void)
3395{
3396 powerdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003397 qemu_notify_event();
3398}
3399
aliguorid6dc3d42009-04-24 18:04:07 +00003400#ifdef CONFIG_IOTHREAD
3401static void qemu_system_vmstop_request(int reason)
aliguorid9f75a42009-04-24 18:03:11 +00003402{
aliguorid6dc3d42009-04-24 18:04:07 +00003403 vmstop_requested = reason;
3404 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003405}
aliguorid6dc3d42009-04-24 18:04:07 +00003406#endif
bellardbb0c6722004-06-20 12:37:32 +00003407
aliguori50317c72009-04-24 18:03:29 +00003408#ifndef _WIN32
3409static int io_thread_fd = -1;
3410
3411static void qemu_event_increment(void)
3412{
3413 static const char byte = 0;
3414
3415 if (io_thread_fd == -1)
3416 return;
3417
3418 write(io_thread_fd, &byte, sizeof(byte));
3419}
3420
3421static void qemu_event_read(void *opaque)
3422{
3423 int fd = (unsigned long)opaque;
3424 ssize_t len;
3425
3426 /* Drain the notify pipe */
3427 do {
3428 char buffer[512];
3429 len = read(fd, buffer, sizeof(buffer));
3430 } while ((len == -1 && errno == EINTR) || len > 0);
3431}
3432
3433static int qemu_event_init(void)
3434{
3435 int err;
3436 int fds[2];
3437
3438 err = pipe(fds);
3439 if (err == -1)
3440 return -errno;
3441
3442 err = fcntl_setfl(fds[0], O_NONBLOCK);
3443 if (err < 0)
3444 goto fail;
3445
3446 err = fcntl_setfl(fds[1], O_NONBLOCK);
3447 if (err < 0)
3448 goto fail;
3449
3450 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
3451 (void *)(unsigned long)fds[0]);
3452
3453 io_thread_fd = fds[1];
Jan Kiszkaa7e21212009-04-29 18:38:28 +00003454 return 0;
3455
aliguori50317c72009-04-24 18:03:29 +00003456fail:
3457 close(fds[0]);
3458 close(fds[1]);
3459 return err;
3460}
3461#else
3462HANDLE qemu_event_handle;
3463
3464static void dummy_event_handler(void *opaque)
3465{
3466}
3467
3468static int qemu_event_init(void)
3469{
3470 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
3471 if (!qemu_event_handle) {
Blue Swirl20889d42009-09-27 20:03:56 +00003472 fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
aliguori50317c72009-04-24 18:03:29 +00003473 return -1;
3474 }
3475 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
3476 return 0;
3477}
3478
3479static void qemu_event_increment(void)
3480{
malcde1c90c2009-09-27 14:38:18 +04003481 if (!SetEvent(qemu_event_handle)) {
Blue Swirl20889d42009-09-27 20:03:56 +00003482 fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
malcde1c90c2009-09-27 14:38:18 +04003483 GetLastError());
3484 exit (1);
3485 }
aliguori50317c72009-04-24 18:03:29 +00003486}
3487#endif
3488
aliguorid6dc3d42009-04-24 18:04:07 +00003489static int cpu_can_run(CPUState *env)
3490{
3491 if (env->stop)
3492 return 0;
3493 if (env->stopped)
3494 return 0;
3495 return 1;
3496}
3497
3498#ifndef CONFIG_IOTHREAD
aliguori3fcf7b62009-04-24 18:03:25 +00003499static int qemu_init_main_loop(void)
3500{
aliguori50317c72009-04-24 18:03:29 +00003501 return qemu_event_init();
aliguori3fcf7b62009-04-24 18:03:25 +00003502}
3503
aliguori0bf46a42009-04-24 18:03:41 +00003504void qemu_init_vcpu(void *_env)
3505{
3506 CPUState *env = _env;
3507
3508 if (kvm_enabled())
3509 kvm_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003510 env->nr_cores = smp_cores;
3511 env->nr_threads = smp_threads;
aliguori0bf46a42009-04-24 18:03:41 +00003512 return;
3513}
3514
aliguori8edac962009-04-24 18:03:45 +00003515int qemu_cpu_self(void *env)
3516{
3517 return 1;
3518}
3519
aliguorid6dc3d42009-04-24 18:04:07 +00003520static void resume_all_vcpus(void)
3521{
3522}
3523
3524static void pause_all_vcpus(void)
3525{
3526}
3527
aliguori8edac962009-04-24 18:03:45 +00003528void qemu_cpu_kick(void *env)
3529{
3530 return;
3531}
3532
aliguorid6dc3d42009-04-24 18:04:07 +00003533void qemu_notify_event(void)
3534{
3535 CPUState *env = cpu_single_env;
3536
3537 if (env) {
3538 cpu_exit(env);
Anthony Liguori4a1418e2009-08-10 17:07:24 -05003539 }
aliguorid6dc3d42009-04-24 18:04:07 +00003540}
3541
aliguori48708522009-04-24 18:03:49 +00003542#define qemu_mutex_lock_iothread() do { } while (0)
3543#define qemu_mutex_unlock_iothread() do { } while (0)
3544
aliguori6e29f5d2009-04-24 18:04:02 +00003545void vm_stop(int reason)
3546{
3547 do_vm_stop(reason);
3548}
3549
aliguorid6dc3d42009-04-24 18:04:07 +00003550#else /* CONFIG_IOTHREAD */
3551
3552#include "qemu-thread.h"
3553
3554QemuMutex qemu_global_mutex;
3555static QemuMutex qemu_fair_mutex;
3556
3557static QemuThread io_thread;
3558
3559static QemuThread *tcg_cpu_thread;
3560static QemuCond *tcg_halt_cond;
3561
3562static int qemu_system_ready;
3563/* cpu creation */
3564static QemuCond qemu_cpu_cond;
3565/* system init */
3566static QemuCond qemu_system_cond;
3567static QemuCond qemu_pause_cond;
3568
3569static void block_io_signals(void);
3570static void unblock_io_signals(void);
3571static int tcg_has_work(void);
3572
3573static int qemu_init_main_loop(void)
3574{
3575 int ret;
3576
3577 ret = qemu_event_init();
3578 if (ret)
3579 return ret;
3580
3581 qemu_cond_init(&qemu_pause_cond);
3582 qemu_mutex_init(&qemu_fair_mutex);
3583 qemu_mutex_init(&qemu_global_mutex);
3584 qemu_mutex_lock(&qemu_global_mutex);
3585
3586 unblock_io_signals();
3587 qemu_thread_self(&io_thread);
3588
3589 return 0;
3590}
3591
3592static void qemu_wait_io_event(CPUState *env)
3593{
3594 while (!tcg_has_work())
3595 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
3596
3597 qemu_mutex_unlock(&qemu_global_mutex);
3598
3599 /*
3600 * Users of qemu_global_mutex can be starved, having no chance
3601 * to acquire it since this path will get to it first.
3602 * So use another lock to provide fairness.
3603 */
3604 qemu_mutex_lock(&qemu_fair_mutex);
3605 qemu_mutex_unlock(&qemu_fair_mutex);
3606
3607 qemu_mutex_lock(&qemu_global_mutex);
3608 if (env->stop) {
3609 env->stop = 0;
3610 env->stopped = 1;
3611 qemu_cond_signal(&qemu_pause_cond);
3612 }
3613}
3614
3615static int qemu_cpu_exec(CPUState *env);
3616
3617static void *kvm_cpu_thread_fn(void *arg)
3618{
3619 CPUState *env = arg;
3620
3621 block_io_signals();
3622 qemu_thread_self(env->thread);
Jean-Christophe DUBOIS321c1cb2009-09-02 23:59:04 +02003623 if (kvm_enabled())
3624 kvm_init_vcpu(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003625
3626 /* signal CPU creation */
3627 qemu_mutex_lock(&qemu_global_mutex);
3628 env->created = 1;
3629 qemu_cond_signal(&qemu_cpu_cond);
3630
3631 /* and wait for machine initialization */
3632 while (!qemu_system_ready)
3633 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3634
3635 while (1) {
3636 if (cpu_can_run(env))
3637 qemu_cpu_exec(env);
Anthony Liguori1c3173b2009-09-10 08:45:43 -05003638 qemu_wait_io_event(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003639 }
3640
3641 return NULL;
3642}
3643
3644static void tcg_cpu_exec(void);
3645
3646static void *tcg_cpu_thread_fn(void *arg)
3647{
3648 CPUState *env = arg;
3649
3650 block_io_signals();
3651 qemu_thread_self(env->thread);
3652
3653 /* signal CPU creation */
3654 qemu_mutex_lock(&qemu_global_mutex);
3655 for (env = first_cpu; env != NULL; env = env->next_cpu)
3656 env->created = 1;
3657 qemu_cond_signal(&qemu_cpu_cond);
3658
3659 /* and wait for machine initialization */
3660 while (!qemu_system_ready)
3661 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3662
3663 while (1) {
3664 tcg_cpu_exec();
3665 qemu_wait_io_event(cur_cpu);
3666 }
3667
3668 return NULL;
3669}
3670
3671void qemu_cpu_kick(void *_env)
3672{
3673 CPUState *env = _env;
3674 qemu_cond_broadcast(env->halt_cond);
3675 if (kvm_enabled())
3676 qemu_thread_signal(env->thread, SIGUSR1);
3677}
3678
Glauber Costae5bc2012009-09-28 15:27:44 -03003679int qemu_cpu_self(void *_env)
aliguorid6dc3d42009-04-24 18:04:07 +00003680{
Glauber Costae5bc2012009-09-28 15:27:44 -03003681 CPUState *env = _env;
3682 QemuThread this;
3683
3684 qemu_thread_self(&this);
3685
3686 return qemu_thread_equal(&this, env->thread);
aliguorid6dc3d42009-04-24 18:04:07 +00003687}
3688
3689static void cpu_signal(int sig)
3690{
3691 if (cpu_single_env)
3692 cpu_exit(cpu_single_env);
3693}
3694
3695static void block_io_signals(void)
3696{
3697 sigset_t set;
3698 struct sigaction sigact;
3699
3700 sigemptyset(&set);
3701 sigaddset(&set, SIGUSR2);
3702 sigaddset(&set, SIGIO);
3703 sigaddset(&set, SIGALRM);
3704 pthread_sigmask(SIG_BLOCK, &set, NULL);
3705
3706 sigemptyset(&set);
3707 sigaddset(&set, SIGUSR1);
3708 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3709
3710 memset(&sigact, 0, sizeof(sigact));
3711 sigact.sa_handler = cpu_signal;
3712 sigaction(SIGUSR1, &sigact, NULL);
3713}
3714
3715static void unblock_io_signals(void)
3716{
3717 sigset_t set;
3718
3719 sigemptyset(&set);
3720 sigaddset(&set, SIGUSR2);
3721 sigaddset(&set, SIGIO);
3722 sigaddset(&set, SIGALRM);
3723 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3724
3725 sigemptyset(&set);
3726 sigaddset(&set, SIGUSR1);
3727 pthread_sigmask(SIG_BLOCK, &set, NULL);
3728}
3729
3730static void qemu_signal_lock(unsigned int msecs)
3731{
3732 qemu_mutex_lock(&qemu_fair_mutex);
3733
3734 while (qemu_mutex_trylock(&qemu_global_mutex)) {
3735 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
3736 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
3737 break;
3738 }
3739 qemu_mutex_unlock(&qemu_fair_mutex);
3740}
3741
3742static void qemu_mutex_lock_iothread(void)
3743{
3744 if (kvm_enabled()) {
3745 qemu_mutex_lock(&qemu_fair_mutex);
3746 qemu_mutex_lock(&qemu_global_mutex);
3747 qemu_mutex_unlock(&qemu_fair_mutex);
3748 } else
3749 qemu_signal_lock(100);
3750}
3751
3752static void qemu_mutex_unlock_iothread(void)
3753{
3754 qemu_mutex_unlock(&qemu_global_mutex);
3755}
3756
3757static int all_vcpus_paused(void)
3758{
3759 CPUState *penv = first_cpu;
3760
3761 while (penv) {
3762 if (!penv->stopped)
3763 return 0;
3764 penv = (CPUState *)penv->next_cpu;
3765 }
3766
3767 return 1;
3768}
3769
3770static void pause_all_vcpus(void)
3771{
3772 CPUState *penv = first_cpu;
3773
3774 while (penv) {
3775 penv->stop = 1;
3776 qemu_thread_signal(penv->thread, SIGUSR1);
3777 qemu_cpu_kick(penv);
3778 penv = (CPUState *)penv->next_cpu;
3779 }
3780
3781 while (!all_vcpus_paused()) {
3782 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
3783 penv = first_cpu;
3784 while (penv) {
3785 qemu_thread_signal(penv->thread, SIGUSR1);
3786 penv = (CPUState *)penv->next_cpu;
3787 }
3788 }
3789}
3790
3791static void resume_all_vcpus(void)
3792{
3793 CPUState *penv = first_cpu;
3794
3795 while (penv) {
3796 penv->stop = 0;
3797 penv->stopped = 0;
3798 qemu_thread_signal(penv->thread, SIGUSR1);
3799 qemu_cpu_kick(penv);
3800 penv = (CPUState *)penv->next_cpu;
3801 }
3802}
3803
3804static void tcg_init_vcpu(void *_env)
3805{
3806 CPUState *env = _env;
3807 /* share a single thread for all cpus with TCG */
3808 if (!tcg_cpu_thread) {
3809 env->thread = qemu_mallocz(sizeof(QemuThread));
3810 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3811 qemu_cond_init(env->halt_cond);
3812 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
3813 while (env->created == 0)
3814 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3815 tcg_cpu_thread = env->thread;
3816 tcg_halt_cond = env->halt_cond;
3817 } else {
3818 env->thread = tcg_cpu_thread;
3819 env->halt_cond = tcg_halt_cond;
3820 }
3821}
3822
3823static void kvm_start_vcpu(CPUState *env)
3824{
aliguorid6dc3d42009-04-24 18:04:07 +00003825 env->thread = qemu_mallocz(sizeof(QemuThread));
3826 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3827 qemu_cond_init(env->halt_cond);
3828 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
3829 while (env->created == 0)
3830 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3831}
3832
3833void qemu_init_vcpu(void *_env)
3834{
3835 CPUState *env = _env;
3836
3837 if (kvm_enabled())
3838 kvm_start_vcpu(env);
3839 else
3840 tcg_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003841 env->nr_cores = smp_cores;
3842 env->nr_threads = smp_threads;
aliguorid6dc3d42009-04-24 18:04:07 +00003843}
3844
3845void qemu_notify_event(void)
3846{
3847 qemu_event_increment();
3848}
3849
3850void vm_stop(int reason)
3851{
3852 QemuThread me;
3853 qemu_thread_self(&me);
3854
3855 if (!qemu_thread_equal(&me, &io_thread)) {
3856 qemu_system_vmstop_request(reason);
3857 /*
3858 * FIXME: should not return to device code in case
3859 * vm_stop() has been requested.
3860 */
3861 if (cpu_single_env) {
3862 cpu_exit(cpu_single_env);
3863 cpu_single_env->stop = 1;
3864 }
3865 return;
3866 }
3867 do_vm_stop(reason);
3868}
3869
3870#endif
3871
3872
ths877cf882007-04-18 18:11:47 +00003873#ifdef _WIN32
blueswir169d64512008-12-07 19:30:18 +00003874static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003875{
3876 int ret, ret2, i;
bellardf3311102006-04-12 20:21:17 +00003877 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00003878
bellardf3311102006-04-12 20:21:17 +00003879
3880 /* XXX: need to suppress polling by better using win32 events */
3881 ret = 0;
3882 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
3883 ret |= pe->func(pe->opaque);
3884 }
thse6b1e552007-04-18 17:56:02 +00003885 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00003886 int err;
3887 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00003888
aliguori56f3a5d2008-10-31 18:07:17 +00003889 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
bellarda18e5242006-06-25 17:18:27 +00003890 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
3891 if (w->func[ret - WAIT_OBJECT_0])
3892 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00003893
ths5fafdf22007-09-16 21:08:06 +00003894 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00003895 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00003896
thse6b1e552007-04-18 17:56:02 +00003897 /* Check if event is signaled */
3898 ret2 = WaitForSingleObject(w->events[i], 0);
3899 if(ret2 == WAIT_OBJECT_0) {
3900 if (w->func[i])
3901 w->func[i](w->opaque[i]);
3902 } else if (ret2 == WAIT_TIMEOUT) {
3903 } else {
3904 err = GetLastError();
3905 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00003906 }
3907 }
bellarda18e5242006-06-25 17:18:27 +00003908 } else if (ret == WAIT_TIMEOUT) {
3909 } else {
3910 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00003911 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00003912 }
bellardf3311102006-04-12 20:21:17 +00003913 }
aliguori56f3a5d2008-10-31 18:07:17 +00003914
3915 *timeout = 0;
3916}
3917#else
blueswir169d64512008-12-07 19:30:18 +00003918static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003919{
3920}
bellardfd1dff42006-02-01 21:29:26 +00003921#endif
aliguori56f3a5d2008-10-31 18:07:17 +00003922
3923void main_loop_wait(int timeout)
3924{
3925 IOHandlerRecord *ioh;
3926 fd_set rfds, wfds, xfds;
3927 int ret, nfds;
3928 struct timeval tv;
3929
3930 qemu_bh_update_timeout(&timeout);
3931
3932 host_main_loop_wait(&timeout);
3933
bellardfd1dff42006-02-01 21:29:26 +00003934 /* poll any events */
3935 /* XXX: separate device handlers from system ones */
aliguori6abfbd72008-11-05 20:49:37 +00003936 nfds = -1;
bellardfd1dff42006-02-01 21:29:26 +00003937 FD_ZERO(&rfds);
3938 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00003939 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00003940 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00003941 if (ioh->deleted)
3942 continue;
bellardfd1dff42006-02-01 21:29:26 +00003943 if (ioh->fd_read &&
3944 (!ioh->fd_read_poll ||
3945 ioh->fd_read_poll(ioh->opaque) != 0)) {
3946 FD_SET(ioh->fd, &rfds);
3947 if (ioh->fd > nfds)
3948 nfds = ioh->fd;
3949 }
3950 if (ioh->fd_write) {
3951 FD_SET(ioh->fd, &wfds);
3952 if (ioh->fd > nfds)
3953 nfds = ioh->fd;
3954 }
3955 }
ths3b46e622007-09-17 08:09:54 +00003956
aliguori56f3a5d2008-10-31 18:07:17 +00003957 tv.tv_sec = timeout / 1000;
3958 tv.tv_usec = (timeout % 1000) * 1000;
3959
Jan Kiszkad918f232009-06-24 14:42:30 +02003960 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
3961
aliguori48708522009-04-24 18:03:49 +00003962 qemu_mutex_unlock_iothread();
bellarde0356492006-05-01 13:33:02 +00003963 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
aliguori48708522009-04-24 18:03:49 +00003964 qemu_mutex_lock_iothread();
bellardfd1dff42006-02-01 21:29:26 +00003965 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00003966 IOHandlerRecord **pioh;
3967
3968 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00003969 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003970 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00003971 }
ths6ab43fd2007-08-25 01:34:19 +00003972 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003973 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00003974 }
3975 }
thscafffd42007-02-28 21:59:44 +00003976
3977 /* remove deleted IO handlers */
3978 pioh = &first_io_handler;
3979 while (*pioh) {
3980 ioh = *pioh;
3981 if (ioh->deleted) {
3982 *pioh = ioh->next;
3983 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00003984 } else
thscafffd42007-02-28 21:59:44 +00003985 pioh = &ioh->next;
3986 }
bellardfd1dff42006-02-01 21:29:26 +00003987 }
Jan Kiszkad918f232009-06-24 14:42:30 +02003988
3989 slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
bellardc20709a2004-04-21 23:27:19 +00003990
aliguori50317c72009-04-24 18:03:29 +00003991 /* rearm timer, if not periodic */
3992 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
3993 alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
3994 qemu_rearm_alarm_timer(alarm_timer);
3995 }
3996
aliguori357c6922008-11-25 17:26:09 +00003997 /* vm time timers */
aliguorid6dc3d42009-04-24 18:04:07 +00003998 if (vm_running) {
3999 if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
Jan Kiszka0fdddf82009-09-15 13:36:04 +02004000 qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
4001 qemu_get_clock(vm_clock));
aliguorid6dc3d42009-04-24 18:04:07 +00004002 }
aliguori357c6922008-11-25 17:26:09 +00004003
4004 /* real time timers */
Jan Kiszka0fdddf82009-09-15 13:36:04 +02004005 qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
aliguori357c6922008-11-25 17:26:09 +00004006 qemu_get_clock(rt_clock));
4007
Jan Kiszka21d5d122009-09-15 13:36:04 +02004008 qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
4009 qemu_get_clock(host_clock));
4010
pbrook423f0742007-05-23 00:06:54 +00004011 /* Check bottom-halves last in case any of the earlier events triggered
4012 them. */
4013 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00004014
bellard5905b2e2004-08-01 21:53:26 +00004015}
4016
aliguori43b96852009-04-24 18:03:33 +00004017static int qemu_cpu_exec(CPUState *env)
bellard5905b2e2004-08-01 21:53:26 +00004018{
aliguori43b96852009-04-24 18:03:33 +00004019 int ret;
bellard89bfc102006-02-08 22:46:31 +00004020#ifdef CONFIG_PROFILER
4021 int64_t ti;
4022#endif
aliguori43b96852009-04-24 18:03:33 +00004023
4024#ifdef CONFIG_PROFILER
4025 ti = profile_getclock();
4026#endif
4027 if (use_icount) {
4028 int64_t count;
4029 int decr;
4030 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
4031 env->icount_decr.u16.low = 0;
4032 env->icount_extra = 0;
4033 count = qemu_next_deadline();
4034 count = (count + (1 << icount_time_shift) - 1)
4035 >> icount_time_shift;
4036 qemu_icount += count;
4037 decr = (count > 0xffff) ? 0xffff : count;
4038 count -= decr;
4039 env->icount_decr.u16.low = decr;
4040 env->icount_extra = count;
4041 }
4042 ret = cpu_exec(env);
4043#ifdef CONFIG_PROFILER
4044 qemu_time += profile_getclock() - ti;
4045#endif
4046 if (use_icount) {
4047 /* Fold pending instructions back into the
4048 instruction counter, and clear the interrupt flag. */
4049 qemu_icount -= (env->icount_decr.u16.low
4050 + env->icount_extra);
4051 env->icount_decr.u32 = 0;
4052 env->icount_extra = 0;
4053 }
4054 return ret;
4055}
4056
aliguorie6e35b12009-04-24 18:03:57 +00004057static void tcg_cpu_exec(void)
4058{
aliguorid6dc3d42009-04-24 18:04:07 +00004059 int ret = 0;
aliguorie6e35b12009-04-24 18:03:57 +00004060
4061 if (next_cpu == NULL)
4062 next_cpu = first_cpu;
4063 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
4064 CPUState *env = cur_cpu = next_cpu;
4065
4066 if (!vm_running)
4067 break;
4068 if (timer_alarm_pending) {
4069 timer_alarm_pending = 0;
4070 break;
4071 }
aliguorid6dc3d42009-04-24 18:04:07 +00004072 if (cpu_can_run(env))
4073 ret = qemu_cpu_exec(env);
aliguorie6e35b12009-04-24 18:03:57 +00004074 if (ret == EXCP_DEBUG) {
4075 gdb_set_stop_cpu(env);
4076 debug_requested = 1;
4077 break;
4078 }
4079 }
4080}
4081
aliguori43b96852009-04-24 18:03:33 +00004082static int cpu_has_work(CPUState *env)
4083{
aliguorid6dc3d42009-04-24 18:04:07 +00004084 if (env->stop)
4085 return 1;
4086 if (env->stopped)
4087 return 0;
aliguori43b96852009-04-24 18:03:33 +00004088 if (!env->halted)
4089 return 1;
4090 if (qemu_cpu_has_work(env))
4091 return 1;
4092 return 0;
4093}
4094
4095static int tcg_has_work(void)
4096{
bellard6a00d602005-11-21 23:25:50 +00004097 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00004098
aliguori43b96852009-04-24 18:03:33 +00004099 for (env = first_cpu; env != NULL; env = env->next_cpu)
4100 if (cpu_has_work(env))
4101 return 1;
4102 return 0;
4103}
bellard15a76442005-11-23 21:01:03 +00004104
aliguori43b96852009-04-24 18:03:33 +00004105static int qemu_calculate_timeout(void)
4106{
Luiz Capitulinob3198202009-06-09 18:24:57 -03004107#ifndef CONFIG_IOTHREAD
aliguori43b96852009-04-24 18:03:33 +00004108 int timeout;
bellard15a76442005-11-23 21:01:03 +00004109
aliguori43b96852009-04-24 18:03:33 +00004110 if (!vm_running)
4111 timeout = 5000;
4112 else if (tcg_has_work())
4113 timeout = 0;
4114 else if (!use_icount)
4115 timeout = 5000;
4116 else {
4117 /* XXX: use timeout computed from timers */
4118 int64_t add;
4119 int64_t delta;
4120 /* Advance virtual time to the next event. */
4121 if (use_icount == 1) {
4122 /* When not using an adaptive execution frequency
4123 we tend to get badly out of sync with real time,
4124 so just delay for a reasonable amount of time. */
4125 delta = 0;
bellard5905b2e2004-08-01 21:53:26 +00004126 } else {
aliguori43b96852009-04-24 18:03:33 +00004127 delta = cpu_get_icount() - cpu_get_clock();
bellard5905b2e2004-08-01 21:53:26 +00004128 }
aliguori43b96852009-04-24 18:03:33 +00004129 if (delta > 0) {
4130 /* If virtual time is ahead of real time then just
4131 wait for IO. */
4132 timeout = (delta / 1000000) + 1;
4133 } else {
4134 /* Wait for either IO to occur or the next
4135 timer event. */
4136 add = qemu_next_deadline();
4137 /* We advance the timer before checking for IO.
4138 Limit the amount we advance so that early IO
4139 activity won't get the guest too far ahead. */
4140 if (add > 10000000)
4141 add = 10000000;
4142 delta += add;
4143 add = (add + (1 << icount_time_shift) - 1)
4144 >> icount_time_shift;
4145 qemu_icount += add;
4146 timeout = delta / 1000000;
4147 if (timeout < 0)
4148 timeout = 0;
4149 }
bellardb4608c02003-06-27 17:34:32 +00004150 }
aliguori43b96852009-04-24 18:03:33 +00004151
4152 return timeout;
Luiz Capitulinob3198202009-06-09 18:24:57 -03004153#else /* CONFIG_IOTHREAD */
4154 return 1000;
4155#endif
aliguori43b96852009-04-24 18:03:33 +00004156}
4157
4158static int vm_can_run(void)
4159{
4160 if (powerdown_requested)
4161 return 0;
4162 if (reset_requested)
4163 return 0;
4164 if (shutdown_requested)
4165 return 0;
aliguorie5689022009-04-24 18:03:54 +00004166 if (debug_requested)
4167 return 0;
aliguori43b96852009-04-24 18:03:33 +00004168 return 1;
4169}
4170
Blue Swirld9c32312009-08-09 08:42:19 +00004171qemu_irq qemu_system_powerdown;
4172
aliguori43b96852009-04-24 18:03:33 +00004173static void main_loop(void)
4174{
aliguori6e29f5d2009-04-24 18:04:02 +00004175 int r;
aliguori43b96852009-04-24 18:03:33 +00004176
aliguorid6dc3d42009-04-24 18:04:07 +00004177#ifdef CONFIG_IOTHREAD
4178 qemu_system_ready = 1;
4179 qemu_cond_broadcast(&qemu_system_cond);
4180#endif
4181
aliguori6e29f5d2009-04-24 18:04:02 +00004182 for (;;) {
aliguorie6e35b12009-04-24 18:03:57 +00004183 do {
4184#ifdef CONFIG_PROFILER
4185 int64_t ti;
4186#endif
aliguorid6dc3d42009-04-24 18:04:07 +00004187#ifndef CONFIG_IOTHREAD
aliguorie6e35b12009-04-24 18:03:57 +00004188 tcg_cpu_exec();
aliguorid6dc3d42009-04-24 18:04:07 +00004189#endif
aliguori43b96852009-04-24 18:03:33 +00004190#ifdef CONFIG_PROFILER
4191 ti = profile_getclock();
4192#endif
4193 main_loop_wait(qemu_calculate_timeout());
4194#ifdef CONFIG_PROFILER
4195 dev_time += profile_getclock() - ti;
4196#endif
aliguorie5689022009-04-24 18:03:54 +00004197 } while (vm_can_run());
aliguori43b96852009-04-24 18:03:33 +00004198
aliguorie5689022009-04-24 18:03:54 +00004199 if (qemu_debug_requested())
aliguori43b96852009-04-24 18:03:33 +00004200 vm_stop(EXCP_DEBUG);
aliguori43b96852009-04-24 18:03:33 +00004201 if (qemu_shutdown_requested()) {
4202 if (no_shutdown) {
4203 vm_stop(0);
4204 no_shutdown = 0;
4205 } else
4206 break;
4207 }
aliguorid6dc3d42009-04-24 18:04:07 +00004208 if (qemu_reset_requested()) {
4209 pause_all_vcpus();
aliguori43b96852009-04-24 18:03:33 +00004210 qemu_system_reset();
aliguorid6dc3d42009-04-24 18:04:07 +00004211 resume_all_vcpus();
4212 }
Blue Swirld9c32312009-08-09 08:42:19 +00004213 if (qemu_powerdown_requested()) {
4214 qemu_irq_raise(qemu_system_powerdown);
4215 }
aliguori6e29f5d2009-04-24 18:04:02 +00004216 if ((r = qemu_vmstop_requested()))
4217 vm_stop(r);
aliguori43b96852009-04-24 18:03:33 +00004218 }
aliguorid6dc3d42009-04-24 18:04:07 +00004219 pause_all_vcpus();
bellardb4608c02003-06-27 17:34:32 +00004220}
4221
pbrook9bd7e6d2009-04-07 22:58:45 +00004222static void version(void)
4223{
pbrook4a19f1e2009-04-07 23:17:49 +00004224 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
pbrook9bd7e6d2009-04-07 22:58:45 +00004225}
4226
ths15f82202007-06-29 23:26:08 +00004227static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00004228{
pbrook9bd7e6d2009-04-07 22:58:45 +00004229 version();
4230 printf("usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00004231 "\n"
bellarda20dd502003-09-30 21:07:02 +00004232 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00004233 "\n"
blueswir15824d652009-03-28 06:44:27 +00004234#define DEF(option, opt_arg, opt_enum, opt_help) \
4235 opt_help
4236#define DEFHEADING(text) stringify(text) "\n"
4237#include "qemu-options.h"
4238#undef DEF
4239#undef DEFHEADING
4240#undef GEN_DOCS
bellard0824d6f2003-06-24 13:42:40 +00004241 "\n"
bellard82c643f2004-07-14 17:28:13 +00004242 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00004243 "ctrl-alt-f toggle full screen\n"
4244 "ctrl-alt-n switch to virtual console 'n'\n"
4245 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00004246 "\n"
4247 "When using -nographic, press 'ctrl-a h' to get some help.\n"
4248 ,
bellard0db63472003-10-27 21:37:46 +00004249 "qemu",
bellarda00bad72004-05-22 21:39:06 +00004250 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00004251#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00004252 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00004253 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00004254#endif
bellard6e44ba72004-01-18 21:56:49 +00004255 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00004256 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00004257 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00004258}
4259
bellardcd6f1162004-05-13 22:02:20 +00004260#define HAS_ARG 0x0001
4261
4262enum {
blueswir15824d652009-03-28 06:44:27 +00004263#define DEF(option, opt_arg, opt_enum, opt_help) \
4264 opt_enum,
4265#define DEFHEADING(text)
4266#include "qemu-options.h"
4267#undef DEF
4268#undef DEFHEADING
4269#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004270};
4271
4272typedef struct QEMUOption {
4273 const char *name;
4274 int flags;
4275 int index;
4276} QEMUOption;
4277
blueswir1dbed7e42008-10-01 19:38:09 +00004278static const QEMUOption qemu_options[] = {
bellardcd6f1162004-05-13 22:02:20 +00004279 { "h", 0, QEMU_OPTION_h },
blueswir15824d652009-03-28 06:44:27 +00004280#define DEF(option, opt_arg, opt_enum, opt_help) \
4281 { option, opt_arg, opt_enum },
4282#define DEFHEADING(text)
4283#include "qemu-options.h"
4284#undef DEF
4285#undef DEFHEADING
4286#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004287 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00004288};
4289
bellard1d14ffa2005-10-30 18:58:22 +00004290#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00004291struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00004292#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00004293#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00004294 {
4295 "pcspk",
4296 "PC speaker",
4297 0,
4298 1,
4299 { .init_isa = pcspk_audio_init }
4300 },
4301#endif
malc4c9b53e2009-01-09 10:46:34 +00004302
4303#ifdef CONFIG_SB16
bellard6a36d842005-12-18 20:34:32 +00004304 {
4305 "sb16",
4306 "Creative Sound Blaster 16",
4307 0,
4308 1,
4309 { .init_isa = SB16_init }
4310 },
malc4c9b53e2009-01-09 10:46:34 +00004311#endif
bellard6a36d842005-12-18 20:34:32 +00004312
malccc53d262008-06-13 10:48:22 +00004313#ifdef CONFIG_CS4231A
4314 {
4315 "cs4231a",
4316 "CS4231A",
4317 0,
4318 1,
4319 { .init_isa = cs4231a_init }
4320 },
4321#endif
4322
bellard6a36d842005-12-18 20:34:32 +00004323#ifdef CONFIG_ADLIB
4324 {
4325 "adlib",
4326#ifdef HAS_YMF262
4327 "Yamaha YMF262 (OPL3)",
4328#else
4329 "Yamaha YM3812 (OPL2)",
4330#endif
4331 0,
4332 1,
4333 { .init_isa = Adlib_init }
4334 },
4335#endif
4336
4337#ifdef CONFIG_GUS
4338 {
4339 "gus",
4340 "Gravis Ultrasound GF1",
4341 0,
4342 1,
4343 { .init_isa = GUS_init }
4344 },
4345#endif
4346
malc4c9b53e2009-01-09 10:46:34 +00004347#ifdef CONFIG_AC97
balroge5c9a132008-01-14 04:27:55 +00004348 {
4349 "ac97",
4350 "Intel 82801AA AC97 Audio",
4351 0,
4352 0,
4353 { .init_pci = ac97_init }
4354 },
malc4c9b53e2009-01-09 10:46:34 +00004355#endif
balroge5c9a132008-01-14 04:27:55 +00004356
malc4c9b53e2009-01-09 10:46:34 +00004357#ifdef CONFIG_ES1370
bellard6a36d842005-12-18 20:34:32 +00004358 {
4359 "es1370",
4360 "ENSONIQ AudioPCI ES1370",
4361 0,
4362 0,
4363 { .init_pci = es1370_init }
4364 },
balrogb00052e2007-04-30 02:22:06 +00004365#endif
bellard6a36d842005-12-18 20:34:32 +00004366
malc4c9b53e2009-01-09 10:46:34 +00004367#endif /* HAS_AUDIO_CHOICE */
4368
bellard6a36d842005-12-18 20:34:32 +00004369 { NULL, NULL, 0, 0, { NULL } }
4370};
4371
bellard1d14ffa2005-10-30 18:58:22 +00004372static void select_soundhw (const char *optarg)
4373{
bellard6a36d842005-12-18 20:34:32 +00004374 struct soundhw *c;
4375
bellard1d14ffa2005-10-30 18:58:22 +00004376 if (*optarg == '?') {
4377 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00004378
bellard1d14ffa2005-10-30 18:58:22 +00004379 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00004380 for (c = soundhw; c->name; ++c) {
4381 printf ("%-11s %s\n", c->name, c->descr);
4382 }
4383 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00004384 exit (*optarg != '?');
4385 }
4386 else {
bellard6a36d842005-12-18 20:34:32 +00004387 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00004388 const char *p;
4389 char *e;
4390 int bad_card = 0;
4391
bellard6a36d842005-12-18 20:34:32 +00004392 if (!strcmp (optarg, "all")) {
4393 for (c = soundhw; c->name; ++c) {
4394 c->enabled = 1;
4395 }
4396 return;
4397 }
bellard1d14ffa2005-10-30 18:58:22 +00004398
bellard6a36d842005-12-18 20:34:32 +00004399 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00004400 while (*p) {
4401 e = strchr (p, ',');
4402 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00004403
4404 for (c = soundhw; c->name; ++c) {
malcb3d6fb42009-09-06 06:49:03 +04004405 if (!strncmp (c->name, p, l) && !c->name[l]) {
bellard6a36d842005-12-18 20:34:32 +00004406 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00004407 break;
4408 }
4409 }
bellard6a36d842005-12-18 20:34:32 +00004410
4411 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00004412 if (l > 80) {
4413 fprintf (stderr,
4414 "Unknown sound card name (too big to show)\n");
4415 }
4416 else {
4417 fprintf (stderr, "Unknown sound card name `%.*s'\n",
4418 (int) l, p);
4419 }
4420 bad_card = 1;
4421 }
4422 p += l + (e != NULL);
4423 }
4424
4425 if (bad_card)
4426 goto show_valid_cards;
4427 }
4428}
4429#endif
4430
malc3893c122008-09-28 00:42:05 +00004431static void select_vgahw (const char *p)
4432{
4433 const char *opts;
4434
Zachary Amsden86176752009-07-30 00:15:02 -10004435 vga_interface_type = VGA_NONE;
malc3893c122008-09-28 00:42:05 +00004436 if (strstart(p, "std", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004437 vga_interface_type = VGA_STD;
malc3893c122008-09-28 00:42:05 +00004438 } else if (strstart(p, "cirrus", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004439 vga_interface_type = VGA_CIRRUS;
malc3893c122008-09-28 00:42:05 +00004440 } else if (strstart(p, "vmware", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004441 vga_interface_type = VGA_VMWARE;
aliguori94909d92009-04-22 15:19:53 +00004442 } else if (strstart(p, "xenfb", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004443 vga_interface_type = VGA_XENFB;
aliguori28b85ed2009-04-22 15:19:48 +00004444 } else if (!strstart(p, "none", &opts)) {
malc3893c122008-09-28 00:42:05 +00004445 invalid_vga:
4446 fprintf(stderr, "Unknown vga type: %s\n", p);
4447 exit(1);
4448 }
malccb5a7aa2008-09-28 00:42:12 +00004449 while (*opts) {
4450 const char *nextopt;
4451
4452 if (strstart(opts, ",retrace=", &nextopt)) {
4453 opts = nextopt;
4454 if (strstart(opts, "dumb", &nextopt))
4455 vga_retrace_method = VGA_RETRACE_DUMB;
4456 else if (strstart(opts, "precise", &nextopt))
4457 vga_retrace_method = VGA_RETRACE_PRECISE;
4458 else goto invalid_vga;
4459 } else goto invalid_vga;
4460 opts = nextopt;
4461 }
malc3893c122008-09-28 00:42:05 +00004462}
4463
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004464#ifdef TARGET_I386
4465static int balloon_parse(const char *arg)
4466{
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004467 QemuOpts *opts;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004468
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004469 if (strcmp(arg, "none") == 0) {
4470 return 0;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004471 }
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004472
4473 if (!strncmp(arg, "virtio", 6)) {
4474 if (arg[6] == ',') {
4475 /* have params -> parse them */
4476 opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL);
4477 if (!opts)
4478 return -1;
4479 } else {
4480 /* create empty opts */
4481 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
4482 }
4483 qemu_opt_set(opts, "driver", "virtio-balloon-pci");
4484 return 0;
4485 }
4486
4487 return -1;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004488}
4489#endif
4490
bellard3587d7e2006-06-26 20:03:44 +00004491#ifdef _WIN32
4492static BOOL WINAPI qemu_ctrl_handler(DWORD type)
4493{
4494 exit(STATUS_CONTROL_C_EXIT);
4495 return TRUE;
4496}
4497#endif
4498
aliguoric4be29f2009-04-17 18:58:14 +00004499int qemu_uuid_parse(const char *str, uint8_t *uuid)
blueswir18fcb1b92008-09-18 18:29:08 +00004500{
4501 int ret;
4502
4503 if(strlen(str) != 36)
4504 return -1;
4505
4506 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
4507 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
4508 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
4509
4510 if(ret != 16)
4511 return -1;
4512
aliguorib6f6e3d2009-04-17 18:59:56 +00004513#ifdef TARGET_I386
4514 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
4515#endif
4516
blueswir18fcb1b92008-09-18 18:29:08 +00004517 return 0;
4518}
4519
bellard7c9d8e02005-11-15 22:16:05 +00004520#define MAX_NET_CLIENTS 32
bellardc20709a2004-04-21 23:27:19 +00004521
aliguori5b08fc12008-08-21 20:08:03 +00004522#ifndef _WIN32
4523
4524static void termsig_handler(int signal)
4525{
4526 qemu_system_shutdown_request();
4527}
4528
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004529static void sigchld_handler(int signal)
4530{
4531 waitpid(-1, NULL, WNOHANG);
4532}
4533
4534static void sighandler_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00004535{
4536 struct sigaction act;
4537
4538 memset(&act, 0, sizeof(act));
4539 act.sa_handler = termsig_handler;
4540 sigaction(SIGINT, &act, NULL);
4541 sigaction(SIGHUP, &act, NULL);
4542 sigaction(SIGTERM, &act, NULL);
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004543
4544 act.sa_handler = sigchld_handler;
4545 act.sa_flags = SA_NOCLDSTOP;
4546 sigaction(SIGCHLD, &act, NULL);
aliguori5b08fc12008-08-21 20:08:03 +00004547}
4548
4549#endif
4550
Paul Brook5cea8592009-05-30 00:52:44 +01004551#ifdef _WIN32
4552/* Look for support files in the same directory as the executable. */
4553static char *find_datadir(const char *argv0)
4554{
4555 char *p;
4556 char buf[MAX_PATH];
4557 DWORD len;
4558
4559 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
4560 if (len == 0) {
Blue Swirlc5947802009-06-09 20:51:21 +03004561 return NULL;
Paul Brook5cea8592009-05-30 00:52:44 +01004562 }
4563
4564 buf[len] = 0;
4565 p = buf + len - 1;
4566 while (p != buf && *p != '\\')
4567 p--;
4568 *p = 0;
4569 if (access(buf, R_OK) == 0) {
4570 return qemu_strdup(buf);
4571 }
4572 return NULL;
4573}
4574#else /* !_WIN32 */
4575
4576/* Find a likely location for support files using the location of the binary.
4577 For installed binaries this will be "$bindir/../share/qemu". When
4578 running from the build tree this will be "$bindir/../pc-bios". */
4579#define SHARE_SUFFIX "/share/qemu"
4580#define BUILD_SUFFIX "/pc-bios"
4581static char *find_datadir(const char *argv0)
4582{
4583 char *dir;
4584 char *p = NULL;
4585 char *res;
Paul Brook5cea8592009-05-30 00:52:44 +01004586 char buf[PATH_MAX];
Blue Swirl3a417592009-06-09 19:12:21 +00004587 size_t max_len;
Paul Brook5cea8592009-05-30 00:52:44 +01004588
4589#if defined(__linux__)
4590 {
4591 int len;
4592 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
4593 if (len > 0) {
4594 buf[len] = 0;
4595 p = buf;
4596 }
4597 }
4598#elif defined(__FreeBSD__)
4599 {
4600 int len;
4601 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
4602 if (len > 0) {
4603 buf[len] = 0;
4604 p = buf;
4605 }
4606 }
4607#endif
4608 /* If we don't have any way of figuring out the actual executable
4609 location then try argv[0]. */
4610 if (!p) {
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004611 p = realpath(argv0, buf);
Paul Brook5cea8592009-05-30 00:52:44 +01004612 if (!p) {
4613 return NULL;
4614 }
4615 }
4616 dir = dirname(p);
4617 dir = dirname(dir);
4618
Blue Swirl3a417592009-06-09 19:12:21 +00004619 max_len = strlen(dir) +
4620 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
4621 res = qemu_mallocz(max_len);
4622 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004623 if (access(res, R_OK)) {
Blue Swirl3a417592009-06-09 19:12:21 +00004624 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004625 if (access(res, R_OK)) {
4626 qemu_free(res);
4627 res = NULL;
4628 }
4629 }
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004630
Paul Brook5cea8592009-05-30 00:52:44 +01004631 return res;
4632}
4633#undef SHARE_SUFFIX
4634#undef BUILD_SUFFIX
4635#endif
4636
4637char *qemu_find_file(int type, const char *name)
4638{
4639 int len;
4640 const char *subdir;
4641 char *buf;
4642
4643 /* If name contains path separators then try it as a straight path. */
4644 if ((strchr(name, '/') || strchr(name, '\\'))
4645 && access(name, R_OK) == 0) {
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +02004646 return qemu_strdup(name);
Paul Brook5cea8592009-05-30 00:52:44 +01004647 }
4648 switch (type) {
4649 case QEMU_FILE_TYPE_BIOS:
4650 subdir = "";
4651 break;
4652 case QEMU_FILE_TYPE_KEYMAP:
4653 subdir = "keymaps/";
4654 break;
4655 default:
4656 abort();
4657 }
4658 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
4659 buf = qemu_mallocz(len);
Blue Swirl3a417592009-06-09 19:12:21 +00004660 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
Paul Brook5cea8592009-05-30 00:52:44 +01004661 if (access(buf, R_OK)) {
4662 qemu_free(buf);
4663 return NULL;
4664 }
4665 return buf;
4666}
4667
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004668static int device_init_func(QemuOpts *opts, void *opaque)
4669{
4670 DeviceState *dev;
4671
4672 dev = qdev_device_add(opts);
4673 if (!dev)
4674 return -1;
4675 return 0;
4676}
4677
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004678struct device_config {
4679 enum {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004680 DEV_USB, /* -usbdevice */
4681 DEV_BT, /* -bt */
4682 } type;
4683 const char *cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004684 QTAILQ_ENTRY(device_config) next;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004685};
Blue Swirl72cf2d42009-09-12 07:36:22 +00004686QTAILQ_HEAD(, device_config) device_configs = QTAILQ_HEAD_INITIALIZER(device_configs);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004687
4688static void add_device_config(int type, const char *cmdline)
4689{
4690 struct device_config *conf;
4691
4692 conf = qemu_mallocz(sizeof(*conf));
4693 conf->type = type;
4694 conf->cmdline = cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004695 QTAILQ_INSERT_TAIL(&device_configs, conf, next);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004696}
4697
4698static int foreach_device_config(int type, int (*func)(const char *cmdline))
4699{
4700 struct device_config *conf;
4701 int rc;
4702
Blue Swirl72cf2d42009-09-12 07:36:22 +00004703 QTAILQ_FOREACH(conf, &device_configs, next) {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004704 if (conf->type != type)
4705 continue;
4706 rc = func(conf->cmdline);
4707 if (0 != rc)
4708 return rc;
4709 }
4710 return 0;
4711}
4712
malc902b3d52008-12-10 19:18:40 +00004713int main(int argc, char **argv, char **envp)
bellard0824d6f2003-06-24 13:42:40 +00004714{
aliguori59030a82009-04-05 18:43:41 +00004715 const char *gdbstub_dev = NULL;
j_mayer28c5af52007-11-11 01:50:45 +00004716 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00004717 int i;
j_mayer28c5af52007-11-11 01:50:45 +00004718 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00004719 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00004720 const char *kernel_filename, *kernel_cmdline;
Jan Kiszkaef3adf62009-07-02 00:19:02 +02004721 char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
aliguori3023f332009-01-16 19:04:14 +00004722 DisplayState *ds;
aliguori7d957bd2009-01-15 22:14:11 +00004723 DisplayChangeListener *dcl;
bellard46d47672004-11-16 01:45:27 +00004724 int cyls, heads, secs, translation;
pbrookfd5f3932008-03-26 20:55:43 +00004725 const char *net_clients[MAX_NET_CLIENTS];
bellard7c9d8e02005-11-15 22:16:05 +00004726 int nb_net_clients;
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004727 QemuOpts *hda_opts = NULL, *opts;
bellardcd6f1162004-05-13 22:02:20 +00004728 int optind;
4729 const char *r, *optarg;
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02004730 CharDriverState *monitor_hds[MAX_MONITOR_DEVICES];
4731 const char *monitor_devices[MAX_MONITOR_DEVICES];
4732 int monitor_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00004733 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00004734 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00004735 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00004736 int parallel_device_index;
aliguori9ede2fd2009-01-15 20:05:25 +00004737 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
4738 int virtio_console_index;
bellardd63d3072004-10-03 13:29:03 +00004739 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00004740 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00004741 const char *cpu_model;
blueswir1b9e82a52009-04-05 18:03:31 +00004742#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00004743 int fds[2];
blueswir1b9e82a52009-04-05 18:03:31 +00004744#endif
bellard26a5f132008-05-28 12:30:31 +00004745 int tb_size;
ths93815bc2007-03-19 15:58:31 +00004746 const char *pid_file = NULL;
aliguori5bb79102008-10-13 03:12:02 +00004747 const char *incoming = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004748#ifndef _WIN32
aliguori54042bc2009-02-27 22:16:47 +00004749 int fd = 0;
4750 struct passwd *pwd = NULL;
aliguori08585322009-02-27 22:09:45 +00004751 const char *chroot_dir = NULL;
4752 const char *run_as = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004753#endif
aliguori268a3622009-04-21 22:30:27 +00004754 CPUState *env;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004755 int show_vnc_port = 0;
bellard0bd48852005-11-11 00:00:47 +00004756
Gerd Hoffmannac7531e2009-08-14 10:36:06 +02004757 qemu_errors_to_file(stderr);
malc902b3d52008-12-10 19:18:40 +00004758 qemu_cache_utils_init(envp);
4759
Blue Swirl72cf2d42009-09-12 07:36:22 +00004760 QLIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00004761#ifndef _WIN32
4762 {
4763 struct sigaction act;
4764 sigfillset(&act.sa_mask);
4765 act.sa_flags = 0;
4766 act.sa_handler = SIG_IGN;
4767 sigaction(SIGPIPE, &act, NULL);
4768 }
bellard3587d7e2006-06-26 20:03:44 +00004769#else
4770 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00004771 /* Note: cpu_interrupt() is currently not SMP safe, so we force
4772 QEMU to run on a single CPU */
4773 {
4774 HANDLE h;
4775 DWORD mask, smask;
4776 int i;
4777 h = GetCurrentProcess();
4778 if (GetProcessAffinityMask(h, &mask, &smask)) {
4779 for(i = 0; i < 32; i++) {
4780 if (mask & (1 << i))
4781 break;
4782 }
4783 if (i != 32) {
4784 mask = 1 << i;
4785 SetProcessAffinityMask(h, mask);
4786 }
4787 }
4788 }
bellard67b915a2004-03-31 23:37:16 +00004789#endif
bellardbe995c22006-06-25 16:25:21 +00004790
Anthony Liguorif80f9ec2009-05-20 18:38:09 -05004791 module_call_init(MODULE_INIT_MACHINE);
Anthony Liguori0c257432009-05-21 20:41:01 -05004792 machine = find_default_machine();
j_mayer94fc95c2007-03-05 19:44:02 +00004793 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00004794 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00004795 ram_size = 0;
bellard33e39632003-07-06 17:15:21 +00004796 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00004797 kernel_filename = NULL;
4798 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00004799 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00004800 translation = BIOS_ATA_TRANSLATION_AUTO;
bellardc4b1fcc2004-03-14 21:44:30 +00004801
aurel32c75a8232008-05-04 00:50:34 +00004802 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00004803 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004804 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00004805 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004806
aliguori8290edd2009-02-27 20:14:29 +00004807 parallel_devices[0] = "vc:80Cx24C";
bellard6508fe52005-01-15 12:02:56 +00004808 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004809 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00004810 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004811
aliguori1b8fc812009-02-27 20:01:39 +00004812 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
aliguori9ede2fd2009-01-15 20:05:25 +00004813 virtio_consoles[i] = NULL;
4814 virtio_console_index = 0;
4815
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02004816 monitor_devices[0] = "vc:80Cx24C";
4817 for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
4818 monitor_devices[i] = NULL;
4819 }
4820 monitor_device_index = 0;
4821
aliguori268a3622009-04-21 22:30:27 +00004822 for (i = 0; i < MAX_NODES; i++) {
4823 node_mem[i] = 0;
4824 node_cpumask[i] = 0;
4825 }
4826
bellard7c9d8e02005-11-15 22:16:05 +00004827 nb_net_clients = 0;
aliguori268a3622009-04-21 22:30:27 +00004828 nb_numa_nodes = 0;
bellard7c9d8e02005-11-15 22:16:05 +00004829 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00004830
bellard26a5f132008-05-28 12:30:31 +00004831 tb_size = 0;
blueswir141bd6392008-10-05 09:56:21 +00004832 autostart= 1;
4833
bellardcd6f1162004-05-13 22:02:20 +00004834 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00004835 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00004836 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00004837 break;
bellardcd6f1162004-05-13 22:02:20 +00004838 r = argv[optind];
4839 if (r[0] != '-') {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004840 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00004841 } else {
4842 const QEMUOption *popt;
4843
4844 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00004845 /* Treat --foo the same as -foo. */
4846 if (r[1] == '-')
4847 r++;
bellardcd6f1162004-05-13 22:02:20 +00004848 popt = qemu_options;
4849 for(;;) {
4850 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00004851 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00004852 argv[0], r);
4853 exit(1);
4854 }
4855 if (!strcmp(popt->name, r + 1))
4856 break;
4857 popt++;
4858 }
4859 if (popt->flags & HAS_ARG) {
4860 if (optind >= argc) {
4861 fprintf(stderr, "%s: option '%s' requires an argument\n",
4862 argv[0], r);
4863 exit(1);
4864 }
4865 optarg = argv[optind++];
4866 } else {
4867 optarg = NULL;
4868 }
4869
4870 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00004871 case QEMU_OPTION_M:
4872 machine = find_machine(optarg);
4873 if (!machine) {
4874 QEMUMachine *m;
4875 printf("Supported machines are:\n");
4876 for(m = first_machine; m != NULL; m = m->next) {
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01004877 if (m->alias)
4878 printf("%-10s %s (alias of %s)\n",
4879 m->alias, m->desc, m->name);
bellardcc1daa42005-06-05 14:49:17 +00004880 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00004881 m->name, m->desc,
Anthony Liguori0c257432009-05-21 20:41:01 -05004882 m->is_default ? " (default)" : "");
bellardcc1daa42005-06-05 14:49:17 +00004883 }
ths15f82202007-06-29 23:26:08 +00004884 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00004885 }
4886 break;
j_mayer94fc95c2007-03-05 19:44:02 +00004887 case QEMU_OPTION_cpu:
4888 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00004889 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00004890/* XXX: implement xxx_cpu_list for targets that still miss it */
4891#if defined(cpu_list)
4892 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00004893#endif
ths15f82202007-06-29 23:26:08 +00004894 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00004895 } else {
4896 cpu_model = optarg;
4897 }
4898 break;
bellardcd6f1162004-05-13 22:02:20 +00004899 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00004900 initrd_filename = optarg;
4901 break;
bellardcd6f1162004-05-13 22:02:20 +00004902 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00004903 if (cyls == 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004904 hda_opts = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00004905 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004906 hda_opts = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00004907 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00004908 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00004909 translation == BIOS_ATA_TRANSLATION_LBA ?
4910 ",trans=lba" :
4911 translation == BIOS_ATA_TRANSLATION_NONE ?
4912 ",trans=none" : "");
4913 break;
bellardcd6f1162004-05-13 22:02:20 +00004914 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00004915 case QEMU_OPTION_hdc:
4916 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00004917 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00004918 break;
thse4bcb142007-12-02 04:51:10 +00004919 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00004920 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00004921 break;
Gerd Hoffmannd058fe02009-07-31 12:25:36 +02004922 case QEMU_OPTION_set:
4923 if (qemu_set_option(optarg) != 0)
4924 exit(1);
4925 break;
balrog3e3d5812007-04-30 02:09:25 +00004926 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00004927 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00004928 break;
pbrooka1bb27b2007-04-06 16:49:48 +00004929 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00004930 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00004931 break;
j_mayer86f55662007-04-24 06:52:59 +00004932 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00004933 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00004934 break;
bellardcd6f1162004-05-13 22:02:20 +00004935 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00004936 snapshot = 1;
4937 break;
bellardcd6f1162004-05-13 22:02:20 +00004938 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00004939 {
bellard330d0412003-07-26 18:11:40 +00004940 const char *p;
4941 p = optarg;
4942 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004943 if (cyls < 1 || cyls > 16383)
4944 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004945 if (*p != ',')
4946 goto chs_fail;
4947 p++;
4948 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004949 if (heads < 1 || heads > 16)
4950 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004951 if (*p != ',')
4952 goto chs_fail;
4953 p++;
4954 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004955 if (secs < 1 || secs > 63)
4956 goto chs_fail;
4957 if (*p == ',') {
4958 p++;
4959 if (!strcmp(p, "none"))
4960 translation = BIOS_ATA_TRANSLATION_NONE;
4961 else if (!strcmp(p, "lba"))
4962 translation = BIOS_ATA_TRANSLATION_LBA;
4963 else if (!strcmp(p, "auto"))
4964 translation = BIOS_ATA_TRANSLATION_AUTO;
4965 else
4966 goto chs_fail;
4967 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00004968 chs_fail:
bellard46d47672004-11-16 01:45:27 +00004969 fprintf(stderr, "qemu: invalid physical CHS format\n");
4970 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00004971 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004972 if (hda_opts != NULL) {
4973 char num[16];
4974 snprintf(num, sizeof(num), "%d", cyls);
4975 qemu_opt_set(hda_opts, "cyls", num);
4976 snprintf(num, sizeof(num), "%d", heads);
4977 qemu_opt_set(hda_opts, "heads", num);
4978 snprintf(num, sizeof(num), "%d", secs);
4979 qemu_opt_set(hda_opts, "secs", num);
4980 if (translation == BIOS_ATA_TRANSLATION_LBA)
4981 qemu_opt_set(hda_opts, "trans", "lba");
4982 if (translation == BIOS_ATA_TRANSLATION_NONE)
4983 qemu_opt_set(hda_opts, "trans", "none");
4984 }
bellard330d0412003-07-26 18:11:40 +00004985 }
4986 break;
aliguori268a3622009-04-21 22:30:27 +00004987 case QEMU_OPTION_numa:
4988 if (nb_numa_nodes >= MAX_NODES) {
4989 fprintf(stderr, "qemu: too many NUMA nodes\n");
4990 exit(1);
4991 }
4992 numa_add(optarg);
4993 break;
bellardcd6f1162004-05-13 22:02:20 +00004994 case QEMU_OPTION_nographic:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004995 display_type = DT_NOGRAPHIC;
bellarda20dd502003-09-30 21:07:02 +00004996 break;
balrog4d3b6f62008-02-10 16:33:14 +00004997#ifdef CONFIG_CURSES
4998 case QEMU_OPTION_curses:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004999 display_type = DT_CURSES;
balrog4d3b6f62008-02-10 16:33:14 +00005000 break;
5001#endif
balroga171fe32007-04-30 01:48:07 +00005002 case QEMU_OPTION_portrait:
5003 graphic_rotate = 1;
5004 break;
bellardcd6f1162004-05-13 22:02:20 +00005005 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00005006 kernel_filename = optarg;
5007 break;
bellardcd6f1162004-05-13 22:02:20 +00005008 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00005009 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00005010 break;
bellardcd6f1162004-05-13 22:02:20 +00005011 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00005012 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00005013 break;
bellardcd6f1162004-05-13 22:02:20 +00005014 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00005015 {
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005016 static const char * const params[] = {
Jan Kiszka95387492009-07-02 00:19:02 +02005017 "order", "once", "menu", NULL
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005018 };
5019 char buf[sizeof(boot_devices)];
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005020 char *standard_boot_devices;
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005021 int legacy = 0;
5022
5023 if (!strchr(optarg, '=')) {
5024 legacy = 1;
5025 pstrcpy(buf, sizeof(buf), optarg);
5026 } else if (check_params(buf, sizeof(buf), params, optarg) < 0) {
5027 fprintf(stderr,
5028 "qemu: unknown boot parameter '%s' in '%s'\n",
5029 buf, optarg);
5030 exit(1);
5031 }
5032
5033 if (legacy ||
5034 get_param_value(buf, sizeof(buf), "order", optarg)) {
5035 boot_devices_bitmap = parse_bootdevices(buf);
5036 pstrcpy(boot_devices, sizeof(boot_devices), buf);
j_mayer28c5af52007-11-11 01:50:45 +00005037 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005038 if (!legacy) {
5039 if (get_param_value(buf, sizeof(buf),
5040 "once", optarg)) {
5041 boot_devices_bitmap |= parse_bootdevices(buf);
5042 standard_boot_devices = qemu_strdup(boot_devices);
5043 pstrcpy(boot_devices, sizeof(boot_devices), buf);
5044 qemu_register_reset(restore_boot_devices,
5045 standard_boot_devices);
5046 }
Jan Kiszka95387492009-07-02 00:19:02 +02005047 if (get_param_value(buf, sizeof(buf),
5048 "menu", optarg)) {
5049 if (!strcmp(buf, "on")) {
5050 boot_menu = 1;
5051 } else if (!strcmp(buf, "off")) {
5052 boot_menu = 0;
5053 } else {
5054 fprintf(stderr,
5055 "qemu: invalid option value '%s'\n",
5056 buf);
5057 exit(1);
5058 }
5059 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005060 }
bellard36b486b2003-11-11 13:36:08 +00005061 }
5062 break;
bellardcd6f1162004-05-13 22:02:20 +00005063 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00005064 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00005065 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00005066 break;
bellard52ca8d62006-06-14 16:03:05 +00005067#ifdef TARGET_I386
5068 case QEMU_OPTION_no_fd_bootchk:
5069 fd_bootchk = 0;
5070 break;
5071#endif
bellard7c9d8e02005-11-15 22:16:05 +00005072 case QEMU_OPTION_net:
5073 if (nb_net_clients >= MAX_NET_CLIENTS) {
5074 fprintf(stderr, "qemu: too many network clients\n");
bellardc4b1fcc2004-03-14 21:44:30 +00005075 exit(1);
5076 }
pbrookfd5f3932008-03-26 20:55:43 +00005077 net_clients[nb_net_clients] = optarg;
bellard7c9d8e02005-11-15 22:16:05 +00005078 nb_net_clients++;
bellard702c6512004-04-02 21:21:32 +00005079 break;
bellardc7f74642004-08-24 21:57:12 +00005080#ifdef CONFIG_SLIRP
5081 case QEMU_OPTION_tftp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005082 legacy_tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00005083 break;
ths47d5d012007-02-20 00:05:08 +00005084 case QEMU_OPTION_bootp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005085 legacy_bootp_filename = optarg;
ths47d5d012007-02-20 00:05:08 +00005086 break;
bellardc94c8d62004-09-13 21:37:34 +00005087#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00005088 case QEMU_OPTION_smb:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005089 net_slirp_smb(optarg);
bellard9d728e82004-09-05 23:09:03 +00005090 break;
bellardc94c8d62004-09-13 21:37:34 +00005091#endif
bellard9bf05442004-08-25 22:12:49 +00005092 case QEMU_OPTION_redir:
Jan Kiszkaf3546de2009-06-24 14:42:28 +02005093 net_slirp_redir(optarg);
bellard9bf05442004-08-25 22:12:49 +00005094 break;
bellardc7f74642004-08-24 21:57:12 +00005095#endif
balrogdc72ac12008-11-09 00:04:26 +00005096 case QEMU_OPTION_bt:
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005097 add_device_config(DEV_BT, optarg);
balrogdc72ac12008-11-09 00:04:26 +00005098 break;
bellard1d14ffa2005-10-30 18:58:22 +00005099#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00005100 case QEMU_OPTION_audio_help:
5101 AUD_help ();
5102 exit (0);
5103 break;
5104 case QEMU_OPTION_soundhw:
5105 select_soundhw (optarg);
5106 break;
5107#endif
bellardcd6f1162004-05-13 22:02:20 +00005108 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00005109 help(0);
bellardcd6f1162004-05-13 22:02:20 +00005110 break;
pbrook9bd7e6d2009-04-07 22:58:45 +00005111 case QEMU_OPTION_version:
5112 version();
5113 exit(0);
5114 break;
aurel3200f82b82008-04-27 21:12:55 +00005115 case QEMU_OPTION_m: {
5116 uint64_t value;
5117 char *ptr;
5118
5119 value = strtoul(optarg, &ptr, 10);
5120 switch (*ptr) {
5121 case 0: case 'M': case 'm':
5122 value <<= 20;
5123 break;
5124 case 'G': case 'g':
5125 value <<= 30;
5126 break;
5127 default:
5128 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00005129 exit(1);
5130 }
aurel3200f82b82008-04-27 21:12:55 +00005131
5132 /* On 32-bit hosts, QEMU is limited by virtual address space */
Anthony Liguori4a1418e2009-08-10 17:07:24 -05005133 if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
aurel3200f82b82008-04-27 21:12:55 +00005134 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
5135 exit(1);
5136 }
Anthony Liguoric227f092009-10-01 16:12:16 -05005137 if (value != (uint64_t)(ram_addr_t)value) {
aurel3200f82b82008-04-27 21:12:55 +00005138 fprintf(stderr, "qemu: ram size too large\n");
5139 exit(1);
5140 }
5141 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00005142 break;
aurel3200f82b82008-04-27 21:12:55 +00005143 }
bellardcd6f1162004-05-13 22:02:20 +00005144 case QEMU_OPTION_d:
5145 {
5146 int mask;
blueswir1c7cd6a32008-10-02 18:27:46 +00005147 const CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00005148
bellardcd6f1162004-05-13 22:02:20 +00005149 mask = cpu_str_to_log_mask(optarg);
5150 if (!mask) {
5151 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00005152 for(item = cpu_log_items; item->mask != 0; item++) {
5153 printf("%-10s %s\n", item->name, item->help);
5154 }
5155 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00005156 }
5157 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00005158 }
bellardcd6f1162004-05-13 22:02:20 +00005159 break;
bellardcd6f1162004-05-13 22:02:20 +00005160 case QEMU_OPTION_s:
aliguori59030a82009-04-05 18:43:41 +00005161 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
bellardcd6f1162004-05-13 22:02:20 +00005162 break;
aliguori59030a82009-04-05 18:43:41 +00005163 case QEMU_OPTION_gdb:
5164 gdbstub_dev = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005165 break;
bellardcd6f1162004-05-13 22:02:20 +00005166 case QEMU_OPTION_L:
Paul Brook5cea8592009-05-30 00:52:44 +01005167 data_dir = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005168 break;
j_mayer1192dad2007-10-05 13:08:35 +00005169 case QEMU_OPTION_bios:
5170 bios_name = optarg;
5171 break;
aurel321b530a62009-04-05 20:08:59 +00005172 case QEMU_OPTION_singlestep:
5173 singlestep = 1;
5174 break;
bellardcd6f1162004-05-13 22:02:20 +00005175 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00005176 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00005177 break;
blueswir15824d652009-03-28 06:44:27 +00005178#ifndef _WIN32
bellard3d11d0e2004-12-12 16:56:30 +00005179 case QEMU_OPTION_k:
5180 keyboard_layout = optarg;
5181 break;
blueswir15824d652009-03-28 06:44:27 +00005182#endif
bellardee22c2f2004-06-03 12:49:50 +00005183 case QEMU_OPTION_localtime:
5184 rtc_utc = 0;
5185 break;
malc3893c122008-09-28 00:42:05 +00005186 case QEMU_OPTION_vga:
5187 select_vgahw (optarg);
bellard1bfe8562004-07-08 21:17:50 +00005188 break;
blueswir15824d652009-03-28 06:44:27 +00005189#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00005190 case QEMU_OPTION_g:
5191 {
5192 const char *p;
5193 int w, h, depth;
5194 p = optarg;
5195 w = strtol(p, (char **)&p, 10);
5196 if (w <= 0) {
5197 graphic_error:
5198 fprintf(stderr, "qemu: invalid resolution or depth\n");
5199 exit(1);
5200 }
5201 if (*p != 'x')
5202 goto graphic_error;
5203 p++;
5204 h = strtol(p, (char **)&p, 10);
5205 if (h <= 0)
5206 goto graphic_error;
5207 if (*p == 'x') {
5208 p++;
5209 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00005210 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00005211 depth != 24 && depth != 32)
5212 goto graphic_error;
5213 } else if (*p == '\0') {
5214 depth = graphic_depth;
5215 } else {
5216 goto graphic_error;
5217 }
ths3b46e622007-09-17 08:09:54 +00005218
bellarde9b137c2004-06-21 16:46:10 +00005219 graphic_width = w;
5220 graphic_height = h;
5221 graphic_depth = depth;
5222 }
5223 break;
blueswir15824d652009-03-28 06:44:27 +00005224#endif
ths20d8a3e2007-02-18 17:04:49 +00005225 case QEMU_OPTION_echr:
5226 {
5227 char *r;
5228 term_escape_char = strtol(optarg, &r, 0);
5229 if (r == optarg)
5230 printf("Bad argument to echr\n");
5231 break;
5232 }
bellard82c643f2004-07-14 17:28:13 +00005233 case QEMU_OPTION_monitor:
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005234 if (monitor_device_index >= MAX_MONITOR_DEVICES) {
5235 fprintf(stderr, "qemu: too many monitor devices\n");
5236 exit(1);
5237 }
5238 monitor_devices[monitor_device_index] = optarg;
5239 monitor_device_index++;
bellard82c643f2004-07-14 17:28:13 +00005240 break;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005241 case QEMU_OPTION_chardev:
5242 opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
5243 if (!opts) {
5244 fprintf(stderr, "parse error: %s\n", optarg);
5245 exit(1);
5246 }
Mark McLoughlin3df04ac2009-09-23 11:24:05 +01005247 if (qemu_chr_open_opts(opts, NULL) == NULL) {
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005248 exit(1);
5249 }
5250 break;
bellard82c643f2004-07-14 17:28:13 +00005251 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00005252 if (serial_device_index >= MAX_SERIAL_PORTS) {
5253 fprintf(stderr, "qemu: too many serial ports\n");
5254 exit(1);
5255 }
pbrookfd5f3932008-03-26 20:55:43 +00005256 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00005257 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00005258 break;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005259 case QEMU_OPTION_watchdog:
Markus Armbruster09aaa162009-08-21 10:31:34 +02005260 if (watchdog) {
5261 fprintf(stderr,
5262 "qemu: only one watchdog option may be given\n");
5263 return 1;
5264 }
5265 watchdog = optarg;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005266 break;
5267 case QEMU_OPTION_watchdog_action:
5268 if (select_watchdog_action(optarg) == -1) {
5269 fprintf(stderr, "Unknown -watchdog-action parameter\n");
5270 exit(1);
5271 }
5272 break;
aliguori51ecf132009-01-15 20:06:40 +00005273 case QEMU_OPTION_virtiocon:
5274 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
5275 fprintf(stderr, "qemu: too many virtio consoles\n");
5276 exit(1);
5277 }
5278 virtio_consoles[virtio_console_index] = optarg;
5279 virtio_console_index++;
5280 break;
bellard6508fe52005-01-15 12:02:56 +00005281 case QEMU_OPTION_parallel:
5282 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
5283 fprintf(stderr, "qemu: too many parallel ports\n");
5284 exit(1);
5285 }
pbrookfd5f3932008-03-26 20:55:43 +00005286 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00005287 parallel_device_index++;
5288 break;
bellardd63d3072004-10-03 13:29:03 +00005289 case QEMU_OPTION_loadvm:
5290 loadvm = optarg;
5291 break;
5292 case QEMU_OPTION_full_screen:
5293 full_screen = 1;
5294 break;
ths667acca2006-12-11 02:08:05 +00005295#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00005296 case QEMU_OPTION_no_frame:
5297 no_frame = 1;
5298 break;
ths3780e192007-06-21 21:08:02 +00005299 case QEMU_OPTION_alt_grab:
5300 alt_grab = 1;
5301 break;
ths667acca2006-12-11 02:08:05 +00005302 case QEMU_OPTION_no_quit:
5303 no_quit = 1;
5304 break;
aliguori7d957bd2009-01-15 22:14:11 +00005305 case QEMU_OPTION_sdl:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005306 display_type = DT_SDL;
aliguori7d957bd2009-01-15 22:14:11 +00005307 break;
ths667acca2006-12-11 02:08:05 +00005308#endif
bellardf7cce892004-12-08 22:21:25 +00005309 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00005310 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00005311 break;
bellarda09db212005-04-30 16:10:35 +00005312#ifdef TARGET_I386
5313 case QEMU_OPTION_win2k_hack:
5314 win2k_install_hack = 1;
5315 break;
aliguori73822ec2009-01-15 20:11:34 +00005316 case QEMU_OPTION_rtc_td_hack:
5317 rtc_td_hack = 1;
5318 break;
aliguori8a92ea22009-02-27 20:12:36 +00005319 case QEMU_OPTION_acpitable:
5320 if(acpi_table_add(optarg) < 0) {
5321 fprintf(stderr, "Wrong acpi table provided\n");
5322 exit(1);
5323 }
5324 break;
aliguorib6f6e3d2009-04-17 18:59:56 +00005325 case QEMU_OPTION_smbios:
5326 if(smbios_entry_add(optarg) < 0) {
5327 fprintf(stderr, "Wrong smbios provided\n");
5328 exit(1);
5329 }
5330 break;
bellarda09db212005-04-30 16:10:35 +00005331#endif
aliguori7ba1e612008-11-05 16:04:33 +00005332#ifdef CONFIG_KVM
5333 case QEMU_OPTION_enable_kvm:
5334 kvm_allowed = 1;
aliguori7ba1e612008-11-05 16:04:33 +00005335 break;
5336#endif
bellardbb36d472005-11-05 14:22:28 +00005337 case QEMU_OPTION_usb:
5338 usb_enabled = 1;
5339 break;
bellarda594cfb2005-11-06 16:13:29 +00005340 case QEMU_OPTION_usbdevice:
5341 usb_enabled = 1;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005342 add_device_config(DEV_USB, optarg);
5343 break;
5344 case QEMU_OPTION_device:
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005345 opts = qemu_opts_parse(&qemu_device_opts, optarg, "driver");
5346 if (!opts) {
5347 fprintf(stderr, "parse error: %s\n", optarg);
5348 exit(1);
5349 }
bellarda594cfb2005-11-06 16:13:29 +00005350 break;
bellard6a00d602005-11-21 23:25:50 +00005351 case QEMU_OPTION_smp:
Andre Przywaradc6b1c02009-08-19 15:42:40 +02005352 smp_parse(optarg);
aliguorib2097002008-10-07 20:39:39 +00005353 if (smp_cpus < 1) {
bellard6a00d602005-11-21 23:25:50 +00005354 fprintf(stderr, "Invalid number of CPUs\n");
5355 exit(1);
5356 }
Jes Sorensen6be68d72009-07-23 17:03:42 +02005357 if (max_cpus < smp_cpus) {
5358 fprintf(stderr, "maxcpus must be equal to or greater than "
5359 "smp\n");
5360 exit(1);
5361 }
5362 if (max_cpus > 255) {
5363 fprintf(stderr, "Unsupported number of maxcpus\n");
5364 exit(1);
5365 }
bellard6a00d602005-11-21 23:25:50 +00005366 break;
bellard24236862006-04-30 21:28:36 +00005367 case QEMU_OPTION_vnc:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005368 display_type = DT_VNC;
ths73fc9742006-12-22 02:09:07 +00005369 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00005370 break;
blueswir15824d652009-03-28 06:44:27 +00005371#ifdef TARGET_I386
bellard6515b202006-05-03 22:02:44 +00005372 case QEMU_OPTION_no_acpi:
5373 acpi_enabled = 0;
5374 break;
aliguori16b29ae2008-12-17 23:28:44 +00005375 case QEMU_OPTION_no_hpet:
5376 no_hpet = 1;
5377 break;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02005378 case QEMU_OPTION_balloon:
5379 if (balloon_parse(optarg) < 0) {
5380 fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
5381 exit(1);
5382 }
Eduardo Habkostdf97b922009-06-10 16:34:08 -03005383 break;
blueswir15824d652009-03-28 06:44:27 +00005384#endif
bellardd1beab82006-10-02 19:44:22 +00005385 case QEMU_OPTION_no_reboot:
5386 no_reboot = 1;
5387 break;
aurel32b2f76162008-04-11 21:35:52 +00005388 case QEMU_OPTION_no_shutdown:
5389 no_shutdown = 1;
5390 break;
balrog9467cd42007-05-01 01:34:14 +00005391 case QEMU_OPTION_show_cursor:
5392 cursor_hide = 0;
5393 break;
blueswir18fcb1b92008-09-18 18:29:08 +00005394 case QEMU_OPTION_uuid:
5395 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
5396 fprintf(stderr, "Fail to parse UUID string."
5397 " Wrong format.\n");
5398 exit(1);
5399 }
5400 break;
blueswir15824d652009-03-28 06:44:27 +00005401#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005402 case QEMU_OPTION_daemonize:
5403 daemonize = 1;
5404 break;
blueswir15824d652009-03-28 06:44:27 +00005405#endif
ths9ae02552007-01-05 17:39:04 +00005406 case QEMU_OPTION_option_rom:
5407 if (nb_option_roms >= MAX_OPTION_ROMS) {
5408 fprintf(stderr, "Too many option ROMs\n");
5409 exit(1);
5410 }
5411 option_rom[nb_option_roms] = optarg;
5412 nb_option_roms++;
5413 break;
blueswir15824d652009-03-28 06:44:27 +00005414#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00005415 case QEMU_OPTION_semihosting:
5416 semihosting_enabled = 1;
5417 break;
blueswir15824d652009-03-28 06:44:27 +00005418#endif
thsc35734b2007-03-19 15:17:08 +00005419 case QEMU_OPTION_name:
Andi Kleen18894652009-07-02 09:34:17 +02005420 qemu_name = qemu_strdup(optarg);
5421 {
5422 char *p = strchr(qemu_name, ',');
5423 if (p != NULL) {
5424 *p++ = 0;
5425 if (strncmp(p, "process=", 8)) {
5426 fprintf(stderr, "Unknown subargument %s to -name", p);
5427 exit(1);
5428 }
5429 p += 8;
5430 set_proc_name(p);
5431 }
5432 }
thsc35734b2007-03-19 15:17:08 +00005433 break;
blueswir195efd112008-12-24 20:26:14 +00005434#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +00005435 case QEMU_OPTION_prom_env:
5436 if (nb_prom_envs >= MAX_PROM_ENVS) {
5437 fprintf(stderr, "Too many prom variables\n");
5438 exit(1);
5439 }
5440 prom_envs[nb_prom_envs] = optarg;
5441 nb_prom_envs++;
5442 break;
5443#endif
balrog2b8f2d42007-07-27 22:08:46 +00005444#ifdef TARGET_ARM
5445 case QEMU_OPTION_old_param:
5446 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00005447 break;
balrog2b8f2d42007-07-27 22:08:46 +00005448#endif
thsf3dcfad2007-08-24 01:26:02 +00005449 case QEMU_OPTION_clock:
5450 configure_alarms(optarg);
5451 break;
bellard7e0af5d02007-11-07 16:24:33 +00005452 case QEMU_OPTION_startdate:
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005453 configure_rtc_date_offset(optarg, 1);
5454 break;
5455 case QEMU_OPTION_rtc:
5456 opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
5457 if (!opts) {
5458 fprintf(stderr, "parse error: %s\n", optarg);
5459 exit(1);
bellard7e0af5d02007-11-07 16:24:33 +00005460 }
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005461 configure_rtc(opts);
bellard7e0af5d02007-11-07 16:24:33 +00005462 break;
bellard26a5f132008-05-28 12:30:31 +00005463 case QEMU_OPTION_tb_size:
5464 tb_size = strtol(optarg, NULL, 0);
5465 if (tb_size < 0)
5466 tb_size = 0;
5467 break;
pbrook2e70f6e2008-06-29 01:03:05 +00005468 case QEMU_OPTION_icount:
5469 use_icount = 1;
5470 if (strcmp(optarg, "auto") == 0) {
5471 icount_time_shift = -1;
5472 } else {
5473 icount_time_shift = strtol(optarg, NULL, 0);
5474 }
5475 break;
aliguori5bb79102008-10-13 03:12:02 +00005476 case QEMU_OPTION_incoming:
5477 incoming = optarg;
5478 break;
blueswir15824d652009-03-28 06:44:27 +00005479#ifndef _WIN32
aliguori08585322009-02-27 22:09:45 +00005480 case QEMU_OPTION_chroot:
5481 chroot_dir = optarg;
5482 break;
5483 case QEMU_OPTION_runas:
5484 run_as = optarg;
5485 break;
blueswir15824d652009-03-28 06:44:27 +00005486#endif
aliguorie37630c2009-04-22 15:19:10 +00005487#ifdef CONFIG_XEN
5488 case QEMU_OPTION_xen_domid:
5489 xen_domid = atoi(optarg);
5490 break;
5491 case QEMU_OPTION_xen_create:
5492 xen_mode = XEN_CREATE;
5493 break;
5494 case QEMU_OPTION_xen_attach:
5495 xen_mode = XEN_ATTACH;
5496 break;
5497#endif
bellardcd6f1162004-05-13 22:02:20 +00005498 }
bellard0824d6f2003-06-24 13:42:40 +00005499 }
5500 }
bellard330d0412003-07-26 18:11:40 +00005501
Paul Brook5cea8592009-05-30 00:52:44 +01005502 /* If no data_dir is specified then try to find it relative to the
5503 executable path. */
5504 if (!data_dir) {
5505 data_dir = find_datadir(argv[0]);
5506 }
5507 /* If all else fails use the install patch specified when building. */
5508 if (!data_dir) {
5509 data_dir = CONFIG_QEMU_SHAREDIR;
5510 }
5511
Jes Sorensen6be68d72009-07-23 17:03:42 +02005512 /*
5513 * Default to max_cpus = smp_cpus, in case the user doesn't
5514 * specify a max_cpus value.
5515 */
5516 if (!max_cpus)
5517 max_cpus = smp_cpus;
5518
balrog3d878ca2008-10-28 10:59:59 +00005519 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
aliguorib2097002008-10-07 20:39:39 +00005520 if (smp_cpus > machine->max_cpus) {
5521 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
5522 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
5523 machine->max_cpus);
5524 exit(1);
5525 }
5526
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005527 if (display_type == DT_NOGRAPHIC) {
aliguoribc0129d2008-08-01 15:12:34 +00005528 if (serial_device_index == 0)
5529 serial_devices[0] = "stdio";
5530 if (parallel_device_index == 0)
5531 parallel_devices[0] = "null";
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005532 if (strncmp(monitor_devices[0], "vc", 2) == 0) {
5533 monitor_devices[0] = "stdio";
5534 }
aliguoribc0129d2008-08-01 15:12:34 +00005535 }
5536
ths71e3ceb2006-12-22 02:11:31 +00005537#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005538 if (daemonize) {
5539 pid_t pid;
5540
5541 if (pipe(fds) == -1)
5542 exit(1);
5543
5544 pid = fork();
5545 if (pid > 0) {
5546 uint8_t status;
5547 ssize_t len;
5548
5549 close(fds[1]);
5550
5551 again:
ths93815bc2007-03-19 15:58:31 +00005552 len = read(fds[0], &status, 1);
5553 if (len == -1 && (errno == EINTR))
5554 goto again;
5555
5556 if (len != 1)
5557 exit(1);
5558 else if (status == 1) {
5559 fprintf(stderr, "Could not acquire pidfile\n");
5560 exit(1);
5561 } else
5562 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00005563 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00005564 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00005565
5566 setsid();
5567
5568 pid = fork();
5569 if (pid > 0)
5570 exit(0);
5571 else if (pid < 0)
5572 exit(1);
5573
5574 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00005575
5576 signal(SIGTSTP, SIG_IGN);
5577 signal(SIGTTOU, SIG_IGN);
5578 signal(SIGTTIN, SIG_IGN);
5579 }
ths71e3ceb2006-12-22 02:11:31 +00005580
thsaa26bb22007-03-25 21:33:06 +00005581 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00005582 if (daemonize) {
5583 uint8_t status = 1;
5584 write(fds[1], &status, 1);
5585 } else
5586 fprintf(stderr, "Could not acquire pid file\n");
5587 exit(1);
5588 }
blueswir1b9e82a52009-04-05 18:03:31 +00005589#endif
ths93815bc2007-03-19 15:58:31 +00005590
Marcelo Tosatti214910a2009-09-18 02:41:23 -03005591 if (kvm_enabled()) {
5592 int ret;
5593
5594 ret = kvm_init(smp_cpus);
5595 if (ret < 0) {
5596 fprintf(stderr, "failed to initialize KVM\n");
5597 exit(1);
5598 }
5599 }
5600
aliguori3fcf7b62009-04-24 18:03:25 +00005601 if (qemu_init_main_loop()) {
5602 fprintf(stderr, "qemu_init_main_loop failed\n");
5603 exit(1);
5604 }
bellarda20dd502003-09-30 21:07:02 +00005605 linux_boot = (kernel_filename != NULL);
balrog6c41b272007-11-17 12:12:29 +00005606
thsf8d39c02008-07-03 10:01:15 +00005607 if (!linux_boot && *kernel_cmdline != '\0') {
5608 fprintf(stderr, "-append only allowed with -kernel option\n");
5609 exit(1);
5610 }
5611
5612 if (!linux_boot && initrd_filename != NULL) {
5613 fprintf(stderr, "-initrd only allowed with -kernel option\n");
5614 exit(1);
5615 }
5616
Filip Navarabf65f532009-07-27 10:02:04 -05005617#ifndef _WIN32
5618 /* Win32 doesn't support line-buffering and requires size >= 2 */
bellardb118d612003-06-30 23:36:21 +00005619 setvbuf(stdout, NULL, _IOLBF, 0);
Filip Navarabf65f532009-07-27 10:02:04 -05005620#endif
ths3b46e622007-09-17 08:09:54 +00005621
Jan Kiszka0fdddf82009-09-15 13:36:04 +02005622 init_clocks();
aliguori7183b4b2008-11-05 20:40:18 +00005623 if (init_timer_alarm() < 0) {
5624 fprintf(stderr, "could not initialize alarm timer\n");
5625 exit(1);
5626 }
pbrook2e70f6e2008-06-29 01:03:05 +00005627 if (use_icount && icount_time_shift < 0) {
5628 use_icount = 2;
5629 /* 125MIPS seems a reasonable initial guess at the guest speed.
5630 It will be corrected fairly quickly anyway. */
5631 icount_time_shift = 3;
5632 init_icount_adjust();
5633 }
pbrook634fce92006-07-15 17:40:09 +00005634
bellardfd1dff42006-02-01 21:29:26 +00005635#ifdef _WIN32
5636 socket_init();
5637#endif
5638
bellard7c9d8e02005-11-15 22:16:05 +00005639 /* init network clients */
5640 if (nb_net_clients == 0) {
5641 /* if no clients, we use a default config */
aliguorif441b282008-08-28 20:05:14 +00005642 net_clients[nb_net_clients++] = "nic";
5643#ifdef CONFIG_SLIRP
5644 net_clients[nb_net_clients++] = "user";
5645#endif
bellardc20709a2004-04-21 23:27:19 +00005646 }
5647
bellard7c9d8e02005-11-15 22:16:05 +00005648 for(i = 0;i < nb_net_clients; i++) {
balrog9ad97e62008-07-29 13:16:31 +00005649 if (net_client_parse(net_clients[i]) < 0)
bellard7c9d8e02005-11-15 22:16:05 +00005650 exit(1);
bellard702c6512004-04-02 21:21:32 +00005651 }
bellardf1510b22003-06-25 00:07:40 +00005652
Glauber Costa406c8df2009-06-17 09:05:30 -04005653 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
5654 net_set_boot_mask(net_boot);
5655
5656 net_client_check();
thseec85c22007-01-05 17:41:07 +00005657
balrogdc72ac12008-11-09 00:04:26 +00005658 /* init the bluetooth world */
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005659 if (foreach_device_config(DEV_BT, bt_parse))
5660 exit(1);
balrogdc72ac12008-11-09 00:04:26 +00005661
bellard0824d6f2003-06-24 13:42:40 +00005662 /* init the memory */
pbrook94a6b542009-04-11 17:15:54 +00005663 if (ram_size == 0)
5664 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
balrog7fb4fdc2008-04-24 17:59:27 +00005665
bellard26a5f132008-05-28 12:30:31 +00005666 /* init the dynamic translator */
5667 cpu_exec_init_all(tb_size * 1024 * 1024);
5668
bellard5905b2e2004-08-01 21:53:26 +00005669 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00005670
5671 /* we always create the cdrom drive, even if no disk is there */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005672 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00005673
balrog9d413d12007-12-04 00:10:34 +00005674 /* we always create at least one floppy */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005675 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00005676
balrog9d413d12007-12-04 00:10:34 +00005677 /* we always create one sd slot, even if no card is in it */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005678 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00005679
ths96d30e42007-01-07 20:42:14 +00005680 /* open the virtual block devices */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005681 if (snapshot)
Gerd Hoffmann7282a032009-07-31 12:25:35 +02005682 qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0);
5683 if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005684 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00005685
Juan Quintela2faf58c2009-09-10 03:04:28 +02005686 vmstate_register(0, &vmstate_timers ,&timers_state);
aliguori475e4272008-10-06 20:21:51 +00005687 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00005688
aliguori3023f332009-01-16 19:04:14 +00005689 /* Maintain compatibility with multiple stdio monitors */
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005690 if (!strcmp(monitor_devices[0],"stdio")) {
aliguori3023f332009-01-16 19:04:14 +00005691 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
5692 const char *devname = serial_devices[i];
5693 if (devname && !strcmp(devname,"mon:stdio")) {
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005694 monitor_devices[0] = NULL;
aliguori3023f332009-01-16 19:04:14 +00005695 break;
5696 } else if (devname && !strcmp(devname,"stdio")) {
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005697 monitor_devices[0] = NULL;
aliguori3023f332009-01-16 19:04:14 +00005698 serial_devices[i] = "mon:stdio";
5699 break;
5700 }
5701 }
5702 }
5703
aliguori268a3622009-04-21 22:30:27 +00005704 if (nb_numa_nodes > 0) {
5705 int i;
5706
5707 if (nb_numa_nodes > smp_cpus) {
5708 nb_numa_nodes = smp_cpus;
5709 }
5710
5711 /* If no memory size if given for any node, assume the default case
5712 * and distribute the available memory equally across all nodes
5713 */
5714 for (i = 0; i < nb_numa_nodes; i++) {
5715 if (node_mem[i] != 0)
5716 break;
5717 }
5718 if (i == nb_numa_nodes) {
5719 uint64_t usedmem = 0;
5720
5721 /* On Linux, the each node's border has to be 8MB aligned,
5722 * the final node gets the rest.
5723 */
5724 for (i = 0; i < nb_numa_nodes - 1; i++) {
5725 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
5726 usedmem += node_mem[i];
5727 }
5728 node_mem[i] = ram_size - usedmem;
5729 }
5730
5731 for (i = 0; i < nb_numa_nodes; i++) {
5732 if (node_cpumask[i] != 0)
5733 break;
5734 }
5735 /* assigning the VCPUs round-robin is easier to implement, guest OSes
5736 * must cope with this anyway, because there are BIOSes out there in
5737 * real machines which also use this scheme.
5738 */
5739 if (i == nb_numa_nodes) {
5740 for (i = 0; i < smp_cpus; i++) {
5741 node_cpumask[i % nb_numa_nodes] |= 1 << i;
5742 }
5743 }
5744 }
5745
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005746 for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
5747 const char *devname = monitor_devices[i];
5748 if (devname && strcmp(devname, "none")) {
5749 char label[32];
5750 if (i == 0) {
5751 snprintf(label, sizeof(label), "monitor");
5752 } else {
5753 snprintf(label, sizeof(label), "monitor%d", i);
5754 }
5755 monitor_hds[i] = qemu_chr_open(label, devname, NULL);
5756 if (!monitor_hds[i]) {
5757 fprintf(stderr, "qemu: could not open monitor device '%s'\n",
5758 devname);
5759 exit(1);
5760 }
aliguori4c621802009-01-16 21:48:20 +00005761 }
5762 }
5763
aliguori2796dae2009-01-16 20:23:27 +00005764 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5765 const char *devname = serial_devices[i];
5766 if (devname && strcmp(devname, "none")) {
Aurelien Jarno324a8022009-09-14 23:49:43 +02005767 char label[32];
5768 snprintf(label, sizeof(label), "serial%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005769 serial_hds[i] = qemu_chr_open(label, devname, NULL);
Aurelien Jarno324a8022009-09-14 23:49:43 +02005770 if (!serial_hds[i]) {
5771 fprintf(stderr, "qemu: could not open serial device '%s'\n",
5772 devname);
5773 exit(1);
5774 }
aliguori2796dae2009-01-16 20:23:27 +00005775 }
5776 }
5777
5778 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5779 const char *devname = parallel_devices[i];
5780 if (devname && strcmp(devname, "none")) {
5781 char label[32];
5782 snprintf(label, sizeof(label), "parallel%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005783 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
aliguori2796dae2009-01-16 20:23:27 +00005784 if (!parallel_hds[i]) {
5785 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
5786 devname);
5787 exit(1);
5788 }
5789 }
5790 }
5791
5792 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5793 const char *devname = virtio_consoles[i];
5794 if (devname && strcmp(devname, "none")) {
5795 char label[32];
5796 snprintf(label, sizeof(label), "virtcon%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005797 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
aliguori2796dae2009-01-16 20:23:27 +00005798 if (!virtcon_hds[i]) {
5799 fprintf(stderr, "qemu: could not open virtio console '%s'\n",
5800 devname);
5801 exit(1);
5802 }
5803 }
5804 }
5805
Paul Brookaae94602009-05-14 22:35:06 +01005806 module_call_init(MODULE_INIT_DEVICE);
5807
Markus Armbruster09aaa162009-08-21 10:31:34 +02005808 if (watchdog) {
5809 i = select_watchdog(watchdog);
5810 if (i > 0)
5811 exit (i == 1 ? 1 : 0);
5812 }
5813
Gerd Hoffmannb6b61142009-07-15 13:48:21 +02005814 if (machine->compat_props) {
5815 qdev_prop_register_compat(machine->compat_props);
5816 }
Paul Brookfbe1b592009-05-13 17:56:25 +01005817 machine->init(ram_size, boot_devices,
aliguori3023f332009-01-16 19:04:14 +00005818 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
5819
aliguori268a3622009-04-21 22:30:27 +00005820
Juan Quintela67b3b712009-08-28 19:25:15 +02005821#ifndef _WIN32
5822 /* must be after terminal init, SDL library changes signal handlers */
5823 sighandler_setup();
5824#endif
5825
aliguori268a3622009-04-21 22:30:27 +00005826 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5827 for (i = 0; i < nb_numa_nodes; i++) {
5828 if (node_cpumask[i] & (1 << env->cpu_index)) {
5829 env->numa_node = i;
5830 }
5831 }
5832 }
5833
aliguori6f338c32009-02-11 15:21:54 +00005834 current_machine = machine;
5835
aliguori3023f332009-01-16 19:04:14 +00005836 /* init USB devices */
5837 if (usb_enabled) {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005838 foreach_device_config(DEV_USB, usb_parse);
aliguori3023f332009-01-16 19:04:14 +00005839 }
5840
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005841 /* init generic devices */
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005842 if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0)
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005843 exit(1);
5844
aliguori8f391ab2009-01-19 16:34:10 +00005845 if (!display_state)
5846 dumb_display_init();
aliguori3023f332009-01-16 19:04:14 +00005847 /* just use the first displaystate for the moment */
5848 ds = display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005849
5850 if (display_type == DT_DEFAULT) {
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005851#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005852 display_type = DT_SDL;
5853#else
5854 display_type = DT_VNC;
5855 vnc_display = "localhost:0,to=99";
5856 show_vnc_port = 1;
5857#endif
5858 }
5859
5860
5861 switch (display_type) {
5862 case DT_NOGRAPHIC:
5863 break;
5864#if defined(CONFIG_CURSES)
5865 case DT_CURSES:
5866 curses_display_init(ds, full_screen);
5867 break;
5868#endif
bellard5b0753e2005-03-01 21:37:28 +00005869#if defined(CONFIG_SDL)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005870 case DT_SDL:
5871 sdl_display_init(ds, full_screen, no_frame);
5872 break;
bellard5b0753e2005-03-01 21:37:28 +00005873#elif defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005874 case DT_SDL:
5875 cocoa_display_init(ds, full_screen);
5876 break;
bellard313aa562003-08-10 21:52:11 +00005877#endif
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005878 case DT_VNC:
5879 vnc_display_init(ds);
5880 if (vnc_display_open(ds, vnc_display) < 0)
5881 exit(1);
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005882
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005883 if (show_vnc_port) {
5884 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005885 }
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005886 break;
5887 default:
5888 break;
bellard313aa562003-08-10 21:52:11 +00005889 }
aliguori7d957bd2009-01-15 22:14:11 +00005890 dpy_resize(ds);
aliguori5b08fc12008-08-21 20:08:03 +00005891
aliguori3023f332009-01-16 19:04:14 +00005892 dcl = ds->listeners;
5893 while (dcl != NULL) {
5894 if (dcl->dpy_refresh != NULL) {
5895 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5896 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
ths20d8a3e2007-02-18 17:04:49 +00005897 }
aliguori3023f332009-01-16 19:04:14 +00005898 dcl = dcl->next;
bellard82c643f2004-07-14 17:28:13 +00005899 }
aliguori3023f332009-01-16 19:04:14 +00005900
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005901 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
blueswir19043b622009-01-21 19:28:13 +00005902 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5903 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5904 }
5905
aliguori2796dae2009-01-16 20:23:27 +00005906 text_consoles_set_display(display_state);
aliguori2970a6c2009-03-05 22:59:58 +00005907 qemu_chr_initial_reset();
aliguori2796dae2009-01-16 20:23:27 +00005908
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005909 for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
5910 if (monitor_devices[i] && monitor_hds[i]) {
5911 monitor_init(monitor_hds[i],
5912 MONITOR_USE_READLINE |
5913 ((i == 0) ? MONITOR_IS_DEFAULT : 0));
5914 }
5915 }
bellard82c643f2004-07-14 17:28:13 +00005916
bellard8d11df92004-08-24 21:13:40 +00005917 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005918 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005919 if (devname && strcmp(devname, "none")) {
thsaf3a9032007-07-11 23:14:59 +00005920 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005921 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00005922 }
bellard82c643f2004-07-14 17:28:13 +00005923 }
bellard82c643f2004-07-14 17:28:13 +00005924
bellard6508fe52005-01-15 12:02:56 +00005925 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005926 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005927 if (devname && strcmp(devname, "none")) {
thsaf3a9032007-07-11 23:14:59 +00005928 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005929 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00005930 }
5931 }
5932
aliguori9ede2fd2009-01-15 20:05:25 +00005933 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5934 const char *devname = virtio_consoles[i];
aliguori2796dae2009-01-16 20:23:27 +00005935 if (virtcon_hds[i] && devname) {
aliguori9ede2fd2009-01-15 20:05:25 +00005936 if (strstart(devname, "vc", 0))
5937 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
5938 }
5939 }
5940
aliguori59030a82009-04-05 18:43:41 +00005941 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
5942 fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
5943 gdbstub_dev);
5944 exit(1);
balrog45669e02007-07-02 13:20:17 +00005945 }
balrog45669e02007-07-02 13:20:17 +00005946
Juan Quintela05f24012009-08-20 19:42:22 +02005947 if (loadvm) {
5948 if (load_vmstate(cur_mon, loadvm) < 0) {
5949 autostart = 0;
5950 }
5951 }
bellardd63d3072004-10-03 13:29:03 +00005952
Glauber Costa2bb8c102009-07-24 16:20:23 -04005953 if (incoming) {
aliguori5bb79102008-10-13 03:12:02 +00005954 qemu_start_incoming_migration(incoming);
Avi Kivity6b99dad2009-08-09 14:39:20 +03005955 } else if (autostart) {
aliguoric0f4ce72009-03-05 23:01:01 +00005956 vm_start();
Avi Kivity6b99dad2009-08-09 14:39:20 +03005957 }
thsffd843b2006-12-21 19:46:43 +00005958
blueswir1b9e82a52009-04-05 18:03:31 +00005959#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005960 if (daemonize) {
5961 uint8_t status = 0;
5962 ssize_t len;
ths71e3ceb2006-12-22 02:11:31 +00005963
5964 again1:
5965 len = write(fds[1], &status, 1);
5966 if (len == -1 && (errno == EINTR))
5967 goto again1;
5968
5969 if (len != 1)
5970 exit(1);
5971
aliguoribd54b862008-07-23 00:58:33 +00005972 chdir("/");
balrogaeb30be2007-07-02 15:03:13 +00005973 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00005974 if (fd == -1)
5975 exit(1);
aliguori08585322009-02-27 22:09:45 +00005976 }
ths71e3ceb2006-12-22 02:11:31 +00005977
aliguori08585322009-02-27 22:09:45 +00005978 if (run_as) {
5979 pwd = getpwnam(run_as);
5980 if (!pwd) {
5981 fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
5982 exit(1);
5983 }
5984 }
ths71e3ceb2006-12-22 02:11:31 +00005985
aliguori08585322009-02-27 22:09:45 +00005986 if (chroot_dir) {
5987 if (chroot(chroot_dir) < 0) {
5988 fprintf(stderr, "chroot failed\n");
5989 exit(1);
5990 }
5991 chdir("/");
5992 }
5993
5994 if (run_as) {
5995 if (setgid(pwd->pw_gid) < 0) {
5996 fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
5997 exit(1);
5998 }
5999 if (setuid(pwd->pw_uid) < 0) {
6000 fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
6001 exit(1);
6002 }
6003 if (setuid(0) != -1) {
6004 fprintf(stderr, "Dropping privileges failed\n");
6005 exit(1);
6006 }
6007 }
aliguori08585322009-02-27 22:09:45 +00006008
6009 if (daemonize) {
6010 dup2(fd, 0);
6011 dup2(fd, 1);
6012 dup2(fd, 2);
6013
6014 close(fd);
ths71e3ceb2006-12-22 02:11:31 +00006015 }
blueswir1b9e82a52009-04-05 18:03:31 +00006016#endif
ths71e3ceb2006-12-22 02:11:31 +00006017
bellard8a7ddc32004-03-31 19:00:16 +00006018 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00006019 quit_timers();
aliguori63a01ef2008-10-31 19:10:00 +00006020 net_cleanup();
thsb46a8902007-10-21 23:20:45 +00006021
bellard0824d6f2003-06-24 13:42:40 +00006022 return 0;
6023}